blob: 2ba8e9eeb617f4b885525cb83ea8ba94579a4197 [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);
Douglas Gregor47f1b2c2009-04-13 18:14:40 +0000255 void VisitTagDecl(TagDecl *D);
256 void VisitEnumDecl(EnumDecl *D);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000257 void VisitValueDecl(ValueDecl *D);
Douglas Gregor47f1b2c2009-04-13 18:14:40 +0000258 void VisitEnumConstantDecl(EnumConstantDecl *D);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000259 void VisitVarDecl(VarDecl *D);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000260 void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
261 uint64_t VisibleOffset);
262 };
263}
264
265void PCHDeclWriter::VisitDecl(Decl *D) {
266 Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
267 Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
268 Writer.AddSourceLocation(D->getLocation(), Record);
269 Record.push_back(D->isInvalidDecl());
270 // FIXME: hasAttrs
271 Record.push_back(D->isImplicit());
272 Record.push_back(D->getAccess());
273}
274
275void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
276 VisitDecl(D);
277 Code = pch::DECL_TRANSLATION_UNIT;
278}
279
280void PCHDeclWriter::VisitNamedDecl(NamedDecl *D) {
281 VisitDecl(D);
282 Writer.AddDeclarationName(D->getDeclName(), Record);
283}
284
285void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
286 VisitNamedDecl(D);
287 Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
288}
289
290void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
291 VisitTypeDecl(D);
292 Writer.AddTypeRef(D->getUnderlyingType(), Record);
293 Code = pch::DECL_TYPEDEF;
294}
295
Douglas Gregor47f1b2c2009-04-13 18:14:40 +0000296void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
297 VisitTypeDecl(D);
298 Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
299 Record.push_back(D->isDefinition());
300 Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
301}
302
303void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) {
304 VisitTagDecl(D);
305 Writer.AddTypeRef(D->getIntegerType(), Record);
306 Code = pch::DECL_ENUM;
307}
308
Douglas Gregorc34897d2009-04-09 22:27:44 +0000309void PCHDeclWriter::VisitValueDecl(ValueDecl *D) {
310 VisitNamedDecl(D);
311 Writer.AddTypeRef(D->getType(), Record);
312}
313
Douglas Gregor47f1b2c2009-04-13 18:14:40 +0000314void PCHDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
315 VisitValueDecl(D);
316 // FIXME: Writer.AddExprRef(D->getInitExpr());
317 Writer.AddAPSInt(D->getInitVal(), Record);
318 Code = pch::DECL_ENUM_CONSTANT;
319}
320
Douglas Gregorc34897d2009-04-09 22:27:44 +0000321void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
322 VisitValueDecl(D);
323 Record.push_back(D->getStorageClass());
324 Record.push_back(D->isThreadSpecified());
325 Record.push_back(D->hasCXXDirectInitializer());
326 Record.push_back(D->isDeclaredInCondition());
327 Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
328 Writer.AddSourceLocation(D->getTypeSpecStartLoc(), Record);
329 // FIXME: emit initializer
330 Code = pch::DECL_VAR;
331}
332
333/// \brief Emit the DeclContext part of a declaration context decl.
334///
335/// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL
336/// block for this declaration context is stored. May be 0 to indicate
337/// that there are no declarations stored within this context.
338///
339/// \param VisibleOffset the offset at which the DECL_CONTEXT_VISIBLE
340/// block for this declaration context is stored. May be 0 to indicate
341/// that there are no declarations visible from this context. Note
342/// that this value will not be emitted for non-primary declaration
343/// contexts.
344void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
345 uint64_t VisibleOffset) {
346 Record.push_back(LexicalOffset);
347 if (DC->getPrimaryContext() == DC)
348 Record.push_back(VisibleOffset);
349}
350
351//===----------------------------------------------------------------------===//
352// PCHWriter Implementation
353//===----------------------------------------------------------------------===//
354
Douglas Gregorb5887f32009-04-10 21:16:55 +0000355/// \brief Write the target triple (e.g., i686-apple-darwin9).
356void PCHWriter::WriteTargetTriple(const TargetInfo &Target) {
357 using namespace llvm;
358 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
359 Abbrev->Add(BitCodeAbbrevOp(pch::TARGET_TRIPLE));
360 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name
361 unsigned TripleAbbrev = S.EmitAbbrev(Abbrev);
362
363 RecordData Record;
364 Record.push_back(pch::TARGET_TRIPLE);
365 const char *Triple = Target.getTargetTriple();
366 S.EmitRecordWithBlob(TripleAbbrev, Record, Triple, strlen(Triple));
367}
368
369/// \brief Write the LangOptions structure.
Douglas Gregor179cfb12009-04-10 20:39:37 +0000370void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
371 RecordData Record;
372 Record.push_back(LangOpts.Trigraphs);
373 Record.push_back(LangOpts.BCPLComment); // BCPL-style '//' comments.
374 Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers.
375 Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode.
376 Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc)
377 Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'.
378 Record.push_back(LangOpts.Digraphs); // C94, C99 and C++
379 Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants.
380 Record.push_back(LangOpts.C99); // C99 Support
381 Record.push_back(LangOpts.Microsoft); // Microsoft extensions.
382 Record.push_back(LangOpts.CPlusPlus); // C++ Support
383 Record.push_back(LangOpts.CPlusPlus0x); // C++0x Support
384 Record.push_back(LangOpts.NoExtensions); // All extensions are disabled, strict mode.
385 Record.push_back(LangOpts.CXXOperatorNames); // Treat C++ operator names as keywords.
386
387 Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled.
388 Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled.
389 Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C modern abi enabled
390
391 Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings
392 Record.push_back(LangOpts.Boolean); // Allow bool/true/false
393 Record.push_back(LangOpts.WritableStrings); // Allow writable strings
394 Record.push_back(LangOpts.LaxVectorConversions);
395 Record.push_back(LangOpts.Exceptions); // Support exception handling.
396
397 Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime.
398 Record.push_back(LangOpts.Freestanding); // Freestanding implementation
399 Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin)
400
401 Record.push_back(LangOpts.ThreadsafeStatics); // Whether static initializers are protected
402 // by locks.
403 Record.push_back(LangOpts.Blocks); // block extension to C
404 Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if
405 // they are unused.
406 Record.push_back(LangOpts.MathErrno); // Math functions must respect errno
407 // (modulo the platform support).
408
409 Record.push_back(LangOpts.OverflowChecking); // Extension to call a handler function when
410 // signed integer arithmetic overflows.
411
412 Record.push_back(LangOpts.HeinousExtensions); // Extensions that we really don't like and
413 // may be ripped out at any time.
414
415 Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined.
416 Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be
417 // defined.
418 Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as
419 // opposed to __DYNAMIC__).
420 Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero.
421
422 Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be
423 // used (instead of C99 semantics).
424 Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined.
425 Record.push_back(LangOpts.getGCMode());
426 Record.push_back(LangOpts.getVisibilityMode());
427 Record.push_back(LangOpts.InstantiationDepth);
428 S.EmitRecord(pch::LANGUAGE_OPTIONS, Record);
429}
430
Douglas Gregorab1cef72009-04-10 03:52:48 +0000431//===----------------------------------------------------------------------===//
432// Source Manager Serialization
433//===----------------------------------------------------------------------===//
434
435/// \brief Create an abbreviation for the SLocEntry that refers to a
436/// file.
437static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &S) {
438 using namespace llvm;
439 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
440 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_FILE_ENTRY));
441 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
442 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
443 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
444 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
445 // FIXME: Need an actual encoding for the line directives; maybe
446 // this should be an array?
447 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
448 return S.EmitAbbrev(Abbrev);
449}
450
451/// \brief Create an abbreviation for the SLocEntry that refers to a
452/// buffer.
453static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &S) {
454 using namespace llvm;
455 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
456 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_ENTRY));
457 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
458 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
459 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
460 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
461 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
462 return S.EmitAbbrev(Abbrev);
463}
464
465/// \brief Create an abbreviation for the SLocEntry that refers to a
466/// buffer's blob.
467static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &S) {
468 using namespace llvm;
469 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
470 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_BLOB));
471 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
472 return S.EmitAbbrev(Abbrev);
473}
474
475/// \brief Create an abbreviation for the SLocEntry that refers to an
476/// buffer.
477static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &S) {
478 using namespace llvm;
479 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
480 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_INSTANTIATION_ENTRY));
481 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
482 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
483 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
484 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
485 return S.EmitAbbrev(Abbrev);
486}
487
488/// \brief Writes the block containing the serialized form of the
489/// source manager.
490///
491/// TODO: We should probably use an on-disk hash table (stored in a
492/// blob), indexed based on the file name, so that we only create
493/// entries for files that we actually need. In the common case (no
494/// errors), we probably won't have to create file entries for any of
495/// the files in the AST.
496void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000497 // Enter the source manager block.
Douglas Gregorab1cef72009-04-10 03:52:48 +0000498 S.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
499
500 // Abbreviations for the various kinds of source-location entries.
501 int SLocFileAbbrv = -1;
502 int SLocBufferAbbrv = -1;
503 int SLocBufferBlobAbbrv = -1;
504 int SLocInstantiationAbbrv = -1;
505
506 // Write out the source location entry table. We skip the first
507 // entry, which is always the same dummy entry.
508 RecordData Record;
509 for (SourceManager::sloc_entry_iterator
510 SLoc = SourceMgr.sloc_entry_begin() + 1,
511 SLocEnd = SourceMgr.sloc_entry_end();
512 SLoc != SLocEnd; ++SLoc) {
513 // Figure out which record code to use.
514 unsigned Code;
515 if (SLoc->isFile()) {
516 if (SLoc->getFile().getContentCache()->Entry)
517 Code = pch::SM_SLOC_FILE_ENTRY;
518 else
519 Code = pch::SM_SLOC_BUFFER_ENTRY;
520 } else
521 Code = pch::SM_SLOC_INSTANTIATION_ENTRY;
522 Record.push_back(Code);
523
524 Record.push_back(SLoc->getOffset());
525 if (SLoc->isFile()) {
526 const SrcMgr::FileInfo &File = SLoc->getFile();
527 Record.push_back(File.getIncludeLoc().getRawEncoding());
528 Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
Douglas Gregor635f97f2009-04-13 16:31:14 +0000529 Record.push_back(File.hasLineDirectives());
Douglas Gregorab1cef72009-04-10 03:52:48 +0000530
531 const SrcMgr::ContentCache *Content = File.getContentCache();
532 if (Content->Entry) {
533 // The source location entry is a file. The blob associated
534 // with this entry is the file name.
535 if (SLocFileAbbrv == -1)
536 SLocFileAbbrv = CreateSLocFileAbbrev(S);
537 S.EmitRecordWithBlob(SLocFileAbbrv, Record,
538 Content->Entry->getName(),
539 strlen(Content->Entry->getName()));
540 } else {
541 // The source location entry is a buffer. The blob associated
542 // with this entry contains the contents of the buffer.
543 if (SLocBufferAbbrv == -1) {
544 SLocBufferAbbrv = CreateSLocBufferAbbrev(S);
545 SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(S);
546 }
547
548 // We add one to the size so that we capture the trailing NULL
549 // that is required by llvm::MemoryBuffer::getMemBuffer (on
550 // the reader side).
551 const llvm::MemoryBuffer *Buffer = Content->getBuffer();
552 const char *Name = Buffer->getBufferIdentifier();
553 S.EmitRecordWithBlob(SLocBufferAbbrv, Record, Name, strlen(Name) + 1);
554 Record.clear();
555 Record.push_back(pch::SM_SLOC_BUFFER_BLOB);
556 S.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
557 Buffer->getBufferStart(),
558 Buffer->getBufferSize() + 1);
559 }
560 } else {
561 // The source location entry is an instantiation.
562 const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation();
563 Record.push_back(Inst.getSpellingLoc().getRawEncoding());
564 Record.push_back(Inst.getInstantiationLocStart().getRawEncoding());
565 Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding());
566
567 if (SLocInstantiationAbbrv == -1)
568 SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(S);
569 S.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record);
570 }
571
572 Record.clear();
573 }
574
Douglas Gregor635f97f2009-04-13 16:31:14 +0000575 // Write the line table.
576 if (SourceMgr.hasLineTable()) {
577 LineTableInfo &LineTable = SourceMgr.getLineTable();
578
579 // Emit the file names
580 Record.push_back(LineTable.getNumFilenames());
581 for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
582 // Emit the file name
583 const char *Filename = LineTable.getFilename(I);
584 unsigned FilenameLen = Filename? strlen(Filename) : 0;
585 Record.push_back(FilenameLen);
586 if (FilenameLen)
587 Record.insert(Record.end(), Filename, Filename + FilenameLen);
588 }
589
590 // Emit the line entries
591 for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
592 L != LEnd; ++L) {
593 // Emit the file ID
594 Record.push_back(L->first);
595
596 // Emit the line entries
597 Record.push_back(L->second.size());
598 for (std::vector<LineEntry>::iterator LE = L->second.begin(),
599 LEEnd = L->second.end();
600 LE != LEEnd; ++LE) {
601 Record.push_back(LE->FileOffset);
602 Record.push_back(LE->LineNo);
603 Record.push_back(LE->FilenameID);
604 Record.push_back((unsigned)LE->FileKind);
605 Record.push_back(LE->IncludeOffset);
606 }
607 S.EmitRecord(pch::SM_LINE_TABLE, Record);
608 }
609 }
610
Douglas Gregorab1cef72009-04-10 03:52:48 +0000611 S.ExitBlock();
612}
613
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000614/// \brief Writes the block containing the serialized form of the
615/// preprocessor.
616///
Chris Lattner850eabd2009-04-10 18:08:30 +0000617void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000618 // Enter the preprocessor block.
619 S.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 3);
620
Chris Lattner1b094952009-04-10 18:00:12 +0000621 // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
622 // FIXME: use diagnostics subsystem for localization etc.
623 if (PP.SawDateOrTime())
624 fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
Chris Lattner84b04f12009-04-10 17:16:57 +0000625
Chris Lattner1b094952009-04-10 18:00:12 +0000626 RecordData Record;
Chris Lattner84b04f12009-04-10 17:16:57 +0000627
Chris Lattner4b21c202009-04-13 01:29:17 +0000628 // If the preprocessor __COUNTER__ value has been bumped, remember it.
629 if (PP.getCounterValue() != 0) {
630 Record.push_back(PP.getCounterValue());
631 S.EmitRecord(pch::PP_COUNTER_VALUE, Record);
632 Record.clear();
633 }
634
Chris Lattner1b094952009-04-10 18:00:12 +0000635 // Loop over all the macro definitions that are live at the end of the file,
636 // emitting each to the PP section.
637 // FIXME: Eventually we want to emit an index so that we can lazily load
638 // macros.
639 for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
640 I != E; ++I) {
Chris Lattnerdb1c81b2009-04-10 21:41:48 +0000641 // FIXME: This emits macros in hash table order, we should do it in a stable
642 // order so that output is reproducible.
Chris Lattner1b094952009-04-10 18:00:12 +0000643 MacroInfo *MI = I->second;
644
645 // Don't emit builtin macros like __LINE__ to the PCH file unless they have
646 // been redefined by the header (in which case they are not isBuiltinMacro).
647 if (MI->isBuiltinMacro())
648 continue;
649
Chris Lattner29241862009-04-11 21:15:38 +0000650 AddIdentifierRef(I->first, Record);
Chris Lattner1b094952009-04-10 18:00:12 +0000651 Record.push_back(MI->getDefinitionLoc().getRawEncoding());
652 Record.push_back(MI->isUsed());
653
654 unsigned Code;
655 if (MI->isObjectLike()) {
656 Code = pch::PP_MACRO_OBJECT_LIKE;
657 } else {
658 Code = pch::PP_MACRO_FUNCTION_LIKE;
659
660 Record.push_back(MI->isC99Varargs());
661 Record.push_back(MI->isGNUVarargs());
662 Record.push_back(MI->getNumArgs());
663 for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
664 I != E; ++I)
Chris Lattner29241862009-04-11 21:15:38 +0000665 AddIdentifierRef(*I, Record);
Chris Lattner1b094952009-04-10 18:00:12 +0000666 }
667 S.EmitRecord(Code, Record);
668 Record.clear();
669
Chris Lattner850eabd2009-04-10 18:08:30 +0000670 // Emit the tokens array.
671 for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
672 // Note that we know that the preprocessor does not have any annotation
673 // tokens in it because they are created by the parser, and thus can't be
674 // in a macro definition.
675 const Token &Tok = MI->getReplacementToken(TokNo);
676
677 Record.push_back(Tok.getLocation().getRawEncoding());
678 Record.push_back(Tok.getLength());
679
Chris Lattner850eabd2009-04-10 18:08:30 +0000680 // FIXME: When reading literal tokens, reconstruct the literal pointer if
681 // it is needed.
Chris Lattner29241862009-04-11 21:15:38 +0000682 AddIdentifierRef(Tok.getIdentifierInfo(), Record);
Chris Lattner850eabd2009-04-10 18:08:30 +0000683
684 // FIXME: Should translate token kind to a stable encoding.
685 Record.push_back(Tok.getKind());
686 // FIXME: Should translate token flags to a stable encoding.
687 Record.push_back(Tok.getFlags());
688
689 S.EmitRecord(pch::PP_TOKEN, Record);
690 Record.clear();
691 }
Chris Lattner1b094952009-04-10 18:00:12 +0000692
693 }
694
Chris Lattner84b04f12009-04-10 17:16:57 +0000695 S.ExitBlock();
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000696}
697
698
Douglas Gregorc34897d2009-04-09 22:27:44 +0000699/// \brief Write the representation of a type to the PCH stream.
700void PCHWriter::WriteType(const Type *T) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000701 pch::TypeID &ID = TypeIDs[T];
Chris Lattner84b04f12009-04-10 17:16:57 +0000702 if (ID == 0) // we haven't seen this type before.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000703 ID = NextTypeID++;
704
705 // Record the offset for this type.
706 if (TypeOffsets.size() == ID - pch::NUM_PREDEF_TYPE_IDS)
707 TypeOffsets.push_back(S.GetCurrentBitNo());
708 else if (TypeOffsets.size() < ID - pch::NUM_PREDEF_TYPE_IDS) {
709 TypeOffsets.resize(ID + 1 - pch::NUM_PREDEF_TYPE_IDS);
710 TypeOffsets[ID - pch::NUM_PREDEF_TYPE_IDS] = S.GetCurrentBitNo();
711 }
712
713 RecordData Record;
714
715 // Emit the type's representation.
716 PCHTypeWriter W(*this, Record);
717 switch (T->getTypeClass()) {
718 // For all of the concrete, non-dependent types, call the
719 // appropriate visitor function.
720#define TYPE(Class, Base) \
721 case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
722#define ABSTRACT_TYPE(Class, Base)
723#define DEPENDENT_TYPE(Class, Base)
724#include "clang/AST/TypeNodes.def"
725
726 // For all of the dependent type nodes (which only occur in C++
727 // templates), produce an error.
728#define TYPE(Class, Base)
729#define DEPENDENT_TYPE(Class, Base) case Type::Class:
730#include "clang/AST/TypeNodes.def"
731 assert(false && "Cannot serialize dependent type nodes");
732 break;
733 }
734
735 // Emit the serialized record.
736 S.EmitRecord(W.Code, Record);
737}
738
739/// \brief Write a block containing all of the types.
740void PCHWriter::WriteTypesBlock(ASTContext &Context) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000741 // Enter the types block.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000742 S.EnterSubblock(pch::TYPES_BLOCK_ID, 2);
743
744 // Emit all of the types in the ASTContext
745 for (std::vector<Type*>::const_iterator T = Context.getTypes().begin(),
746 TEnd = Context.getTypes().end();
747 T != TEnd; ++T) {
748 // Builtin types are never serialized.
749 if (isa<BuiltinType>(*T))
750 continue;
751
752 WriteType(*T);
753 }
754
755 // Exit the types block
756 S.ExitBlock();
Douglas Gregorc34897d2009-04-09 22:27:44 +0000757}
758
759/// \brief Write the block containing all of the declaration IDs
760/// lexically declared within the given DeclContext.
761///
762/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
763/// bistream, or 0 if no block was written.
764uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
765 DeclContext *DC) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000766 if (DC->decls_empty(Context))
Douglas Gregorc34897d2009-04-09 22:27:44 +0000767 return 0;
768
769 uint64_t Offset = S.GetCurrentBitNo();
770 RecordData Record;
771 for (DeclContext::decl_iterator D = DC->decls_begin(Context),
772 DEnd = DC->decls_end(Context);
773 D != DEnd; ++D)
774 AddDeclRef(*D, Record);
775
776 S.EmitRecord(pch::DECL_CONTEXT_LEXICAL, Record);
777 return Offset;
778}
779
780/// \brief Write the block containing all of the declaration IDs
781/// visible from the given DeclContext.
782///
783/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
784/// bistream, or 0 if no block was written.
785uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
786 DeclContext *DC) {
787 if (DC->getPrimaryContext() != DC)
788 return 0;
789
790 // Force the DeclContext to build a its name-lookup table.
791 DC->lookup(Context, DeclarationName());
792
793 // Serialize the contents of the mapping used for lookup. Note that,
794 // although we have two very different code paths, the serialized
795 // representation is the same for both cases: a declaration name,
796 // followed by a size, followed by references to the visible
797 // declarations that have that name.
798 uint64_t Offset = S.GetCurrentBitNo();
799 RecordData Record;
800 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
801 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
802 D != DEnd; ++D) {
803 AddDeclarationName(D->first, Record);
804 DeclContext::lookup_result Result = D->second.getLookupResult(Context);
805 Record.push_back(Result.second - Result.first);
806 for(; Result.first != Result.second; ++Result.first)
807 AddDeclRef(*Result.first, Record);
808 }
809
810 if (Record.size() == 0)
811 return 0;
812
813 S.EmitRecord(pch::DECL_CONTEXT_VISIBLE, Record);
814 return Offset;
815}
816
817/// \brief Write a block containing all of the declarations.
818void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000819 // Enter the declarations block.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000820 S.EnterSubblock(pch::DECLS_BLOCK_ID, 2);
821
822 // Emit all of the declarations.
823 RecordData Record;
824 PCHDeclWriter W(*this, Record);
825 while (!DeclsToEmit.empty()) {
826 // Pull the next declaration off the queue
827 Decl *D = DeclsToEmit.front();
828 DeclsToEmit.pop();
829
830 // If this declaration is also a DeclContext, write blocks for the
831 // declarations that lexically stored inside its context and those
832 // declarations that are visible from its context. These blocks
833 // are written before the declaration itself so that we can put
834 // their offsets into the record for the declaration.
835 uint64_t LexicalOffset = 0;
836 uint64_t VisibleOffset = 0;
837 DeclContext *DC = dyn_cast<DeclContext>(D);
838 if (DC) {
839 LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
840 VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
841 }
842
843 // Determine the ID for this declaration
Douglas Gregorac8f2802009-04-10 17:25:41 +0000844 pch::DeclID ID = DeclIDs[D];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000845 if (ID == 0)
846 ID = DeclIDs.size();
847
848 unsigned Index = ID - 1;
849
850 // Record the offset for this declaration
851 if (DeclOffsets.size() == Index)
852 DeclOffsets.push_back(S.GetCurrentBitNo());
853 else if (DeclOffsets.size() < Index) {
854 DeclOffsets.resize(Index+1);
855 DeclOffsets[Index] = S.GetCurrentBitNo();
856 }
857
858 // Build and emit a record for this declaration
859 Record.clear();
860 W.Code = (pch::DeclCode)0;
861 W.Visit(D);
862 if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
863 assert(W.Code && "Visitor did not set record code");
864 S.EmitRecord(W.Code, Record);
865 }
866
867 // Exit the declarations block
868 S.ExitBlock();
Douglas Gregorc34897d2009-04-09 22:27:44 +0000869}
870
Douglas Gregor7a224cf2009-04-11 00:14:32 +0000871/// \brief Write the identifier table into the PCH file.
872///
873/// The identifier table consists of a blob containing string data
874/// (the actual identifiers themselves) and a separate "offsets" index
875/// that maps identifier IDs to locations within the blob.
876void PCHWriter::WriteIdentifierTable() {
877 using namespace llvm;
878
879 // Create and write out the blob that contains the identifier
880 // strings.
881 RecordData IdentOffsets;
882 IdentOffsets.resize(IdentifierIDs.size());
883 {
884 // Create the identifier string data.
885 std::vector<char> Data;
886 Data.push_back(0); // Data must not be empty.
887 for (llvm::DenseMap<const IdentifierInfo *, pch::IdentID>::iterator
888 ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
889 ID != IDEnd; ++ID) {
890 assert(ID->first && "NULL identifier in identifier table");
891
892 // Make sure we're starting on an odd byte. The PCH reader
893 // expects the low bit to be set on all of the offsets.
894 if ((Data.size() & 0x01) == 0)
895 Data.push_back((char)0);
896
897 IdentOffsets[ID->second - 1] = Data.size();
898 Data.insert(Data.end(),
899 ID->first->getName(),
900 ID->first->getName() + ID->first->getLength());
901 Data.push_back((char)0);
902 }
903
904 // Create a blob abbreviation
905 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
906 Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_TABLE));
907 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name
908 unsigned IDTableAbbrev = S.EmitAbbrev(Abbrev);
909
910 // Write the identifier table
911 RecordData Record;
912 Record.push_back(pch::IDENTIFIER_TABLE);
913 S.EmitRecordWithBlob(IDTableAbbrev, Record, &Data.front(), Data.size());
914 }
915
916 // Write the offsets table for identifier IDs.
917 S.EmitRecord(pch::IDENTIFIER_OFFSET, IdentOffsets);
918}
919
Douglas Gregorc34897d2009-04-09 22:27:44 +0000920PCHWriter::PCHWriter(llvm::BitstreamWriter &S)
921 : S(S), NextTypeID(pch::NUM_PREDEF_TYPE_IDS) { }
922
Chris Lattner850eabd2009-04-10 18:08:30 +0000923void PCHWriter::WritePCH(ASTContext &Context, const Preprocessor &PP) {
Douglas Gregorc34897d2009-04-09 22:27:44 +0000924 // Emit the file header.
925 S.Emit((unsigned)'C', 8);
926 S.Emit((unsigned)'P', 8);
927 S.Emit((unsigned)'C', 8);
928 S.Emit((unsigned)'H', 8);
929
930 // The translation unit is the first declaration we'll emit.
931 DeclIDs[Context.getTranslationUnitDecl()] = 1;
932 DeclsToEmit.push(Context.getTranslationUnitDecl());
933
934 // Write the remaining PCH contents.
Douglas Gregorb5887f32009-04-10 21:16:55 +0000935 S.EnterSubblock(pch::PCH_BLOCK_ID, 3);
936 WriteTargetTriple(Context.Target);
Douglas Gregor179cfb12009-04-10 20:39:37 +0000937 WriteLanguageOptions(Context.getLangOptions());
Douglas Gregorab1cef72009-04-10 03:52:48 +0000938 WriteSourceManagerBlock(Context.getSourceManager());
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000939 WritePreprocessor(PP);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000940 WriteTypesBlock(Context);
941 WriteDeclsBlock(Context);
Douglas Gregor179cfb12009-04-10 20:39:37 +0000942 S.EmitRecord(pch::TYPE_OFFSET, TypeOffsets);
943 S.EmitRecord(pch::DECL_OFFSET, DeclOffsets);
Douglas Gregor7a224cf2009-04-11 00:14:32 +0000944 WriteIdentifierTable();
Douglas Gregorc34897d2009-04-09 22:27:44 +0000945 S.ExitBlock();
946}
947
948void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
949 Record.push_back(Loc.getRawEncoding());
950}
951
952void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
953 Record.push_back(Value.getBitWidth());
954 unsigned N = Value.getNumWords();
955 const uint64_t* Words = Value.getRawData();
956 for (unsigned I = 0; I != N; ++I)
957 Record.push_back(Words[I]);
958}
959
Douglas Gregor47f1b2c2009-04-13 18:14:40 +0000960void PCHWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) {
961 Record.push_back(Value.isUnsigned());
962 AddAPInt(Value, Record);
963}
964
Douglas Gregorc34897d2009-04-09 22:27:44 +0000965void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
Douglas Gregor7a224cf2009-04-11 00:14:32 +0000966 if (II == 0) {
967 Record.push_back(0);
968 return;
969 }
970
971 pch::IdentID &ID = IdentifierIDs[II];
972 if (ID == 0)
973 ID = IdentifierIDs.size();
974
975 Record.push_back(ID);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000976}
977
978void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
979 if (T.isNull()) {
980 Record.push_back(pch::PREDEF_TYPE_NULL_ID);
981 return;
982 }
983
984 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000985 pch::TypeID ID = 0;
Douglas Gregorc34897d2009-04-09 22:27:44 +0000986 switch (BT->getKind()) {
987 case BuiltinType::Void: ID = pch::PREDEF_TYPE_VOID_ID; break;
988 case BuiltinType::Bool: ID = pch::PREDEF_TYPE_BOOL_ID; break;
989 case BuiltinType::Char_U: ID = pch::PREDEF_TYPE_CHAR_U_ID; break;
990 case BuiltinType::UChar: ID = pch::PREDEF_TYPE_UCHAR_ID; break;
991 case BuiltinType::UShort: ID = pch::PREDEF_TYPE_USHORT_ID; break;
992 case BuiltinType::UInt: ID = pch::PREDEF_TYPE_UINT_ID; break;
993 case BuiltinType::ULong: ID = pch::PREDEF_TYPE_ULONG_ID; break;
994 case BuiltinType::ULongLong: ID = pch::PREDEF_TYPE_ULONGLONG_ID; break;
995 case BuiltinType::Char_S: ID = pch::PREDEF_TYPE_CHAR_S_ID; break;
996 case BuiltinType::SChar: ID = pch::PREDEF_TYPE_SCHAR_ID; break;
997 case BuiltinType::WChar: ID = pch::PREDEF_TYPE_WCHAR_ID; break;
998 case BuiltinType::Short: ID = pch::PREDEF_TYPE_SHORT_ID; break;
999 case BuiltinType::Int: ID = pch::PREDEF_TYPE_INT_ID; break;
1000 case BuiltinType::Long: ID = pch::PREDEF_TYPE_LONG_ID; break;
1001 case BuiltinType::LongLong: ID = pch::PREDEF_TYPE_LONGLONG_ID; break;
1002 case BuiltinType::Float: ID = pch::PREDEF_TYPE_FLOAT_ID; break;
1003 case BuiltinType::Double: ID = pch::PREDEF_TYPE_DOUBLE_ID; break;
1004 case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
1005 case BuiltinType::Overload: ID = pch::PREDEF_TYPE_OVERLOAD_ID; break;
1006 case BuiltinType::Dependent: ID = pch::PREDEF_TYPE_DEPENDENT_ID; break;
1007 }
1008
1009 Record.push_back((ID << 3) | T.getCVRQualifiers());
1010 return;
1011 }
1012
Douglas Gregorac8f2802009-04-10 17:25:41 +00001013 pch::TypeID &ID = TypeIDs[T.getTypePtr()];
Douglas Gregorc34897d2009-04-09 22:27:44 +00001014 if (ID == 0) // we haven't seen this type before
1015 ID = NextTypeID++;
1016
1017 // Encode the type qualifiers in the type reference.
1018 Record.push_back((ID << 3) | T.getCVRQualifiers());
1019}
1020
1021void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {
1022 if (D == 0) {
1023 Record.push_back(0);
1024 return;
1025 }
1026
Douglas Gregorac8f2802009-04-10 17:25:41 +00001027 pch::DeclID &ID = DeclIDs[D];
Douglas Gregorc34897d2009-04-09 22:27:44 +00001028 if (ID == 0) {
1029 // We haven't seen this declaration before. Give it a new ID and
1030 // enqueue it in the list of declarations to emit.
1031 ID = DeclIDs.size();
1032 DeclsToEmit.push(const_cast<Decl *>(D));
1033 }
1034
1035 Record.push_back(ID);
1036}
1037
1038void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
1039 Record.push_back(Name.getNameKind());
1040 switch (Name.getNameKind()) {
1041 case DeclarationName::Identifier:
1042 AddIdentifierRef(Name.getAsIdentifierInfo(), Record);
1043 break;
1044
1045 case DeclarationName::ObjCZeroArgSelector:
1046 case DeclarationName::ObjCOneArgSelector:
1047 case DeclarationName::ObjCMultiArgSelector:
1048 assert(false && "Serialization of Objective-C selectors unavailable");
1049 break;
1050
1051 case DeclarationName::CXXConstructorName:
1052 case DeclarationName::CXXDestructorName:
1053 case DeclarationName::CXXConversionFunctionName:
1054 AddTypeRef(Name.getCXXNameType(), Record);
1055 break;
1056
1057 case DeclarationName::CXXOperatorName:
1058 Record.push_back(Name.getCXXOverloadedOperator());
1059 break;
1060
1061 case DeclarationName::CXXUsingDirective:
1062 // No extra data to emit
1063 break;
1064 }
1065}