blob: 6056fbc53925d4d9f9d82659e5ee56662a333db6 [file] [log] [blame]
Douglas Gregorc34897d2009-04-09 22:27:44 +00001//===--- PCHWriter.h - Precompiled Headers Writer ---------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the PCHWriter class, which writes a precompiled header.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Frontend/PCHWriter.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclContextInternals.h"
18#include "clang/AST/DeclVisitor.h"
19#include "clang/AST/Type.h"
Chris Lattner1b094952009-04-10 18:00:12 +000020#include "clang/Lex/MacroInfo.h"
21#include "clang/Lex/Preprocessor.h"
Douglas Gregorab1cef72009-04-10 03:52:48 +000022#include "clang/Basic/FileManager.h"
23#include "clang/Basic/SourceManager.h"
Douglas Gregor635f97f2009-04-13 16:31:14 +000024#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregorb5887f32009-04-10 21:16:55 +000025#include "clang/Basic/TargetInfo.h"
Douglas Gregorc34897d2009-04-09 22:27:44 +000026#include "llvm/Bitcode/BitstreamWriter.h"
27#include "llvm/Support/Compiler.h"
Douglas Gregorab1cef72009-04-10 03:52:48 +000028#include "llvm/Support/MemoryBuffer.h"
Chris Lattner64b65f82009-04-11 18:40:46 +000029#include <cstdio>
Douglas Gregorc34897d2009-04-09 22:27:44 +000030using namespace clang;
31
32//===----------------------------------------------------------------------===//
33// Type serialization
34//===----------------------------------------------------------------------===//
35namespace {
36 class VISIBILITY_HIDDEN PCHTypeWriter {
37 PCHWriter &Writer;
38 PCHWriter::RecordData &Record;
39
40 public:
41 /// \brief Type code that corresponds to the record generated.
42 pch::TypeCode Code;
43
44 PCHTypeWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
45 : Writer(Writer), Record(Record) { }
46
47 void VisitArrayType(const ArrayType *T);
48 void VisitFunctionType(const FunctionType *T);
49 void VisitTagType(const TagType *T);
50
51#define TYPE(Class, Base) void Visit##Class##Type(const Class##Type *T);
52#define ABSTRACT_TYPE(Class, Base)
53#define DEPENDENT_TYPE(Class, Base)
54#include "clang/AST/TypeNodes.def"
55 };
56}
57
58void PCHTypeWriter::VisitExtQualType(const ExtQualType *T) {
59 Writer.AddTypeRef(QualType(T->getBaseType(), 0), Record);
60 Record.push_back(T->getObjCGCAttr()); // FIXME: use stable values
61 Record.push_back(T->getAddressSpace());
62 Code = pch::TYPE_EXT_QUAL;
63}
64
65void PCHTypeWriter::VisitBuiltinType(const BuiltinType *T) {
66 assert(false && "Built-in types are never serialized");
67}
68
69void PCHTypeWriter::VisitFixedWidthIntType(const FixedWidthIntType *T) {
70 Record.push_back(T->getWidth());
71 Record.push_back(T->isSigned());
72 Code = pch::TYPE_FIXED_WIDTH_INT;
73}
74
75void PCHTypeWriter::VisitComplexType(const ComplexType *T) {
76 Writer.AddTypeRef(T->getElementType(), Record);
77 Code = pch::TYPE_COMPLEX;
78}
79
80void PCHTypeWriter::VisitPointerType(const PointerType *T) {
81 Writer.AddTypeRef(T->getPointeeType(), Record);
82 Code = pch::TYPE_POINTER;
83}
84
85void PCHTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
86 Writer.AddTypeRef(T->getPointeeType(), Record);
87 Code = pch::TYPE_BLOCK_POINTER;
88}
89
90void PCHTypeWriter::VisitLValueReferenceType(const LValueReferenceType *T) {
91 Writer.AddTypeRef(T->getPointeeType(), Record);
92 Code = pch::TYPE_LVALUE_REFERENCE;
93}
94
95void PCHTypeWriter::VisitRValueReferenceType(const RValueReferenceType *T) {
96 Writer.AddTypeRef(T->getPointeeType(), Record);
97 Code = pch::TYPE_RVALUE_REFERENCE;
98}
99
100void PCHTypeWriter::VisitMemberPointerType(const MemberPointerType *T) {
101 Writer.AddTypeRef(T->getPointeeType(), Record);
102 Writer.AddTypeRef(QualType(T->getClass(), 0), Record);
103 Code = pch::TYPE_MEMBER_POINTER;
104}
105
106void PCHTypeWriter::VisitArrayType(const ArrayType *T) {
107 Writer.AddTypeRef(T->getElementType(), Record);
108 Record.push_back(T->getSizeModifier()); // FIXME: stable values
109 Record.push_back(T->getIndexTypeQualifier()); // FIXME: stable values
110}
111
112void PCHTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) {
113 VisitArrayType(T);
114 Writer.AddAPInt(T->getSize(), Record);
115 Code = pch::TYPE_CONSTANT_ARRAY;
116}
117
118void PCHTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
119 VisitArrayType(T);
120 Code = pch::TYPE_INCOMPLETE_ARRAY;
121}
122
123void PCHTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
124 VisitArrayType(T);
125 // FIXME: Serialize array size expression.
126 assert(false && "Cannot serialize variable-length arrays");
127 Code = pch::TYPE_VARIABLE_ARRAY;
128}
129
130void PCHTypeWriter::VisitVectorType(const VectorType *T) {
131 Writer.AddTypeRef(T->getElementType(), Record);
132 Record.push_back(T->getNumElements());
133 Code = pch::TYPE_VECTOR;
134}
135
136void PCHTypeWriter::VisitExtVectorType(const ExtVectorType *T) {
137 VisitVectorType(T);
138 Code = pch::TYPE_EXT_VECTOR;
139}
140
141void PCHTypeWriter::VisitFunctionType(const FunctionType *T) {
142 Writer.AddTypeRef(T->getResultType(), Record);
143}
144
145void PCHTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
146 VisitFunctionType(T);
147 Code = pch::TYPE_FUNCTION_NO_PROTO;
148}
149
150void PCHTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
151 VisitFunctionType(T);
152 Record.push_back(T->getNumArgs());
153 for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I)
154 Writer.AddTypeRef(T->getArgType(I), Record);
155 Record.push_back(T->isVariadic());
156 Record.push_back(T->getTypeQuals());
157 Code = pch::TYPE_FUNCTION_PROTO;
158}
159
160void PCHTypeWriter::VisitTypedefType(const TypedefType *T) {
161 Writer.AddDeclRef(T->getDecl(), Record);
162 Code = pch::TYPE_TYPEDEF;
163}
164
165void PCHTypeWriter::VisitTypeOfExprType(const TypeOfExprType *T) {
166 // FIXME: serialize the typeof expression
167 assert(false && "Cannot serialize typeof(expr)");
168 Code = pch::TYPE_TYPEOF_EXPR;
169}
170
171void PCHTypeWriter::VisitTypeOfType(const TypeOfType *T) {
172 Writer.AddTypeRef(T->getUnderlyingType(), Record);
173 Code = pch::TYPE_TYPEOF;
174}
175
176void PCHTypeWriter::VisitTagType(const TagType *T) {
177 Writer.AddDeclRef(T->getDecl(), Record);
178 assert(!T->isBeingDefined() &&
179 "Cannot serialize in the middle of a type definition");
180}
181
182void PCHTypeWriter::VisitRecordType(const RecordType *T) {
183 VisitTagType(T);
184 Code = pch::TYPE_RECORD;
185}
186
187void PCHTypeWriter::VisitEnumType(const EnumType *T) {
188 VisitTagType(T);
189 Code = pch::TYPE_ENUM;
190}
191
192void
193PCHTypeWriter::VisitTemplateSpecializationType(
194 const TemplateSpecializationType *T) {
195 // FIXME: Serialize this type
196 assert(false && "Cannot serialize template specialization types");
197}
198
199void PCHTypeWriter::VisitQualifiedNameType(const QualifiedNameType *T) {
200 // FIXME: Serialize this type
201 assert(false && "Cannot serialize qualified name types");
202}
203
204void PCHTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
205 Writer.AddDeclRef(T->getDecl(), Record);
206 Code = pch::TYPE_OBJC_INTERFACE;
207}
208
209void
210PCHTypeWriter::VisitObjCQualifiedInterfaceType(
211 const ObjCQualifiedInterfaceType *T) {
212 VisitObjCInterfaceType(T);
213 Record.push_back(T->getNumProtocols());
214 for (unsigned I = 0, N = T->getNumProtocols(); I != N; ++I)
215 Writer.AddDeclRef(T->getProtocol(I), Record);
216 Code = pch::TYPE_OBJC_QUALIFIED_INTERFACE;
217}
218
219void PCHTypeWriter::VisitObjCQualifiedIdType(const ObjCQualifiedIdType *T) {
220 Record.push_back(T->getNumProtocols());
221 for (unsigned I = 0, N = T->getNumProtocols(); I != N; ++I)
222 Writer.AddDeclRef(T->getProtocols(I), Record);
223 Code = pch::TYPE_OBJC_QUALIFIED_ID;
224}
225
226void
227PCHTypeWriter::VisitObjCQualifiedClassType(const ObjCQualifiedClassType *T) {
228 Record.push_back(T->getNumProtocols());
229 for (unsigned I = 0, N = T->getNumProtocols(); I != N; ++I)
230 Writer.AddDeclRef(T->getProtocols(I), Record);
231 Code = pch::TYPE_OBJC_QUALIFIED_CLASS;
232}
233
234//===----------------------------------------------------------------------===//
235// Declaration serialization
236//===----------------------------------------------------------------------===//
237namespace {
238 class VISIBILITY_HIDDEN PCHDeclWriter
239 : public DeclVisitor<PCHDeclWriter, void> {
240
241 PCHWriter &Writer;
242 PCHWriter::RecordData &Record;
243
244 public:
245 pch::DeclCode Code;
246
247 PCHDeclWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
248 : Writer(Writer), Record(Record) { }
249
250 void VisitDecl(Decl *D);
251 void VisitTranslationUnitDecl(TranslationUnitDecl *D);
252 void VisitNamedDecl(NamedDecl *D);
253 void VisitTypeDecl(TypeDecl *D);
254 void VisitTypedefDecl(TypedefDecl *D);
255 void VisitValueDecl(ValueDecl *D);
256 void VisitVarDecl(VarDecl *D);
257
258 void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
259 uint64_t VisibleOffset);
260 };
261}
262
263void PCHDeclWriter::VisitDecl(Decl *D) {
264 Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
265 Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
266 Writer.AddSourceLocation(D->getLocation(), Record);
267 Record.push_back(D->isInvalidDecl());
268 // FIXME: hasAttrs
269 Record.push_back(D->isImplicit());
270 Record.push_back(D->getAccess());
271}
272
273void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
274 VisitDecl(D);
275 Code = pch::DECL_TRANSLATION_UNIT;
276}
277
278void PCHDeclWriter::VisitNamedDecl(NamedDecl *D) {
279 VisitDecl(D);
280 Writer.AddDeclarationName(D->getDeclName(), Record);
281}
282
283void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
284 VisitNamedDecl(D);
285 Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
286}
287
288void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
289 VisitTypeDecl(D);
290 Writer.AddTypeRef(D->getUnderlyingType(), Record);
291 Code = pch::DECL_TYPEDEF;
292}
293
294void PCHDeclWriter::VisitValueDecl(ValueDecl *D) {
295 VisitNamedDecl(D);
296 Writer.AddTypeRef(D->getType(), Record);
297}
298
299void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
300 VisitValueDecl(D);
301 Record.push_back(D->getStorageClass());
302 Record.push_back(D->isThreadSpecified());
303 Record.push_back(D->hasCXXDirectInitializer());
304 Record.push_back(D->isDeclaredInCondition());
305 Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
306 Writer.AddSourceLocation(D->getTypeSpecStartLoc(), Record);
307 // FIXME: emit initializer
308 Code = pch::DECL_VAR;
309}
310
311/// \brief Emit the DeclContext part of a declaration context decl.
312///
313/// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL
314/// block for this declaration context is stored. May be 0 to indicate
315/// that there are no declarations stored within this context.
316///
317/// \param VisibleOffset the offset at which the DECL_CONTEXT_VISIBLE
318/// block for this declaration context is stored. May be 0 to indicate
319/// that there are no declarations visible from this context. Note
320/// that this value will not be emitted for non-primary declaration
321/// contexts.
322void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
323 uint64_t VisibleOffset) {
324 Record.push_back(LexicalOffset);
325 if (DC->getPrimaryContext() == DC)
326 Record.push_back(VisibleOffset);
327}
328
329//===----------------------------------------------------------------------===//
330// PCHWriter Implementation
331//===----------------------------------------------------------------------===//
332
Douglas Gregorb5887f32009-04-10 21:16:55 +0000333/// \brief Write the target triple (e.g., i686-apple-darwin9).
334void PCHWriter::WriteTargetTriple(const TargetInfo &Target) {
335 using namespace llvm;
336 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
337 Abbrev->Add(BitCodeAbbrevOp(pch::TARGET_TRIPLE));
338 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name
339 unsigned TripleAbbrev = S.EmitAbbrev(Abbrev);
340
341 RecordData Record;
342 Record.push_back(pch::TARGET_TRIPLE);
343 const char *Triple = Target.getTargetTriple();
344 S.EmitRecordWithBlob(TripleAbbrev, Record, Triple, strlen(Triple));
345}
346
347/// \brief Write the LangOptions structure.
Douglas Gregor179cfb12009-04-10 20:39:37 +0000348void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
349 RecordData Record;
350 Record.push_back(LangOpts.Trigraphs);
351 Record.push_back(LangOpts.BCPLComment); // BCPL-style '//' comments.
352 Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers.
353 Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode.
354 Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc)
355 Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'.
356 Record.push_back(LangOpts.Digraphs); // C94, C99 and C++
357 Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants.
358 Record.push_back(LangOpts.C99); // C99 Support
359 Record.push_back(LangOpts.Microsoft); // Microsoft extensions.
360 Record.push_back(LangOpts.CPlusPlus); // C++ Support
361 Record.push_back(LangOpts.CPlusPlus0x); // C++0x Support
362 Record.push_back(LangOpts.NoExtensions); // All extensions are disabled, strict mode.
363 Record.push_back(LangOpts.CXXOperatorNames); // Treat C++ operator names as keywords.
364
365 Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled.
366 Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled.
367 Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C modern abi enabled
368
369 Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings
370 Record.push_back(LangOpts.Boolean); // Allow bool/true/false
371 Record.push_back(LangOpts.WritableStrings); // Allow writable strings
372 Record.push_back(LangOpts.LaxVectorConversions);
373 Record.push_back(LangOpts.Exceptions); // Support exception handling.
374
375 Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime.
376 Record.push_back(LangOpts.Freestanding); // Freestanding implementation
377 Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin)
378
379 Record.push_back(LangOpts.ThreadsafeStatics); // Whether static initializers are protected
380 // by locks.
381 Record.push_back(LangOpts.Blocks); // block extension to C
382 Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if
383 // they are unused.
384 Record.push_back(LangOpts.MathErrno); // Math functions must respect errno
385 // (modulo the platform support).
386
387 Record.push_back(LangOpts.OverflowChecking); // Extension to call a handler function when
388 // signed integer arithmetic overflows.
389
390 Record.push_back(LangOpts.HeinousExtensions); // Extensions that we really don't like and
391 // may be ripped out at any time.
392
393 Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined.
394 Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be
395 // defined.
396 Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as
397 // opposed to __DYNAMIC__).
398 Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero.
399
400 Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be
401 // used (instead of C99 semantics).
402 Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined.
403 Record.push_back(LangOpts.getGCMode());
404 Record.push_back(LangOpts.getVisibilityMode());
405 Record.push_back(LangOpts.InstantiationDepth);
406 S.EmitRecord(pch::LANGUAGE_OPTIONS, Record);
407}
408
Douglas Gregorab1cef72009-04-10 03:52:48 +0000409//===----------------------------------------------------------------------===//
410// Source Manager Serialization
411//===----------------------------------------------------------------------===//
412
413/// \brief Create an abbreviation for the SLocEntry that refers to a
414/// file.
415static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &S) {
416 using namespace llvm;
417 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
418 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_FILE_ENTRY));
419 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
420 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
421 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
422 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
423 // FIXME: Need an actual encoding for the line directives; maybe
424 // this should be an array?
425 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
426 return S.EmitAbbrev(Abbrev);
427}
428
429/// \brief Create an abbreviation for the SLocEntry that refers to a
430/// buffer.
431static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &S) {
432 using namespace llvm;
433 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
434 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_ENTRY));
435 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
436 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
437 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
438 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
439 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
440 return S.EmitAbbrev(Abbrev);
441}
442
443/// \brief Create an abbreviation for the SLocEntry that refers to a
444/// buffer's blob.
445static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &S) {
446 using namespace llvm;
447 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
448 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_BLOB));
449 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
450 return S.EmitAbbrev(Abbrev);
451}
452
453/// \brief Create an abbreviation for the SLocEntry that refers to an
454/// buffer.
455static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &S) {
456 using namespace llvm;
457 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
458 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_INSTANTIATION_ENTRY));
459 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
460 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
461 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
462 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
463 return S.EmitAbbrev(Abbrev);
464}
465
466/// \brief Writes the block containing the serialized form of the
467/// source manager.
468///
469/// TODO: We should probably use an on-disk hash table (stored in a
470/// blob), indexed based on the file name, so that we only create
471/// entries for files that we actually need. In the common case (no
472/// errors), we probably won't have to create file entries for any of
473/// the files in the AST.
474void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000475 // Enter the source manager block.
Douglas Gregorab1cef72009-04-10 03:52:48 +0000476 S.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
477
478 // Abbreviations for the various kinds of source-location entries.
479 int SLocFileAbbrv = -1;
480 int SLocBufferAbbrv = -1;
481 int SLocBufferBlobAbbrv = -1;
482 int SLocInstantiationAbbrv = -1;
483
484 // Write out the source location entry table. We skip the first
485 // entry, which is always the same dummy entry.
486 RecordData Record;
487 for (SourceManager::sloc_entry_iterator
488 SLoc = SourceMgr.sloc_entry_begin() + 1,
489 SLocEnd = SourceMgr.sloc_entry_end();
490 SLoc != SLocEnd; ++SLoc) {
491 // Figure out which record code to use.
492 unsigned Code;
493 if (SLoc->isFile()) {
494 if (SLoc->getFile().getContentCache()->Entry)
495 Code = pch::SM_SLOC_FILE_ENTRY;
496 else
497 Code = pch::SM_SLOC_BUFFER_ENTRY;
498 } else
499 Code = pch::SM_SLOC_INSTANTIATION_ENTRY;
500 Record.push_back(Code);
501
502 Record.push_back(SLoc->getOffset());
503 if (SLoc->isFile()) {
504 const SrcMgr::FileInfo &File = SLoc->getFile();
505 Record.push_back(File.getIncludeLoc().getRawEncoding());
506 Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
Douglas Gregor635f97f2009-04-13 16:31:14 +0000507 Record.push_back(File.hasLineDirectives());
Douglas Gregorab1cef72009-04-10 03:52:48 +0000508
509 const SrcMgr::ContentCache *Content = File.getContentCache();
510 if (Content->Entry) {
511 // The source location entry is a file. The blob associated
512 // with this entry is the file name.
513 if (SLocFileAbbrv == -1)
514 SLocFileAbbrv = CreateSLocFileAbbrev(S);
515 S.EmitRecordWithBlob(SLocFileAbbrv, Record,
516 Content->Entry->getName(),
517 strlen(Content->Entry->getName()));
518 } else {
519 // The source location entry is a buffer. The blob associated
520 // with this entry contains the contents of the buffer.
521 if (SLocBufferAbbrv == -1) {
522 SLocBufferAbbrv = CreateSLocBufferAbbrev(S);
523 SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(S);
524 }
525
526 // We add one to the size so that we capture the trailing NULL
527 // that is required by llvm::MemoryBuffer::getMemBuffer (on
528 // the reader side).
529 const llvm::MemoryBuffer *Buffer = Content->getBuffer();
530 const char *Name = Buffer->getBufferIdentifier();
531 S.EmitRecordWithBlob(SLocBufferAbbrv, Record, Name, strlen(Name) + 1);
532 Record.clear();
533 Record.push_back(pch::SM_SLOC_BUFFER_BLOB);
534 S.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
535 Buffer->getBufferStart(),
536 Buffer->getBufferSize() + 1);
537 }
538 } else {
539 // The source location entry is an instantiation.
540 const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation();
541 Record.push_back(Inst.getSpellingLoc().getRawEncoding());
542 Record.push_back(Inst.getInstantiationLocStart().getRawEncoding());
543 Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding());
544
545 if (SLocInstantiationAbbrv == -1)
546 SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(S);
547 S.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record);
548 }
549
550 Record.clear();
551 }
552
Douglas Gregor635f97f2009-04-13 16:31:14 +0000553 // Write the line table.
554 if (SourceMgr.hasLineTable()) {
555 LineTableInfo &LineTable = SourceMgr.getLineTable();
556
557 // Emit the file names
558 Record.push_back(LineTable.getNumFilenames());
559 for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
560 // Emit the file name
561 const char *Filename = LineTable.getFilename(I);
562 unsigned FilenameLen = Filename? strlen(Filename) : 0;
563 Record.push_back(FilenameLen);
564 if (FilenameLen)
565 Record.insert(Record.end(), Filename, Filename + FilenameLen);
566 }
567
568 // Emit the line entries
569 for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
570 L != LEnd; ++L) {
571 // Emit the file ID
572 Record.push_back(L->first);
573
574 // Emit the line entries
575 Record.push_back(L->second.size());
576 for (std::vector<LineEntry>::iterator LE = L->second.begin(),
577 LEEnd = L->second.end();
578 LE != LEEnd; ++LE) {
579 Record.push_back(LE->FileOffset);
580 Record.push_back(LE->LineNo);
581 Record.push_back(LE->FilenameID);
582 Record.push_back((unsigned)LE->FileKind);
583 Record.push_back(LE->IncludeOffset);
584 }
585 S.EmitRecord(pch::SM_LINE_TABLE, Record);
586 }
587 }
588
Douglas Gregorab1cef72009-04-10 03:52:48 +0000589 S.ExitBlock();
590}
591
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000592/// \brief Writes the block containing the serialized form of the
593/// preprocessor.
594///
Chris Lattner850eabd2009-04-10 18:08:30 +0000595void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000596 // Enter the preprocessor block.
597 S.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 3);
598
Chris Lattner1b094952009-04-10 18:00:12 +0000599 // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
600 // FIXME: use diagnostics subsystem for localization etc.
601 if (PP.SawDateOrTime())
602 fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
Chris Lattner84b04f12009-04-10 17:16:57 +0000603
Chris Lattner1b094952009-04-10 18:00:12 +0000604 RecordData Record;
Chris Lattner84b04f12009-04-10 17:16:57 +0000605
Chris Lattner4b21c202009-04-13 01:29:17 +0000606 // If the preprocessor __COUNTER__ value has been bumped, remember it.
607 if (PP.getCounterValue() != 0) {
608 Record.push_back(PP.getCounterValue());
609 S.EmitRecord(pch::PP_COUNTER_VALUE, Record);
610 Record.clear();
611 }
612
Chris Lattner1b094952009-04-10 18:00:12 +0000613 // Loop over all the macro definitions that are live at the end of the file,
614 // emitting each to the PP section.
615 // FIXME: Eventually we want to emit an index so that we can lazily load
616 // macros.
617 for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
618 I != E; ++I) {
Chris Lattnerdb1c81b2009-04-10 21:41:48 +0000619 // FIXME: This emits macros in hash table order, we should do it in a stable
620 // order so that output is reproducible.
Chris Lattner1b094952009-04-10 18:00:12 +0000621 MacroInfo *MI = I->second;
622
623 // Don't emit builtin macros like __LINE__ to the PCH file unless they have
624 // been redefined by the header (in which case they are not isBuiltinMacro).
625 if (MI->isBuiltinMacro())
626 continue;
627
Chris Lattner29241862009-04-11 21:15:38 +0000628 AddIdentifierRef(I->first, Record);
Chris Lattner1b094952009-04-10 18:00:12 +0000629 Record.push_back(MI->getDefinitionLoc().getRawEncoding());
630 Record.push_back(MI->isUsed());
631
632 unsigned Code;
633 if (MI->isObjectLike()) {
634 Code = pch::PP_MACRO_OBJECT_LIKE;
635 } else {
636 Code = pch::PP_MACRO_FUNCTION_LIKE;
637
638 Record.push_back(MI->isC99Varargs());
639 Record.push_back(MI->isGNUVarargs());
640 Record.push_back(MI->getNumArgs());
641 for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
642 I != E; ++I)
Chris Lattner29241862009-04-11 21:15:38 +0000643 AddIdentifierRef(*I, Record);
Chris Lattner1b094952009-04-10 18:00:12 +0000644 }
645 S.EmitRecord(Code, Record);
646 Record.clear();
647
Chris Lattner850eabd2009-04-10 18:08:30 +0000648 // Emit the tokens array.
649 for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
650 // Note that we know that the preprocessor does not have any annotation
651 // tokens in it because they are created by the parser, and thus can't be
652 // in a macro definition.
653 const Token &Tok = MI->getReplacementToken(TokNo);
654
655 Record.push_back(Tok.getLocation().getRawEncoding());
656 Record.push_back(Tok.getLength());
657
Chris Lattner850eabd2009-04-10 18:08:30 +0000658 // FIXME: When reading literal tokens, reconstruct the literal pointer if
659 // it is needed.
Chris Lattner29241862009-04-11 21:15:38 +0000660 AddIdentifierRef(Tok.getIdentifierInfo(), Record);
Chris Lattner850eabd2009-04-10 18:08:30 +0000661
662 // FIXME: Should translate token kind to a stable encoding.
663 Record.push_back(Tok.getKind());
664 // FIXME: Should translate token flags to a stable encoding.
665 Record.push_back(Tok.getFlags());
666
667 S.EmitRecord(pch::PP_TOKEN, Record);
668 Record.clear();
669 }
Chris Lattner1b094952009-04-10 18:00:12 +0000670
671 }
672
Chris Lattner84b04f12009-04-10 17:16:57 +0000673 S.ExitBlock();
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000674}
675
676
Douglas Gregorc34897d2009-04-09 22:27:44 +0000677/// \brief Write the representation of a type to the PCH stream.
678void PCHWriter::WriteType(const Type *T) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000679 pch::TypeID &ID = TypeIDs[T];
Chris Lattner84b04f12009-04-10 17:16:57 +0000680 if (ID == 0) // we haven't seen this type before.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000681 ID = NextTypeID++;
682
683 // Record the offset for this type.
684 if (TypeOffsets.size() == ID - pch::NUM_PREDEF_TYPE_IDS)
685 TypeOffsets.push_back(S.GetCurrentBitNo());
686 else if (TypeOffsets.size() < ID - pch::NUM_PREDEF_TYPE_IDS) {
687 TypeOffsets.resize(ID + 1 - pch::NUM_PREDEF_TYPE_IDS);
688 TypeOffsets[ID - pch::NUM_PREDEF_TYPE_IDS] = S.GetCurrentBitNo();
689 }
690
691 RecordData Record;
692
693 // Emit the type's representation.
694 PCHTypeWriter W(*this, Record);
695 switch (T->getTypeClass()) {
696 // For all of the concrete, non-dependent types, call the
697 // appropriate visitor function.
698#define TYPE(Class, Base) \
699 case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
700#define ABSTRACT_TYPE(Class, Base)
701#define DEPENDENT_TYPE(Class, Base)
702#include "clang/AST/TypeNodes.def"
703
704 // For all of the dependent type nodes (which only occur in C++
705 // templates), produce an error.
706#define TYPE(Class, Base)
707#define DEPENDENT_TYPE(Class, Base) case Type::Class:
708#include "clang/AST/TypeNodes.def"
709 assert(false && "Cannot serialize dependent type nodes");
710 break;
711 }
712
713 // Emit the serialized record.
714 S.EmitRecord(W.Code, Record);
715}
716
717/// \brief Write a block containing all of the types.
718void PCHWriter::WriteTypesBlock(ASTContext &Context) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000719 // Enter the types block.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000720 S.EnterSubblock(pch::TYPES_BLOCK_ID, 2);
721
722 // Emit all of the types in the ASTContext
723 for (std::vector<Type*>::const_iterator T = Context.getTypes().begin(),
724 TEnd = Context.getTypes().end();
725 T != TEnd; ++T) {
726 // Builtin types are never serialized.
727 if (isa<BuiltinType>(*T))
728 continue;
729
730 WriteType(*T);
731 }
732
733 // Exit the types block
734 S.ExitBlock();
Douglas Gregorc34897d2009-04-09 22:27:44 +0000735}
736
737/// \brief Write the block containing all of the declaration IDs
738/// lexically declared within the given DeclContext.
739///
740/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
741/// bistream, or 0 if no block was written.
742uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
743 DeclContext *DC) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000744 if (DC->decls_empty(Context))
Douglas Gregorc34897d2009-04-09 22:27:44 +0000745 return 0;
746
747 uint64_t Offset = S.GetCurrentBitNo();
748 RecordData Record;
749 for (DeclContext::decl_iterator D = DC->decls_begin(Context),
750 DEnd = DC->decls_end(Context);
751 D != DEnd; ++D)
752 AddDeclRef(*D, Record);
753
754 S.EmitRecord(pch::DECL_CONTEXT_LEXICAL, Record);
755 return Offset;
756}
757
758/// \brief Write the block containing all of the declaration IDs
759/// visible from the given DeclContext.
760///
761/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
762/// bistream, or 0 if no block was written.
763uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
764 DeclContext *DC) {
765 if (DC->getPrimaryContext() != DC)
766 return 0;
767
768 // Force the DeclContext to build a its name-lookup table.
769 DC->lookup(Context, DeclarationName());
770
771 // Serialize the contents of the mapping used for lookup. Note that,
772 // although we have two very different code paths, the serialized
773 // representation is the same for both cases: a declaration name,
774 // followed by a size, followed by references to the visible
775 // declarations that have that name.
776 uint64_t Offset = S.GetCurrentBitNo();
777 RecordData Record;
778 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
779 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
780 D != DEnd; ++D) {
781 AddDeclarationName(D->first, Record);
782 DeclContext::lookup_result Result = D->second.getLookupResult(Context);
783 Record.push_back(Result.second - Result.first);
784 for(; Result.first != Result.second; ++Result.first)
785 AddDeclRef(*Result.first, Record);
786 }
787
788 if (Record.size() == 0)
789 return 0;
790
791 S.EmitRecord(pch::DECL_CONTEXT_VISIBLE, Record);
792 return Offset;
793}
794
795/// \brief Write a block containing all of the declarations.
796void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000797 // Enter the declarations block.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000798 S.EnterSubblock(pch::DECLS_BLOCK_ID, 2);
799
800 // Emit all of the declarations.
801 RecordData Record;
802 PCHDeclWriter W(*this, Record);
803 while (!DeclsToEmit.empty()) {
804 // Pull the next declaration off the queue
805 Decl *D = DeclsToEmit.front();
806 DeclsToEmit.pop();
807
808 // If this declaration is also a DeclContext, write blocks for the
809 // declarations that lexically stored inside its context and those
810 // declarations that are visible from its context. These blocks
811 // are written before the declaration itself so that we can put
812 // their offsets into the record for the declaration.
813 uint64_t LexicalOffset = 0;
814 uint64_t VisibleOffset = 0;
815 DeclContext *DC = dyn_cast<DeclContext>(D);
816 if (DC) {
817 LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
818 VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
819 }
820
821 // Determine the ID for this declaration
Douglas Gregorac8f2802009-04-10 17:25:41 +0000822 pch::DeclID ID = DeclIDs[D];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000823 if (ID == 0)
824 ID = DeclIDs.size();
825
826 unsigned Index = ID - 1;
827
828 // Record the offset for this declaration
829 if (DeclOffsets.size() == Index)
830 DeclOffsets.push_back(S.GetCurrentBitNo());
831 else if (DeclOffsets.size() < Index) {
832 DeclOffsets.resize(Index+1);
833 DeclOffsets[Index] = S.GetCurrentBitNo();
834 }
835
836 // Build and emit a record for this declaration
837 Record.clear();
838 W.Code = (pch::DeclCode)0;
839 W.Visit(D);
840 if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
841 assert(W.Code && "Visitor did not set record code");
842 S.EmitRecord(W.Code, Record);
843 }
844
845 // Exit the declarations block
846 S.ExitBlock();
Douglas Gregorc34897d2009-04-09 22:27:44 +0000847}
848
Douglas Gregor7a224cf2009-04-11 00:14:32 +0000849/// \brief Write the identifier table into the PCH file.
850///
851/// The identifier table consists of a blob containing string data
852/// (the actual identifiers themselves) and a separate "offsets" index
853/// that maps identifier IDs to locations within the blob.
854void PCHWriter::WriteIdentifierTable() {
855 using namespace llvm;
856
857 // Create and write out the blob that contains the identifier
858 // strings.
859 RecordData IdentOffsets;
860 IdentOffsets.resize(IdentifierIDs.size());
861 {
862 // Create the identifier string data.
863 std::vector<char> Data;
864 Data.push_back(0); // Data must not be empty.
865 for (llvm::DenseMap<const IdentifierInfo *, pch::IdentID>::iterator
866 ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
867 ID != IDEnd; ++ID) {
868 assert(ID->first && "NULL identifier in identifier table");
869
870 // Make sure we're starting on an odd byte. The PCH reader
871 // expects the low bit to be set on all of the offsets.
872 if ((Data.size() & 0x01) == 0)
873 Data.push_back((char)0);
874
875 IdentOffsets[ID->second - 1] = Data.size();
876 Data.insert(Data.end(),
877 ID->first->getName(),
878 ID->first->getName() + ID->first->getLength());
879 Data.push_back((char)0);
880 }
881
882 // Create a blob abbreviation
883 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
884 Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_TABLE));
885 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name
886 unsigned IDTableAbbrev = S.EmitAbbrev(Abbrev);
887
888 // Write the identifier table
889 RecordData Record;
890 Record.push_back(pch::IDENTIFIER_TABLE);
891 S.EmitRecordWithBlob(IDTableAbbrev, Record, &Data.front(), Data.size());
892 }
893
894 // Write the offsets table for identifier IDs.
895 S.EmitRecord(pch::IDENTIFIER_OFFSET, IdentOffsets);
896}
897
Douglas Gregorc34897d2009-04-09 22:27:44 +0000898PCHWriter::PCHWriter(llvm::BitstreamWriter &S)
899 : S(S), NextTypeID(pch::NUM_PREDEF_TYPE_IDS) { }
900
Chris Lattner850eabd2009-04-10 18:08:30 +0000901void PCHWriter::WritePCH(ASTContext &Context, const Preprocessor &PP) {
Douglas Gregorc34897d2009-04-09 22:27:44 +0000902 // Emit the file header.
903 S.Emit((unsigned)'C', 8);
904 S.Emit((unsigned)'P', 8);
905 S.Emit((unsigned)'C', 8);
906 S.Emit((unsigned)'H', 8);
907
908 // The translation unit is the first declaration we'll emit.
909 DeclIDs[Context.getTranslationUnitDecl()] = 1;
910 DeclsToEmit.push(Context.getTranslationUnitDecl());
911
912 // Write the remaining PCH contents.
Douglas Gregorb5887f32009-04-10 21:16:55 +0000913 S.EnterSubblock(pch::PCH_BLOCK_ID, 3);
914 WriteTargetTriple(Context.Target);
Douglas Gregor179cfb12009-04-10 20:39:37 +0000915 WriteLanguageOptions(Context.getLangOptions());
Douglas Gregorab1cef72009-04-10 03:52:48 +0000916 WriteSourceManagerBlock(Context.getSourceManager());
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000917 WritePreprocessor(PP);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000918 WriteTypesBlock(Context);
919 WriteDeclsBlock(Context);
Douglas Gregor179cfb12009-04-10 20:39:37 +0000920 S.EmitRecord(pch::TYPE_OFFSET, TypeOffsets);
921 S.EmitRecord(pch::DECL_OFFSET, DeclOffsets);
Douglas Gregor7a224cf2009-04-11 00:14:32 +0000922 WriteIdentifierTable();
Douglas Gregorc34897d2009-04-09 22:27:44 +0000923 S.ExitBlock();
924}
925
926void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
927 Record.push_back(Loc.getRawEncoding());
928}
929
930void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
931 Record.push_back(Value.getBitWidth());
932 unsigned N = Value.getNumWords();
933 const uint64_t* Words = Value.getRawData();
934 for (unsigned I = 0; I != N; ++I)
935 Record.push_back(Words[I]);
936}
937
938void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
Douglas Gregor7a224cf2009-04-11 00:14:32 +0000939 if (II == 0) {
940 Record.push_back(0);
941 return;
942 }
943
944 pch::IdentID &ID = IdentifierIDs[II];
945 if (ID == 0)
946 ID = IdentifierIDs.size();
947
948 Record.push_back(ID);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000949}
950
951void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
952 if (T.isNull()) {
953 Record.push_back(pch::PREDEF_TYPE_NULL_ID);
954 return;
955 }
956
957 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000958 pch::TypeID ID = 0;
Douglas Gregorc34897d2009-04-09 22:27:44 +0000959 switch (BT->getKind()) {
960 case BuiltinType::Void: ID = pch::PREDEF_TYPE_VOID_ID; break;
961 case BuiltinType::Bool: ID = pch::PREDEF_TYPE_BOOL_ID; break;
962 case BuiltinType::Char_U: ID = pch::PREDEF_TYPE_CHAR_U_ID; break;
963 case BuiltinType::UChar: ID = pch::PREDEF_TYPE_UCHAR_ID; break;
964 case BuiltinType::UShort: ID = pch::PREDEF_TYPE_USHORT_ID; break;
965 case BuiltinType::UInt: ID = pch::PREDEF_TYPE_UINT_ID; break;
966 case BuiltinType::ULong: ID = pch::PREDEF_TYPE_ULONG_ID; break;
967 case BuiltinType::ULongLong: ID = pch::PREDEF_TYPE_ULONGLONG_ID; break;
968 case BuiltinType::Char_S: ID = pch::PREDEF_TYPE_CHAR_S_ID; break;
969 case BuiltinType::SChar: ID = pch::PREDEF_TYPE_SCHAR_ID; break;
970 case BuiltinType::WChar: ID = pch::PREDEF_TYPE_WCHAR_ID; break;
971 case BuiltinType::Short: ID = pch::PREDEF_TYPE_SHORT_ID; break;
972 case BuiltinType::Int: ID = pch::PREDEF_TYPE_INT_ID; break;
973 case BuiltinType::Long: ID = pch::PREDEF_TYPE_LONG_ID; break;
974 case BuiltinType::LongLong: ID = pch::PREDEF_TYPE_LONGLONG_ID; break;
975 case BuiltinType::Float: ID = pch::PREDEF_TYPE_FLOAT_ID; break;
976 case BuiltinType::Double: ID = pch::PREDEF_TYPE_DOUBLE_ID; break;
977 case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
978 case BuiltinType::Overload: ID = pch::PREDEF_TYPE_OVERLOAD_ID; break;
979 case BuiltinType::Dependent: ID = pch::PREDEF_TYPE_DEPENDENT_ID; break;
980 }
981
982 Record.push_back((ID << 3) | T.getCVRQualifiers());
983 return;
984 }
985
Douglas Gregorac8f2802009-04-10 17:25:41 +0000986 pch::TypeID &ID = TypeIDs[T.getTypePtr()];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000987 if (ID == 0) // we haven't seen this type before
988 ID = NextTypeID++;
989
990 // Encode the type qualifiers in the type reference.
991 Record.push_back((ID << 3) | T.getCVRQualifiers());
992}
993
994void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {
995 if (D == 0) {
996 Record.push_back(0);
997 return;
998 }
999
Douglas Gregorac8f2802009-04-10 17:25:41 +00001000 pch::DeclID &ID = DeclIDs[D];
Douglas Gregorc34897d2009-04-09 22:27:44 +00001001 if (ID == 0) {
1002 // We haven't seen this declaration before. Give it a new ID and
1003 // enqueue it in the list of declarations to emit.
1004 ID = DeclIDs.size();
1005 DeclsToEmit.push(const_cast<Decl *>(D));
1006 }
1007
1008 Record.push_back(ID);
1009}
1010
1011void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
1012 Record.push_back(Name.getNameKind());
1013 switch (Name.getNameKind()) {
1014 case DeclarationName::Identifier:
1015 AddIdentifierRef(Name.getAsIdentifierInfo(), Record);
1016 break;
1017
1018 case DeclarationName::ObjCZeroArgSelector:
1019 case DeclarationName::ObjCOneArgSelector:
1020 case DeclarationName::ObjCMultiArgSelector:
1021 assert(false && "Serialization of Objective-C selectors unavailable");
1022 break;
1023
1024 case DeclarationName::CXXConstructorName:
1025 case DeclarationName::CXXDestructorName:
1026 case DeclarationName::CXXConversionFunctionName:
1027 AddTypeRef(Name.getCXXNameType(), Record);
1028 break;
1029
1030 case DeclarationName::CXXOperatorName:
1031 Record.push_back(Name.getCXXOverloadedOperator());
1032 break;
1033
1034 case DeclarationName::CXXUsingDirective:
1035 // No extra data to emit
1036 break;
1037 }
1038}