blob: 8384177621895f459957db7e82f7f5e385ede248 [file] [log] [blame]
Douglas Gregor2cf26342009-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 Lattner7c5d24e2009-04-10 18:00:12 +000020#include "clang/Lex/MacroInfo.h"
21#include "clang/Lex/Preprocessor.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000022#include "clang/Basic/FileManager.h"
23#include "clang/Basic/SourceManager.h"
Douglas Gregorbd945002009-04-13 16:31:14 +000024#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregor2bec0412009-04-10 21:16:55 +000025#include "clang/Basic/TargetInfo.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000026#include "llvm/Bitcode/BitstreamWriter.h"
27#include "llvm/Support/Compiler.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000028#include "llvm/Support/MemoryBuffer.h"
Chris Lattner3c304bd2009-04-11 18:40:46 +000029#include <cstdio>
Douglas Gregor2cf26342009-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 Gregor0a2b45e2009-04-13 18:14:40 +0000255 void VisitTagDecl(TagDecl *D);
256 void VisitEnumDecl(EnumDecl *D);
Douglas Gregor8c700062009-04-13 21:20:57 +0000257 void VisitRecordDecl(RecordDecl *D);
Douglas Gregor2cf26342009-04-09 22:27:44 +0000258 void VisitValueDecl(ValueDecl *D);
Douglas Gregor0a2b45e2009-04-13 18:14:40 +0000259 void VisitEnumConstantDecl(EnumConstantDecl *D);
Douglas Gregor3a2f7e42009-04-13 22:18:37 +0000260 void VisitFunctionDecl(FunctionDecl *D);
Douglas Gregor8c700062009-04-13 21:20:57 +0000261 void VisitFieldDecl(FieldDecl *D);
Douglas Gregor2cf26342009-04-09 22:27:44 +0000262 void VisitVarDecl(VarDecl *D);
Douglas Gregor3a2f7e42009-04-13 22:18:37 +0000263 void VisitParmVarDecl(ParmVarDecl *D);
264 void VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
Douglas Gregor2cf26342009-04-09 22:27:44 +0000265 void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
266 uint64_t VisibleOffset);
267 };
268}
269
270void PCHDeclWriter::VisitDecl(Decl *D) {
271 Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
272 Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
273 Writer.AddSourceLocation(D->getLocation(), Record);
274 Record.push_back(D->isInvalidDecl());
275 // FIXME: hasAttrs
276 Record.push_back(D->isImplicit());
277 Record.push_back(D->getAccess());
278}
279
280void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
281 VisitDecl(D);
282 Code = pch::DECL_TRANSLATION_UNIT;
283}
284
285void PCHDeclWriter::VisitNamedDecl(NamedDecl *D) {
286 VisitDecl(D);
287 Writer.AddDeclarationName(D->getDeclName(), Record);
288}
289
290void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
291 VisitNamedDecl(D);
292 Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
293}
294
295void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
296 VisitTypeDecl(D);
297 Writer.AddTypeRef(D->getUnderlyingType(), Record);
298 Code = pch::DECL_TYPEDEF;
299}
300
Douglas Gregor0a2b45e2009-04-13 18:14:40 +0000301void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
302 VisitTypeDecl(D);
303 Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
304 Record.push_back(D->isDefinition());
305 Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
306}
307
308void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) {
309 VisitTagDecl(D);
310 Writer.AddTypeRef(D->getIntegerType(), Record);
311 Code = pch::DECL_ENUM;
312}
313
Douglas Gregor8c700062009-04-13 21:20:57 +0000314void PCHDeclWriter::VisitRecordDecl(RecordDecl *D) {
315 VisitTagDecl(D);
316 Record.push_back(D->hasFlexibleArrayMember());
317 Record.push_back(D->isAnonymousStructOrUnion());
318 Code = pch::DECL_RECORD;
319}
320
Douglas Gregor2cf26342009-04-09 22:27:44 +0000321void PCHDeclWriter::VisitValueDecl(ValueDecl *D) {
322 VisitNamedDecl(D);
323 Writer.AddTypeRef(D->getType(), Record);
324}
325
Douglas Gregor0a2b45e2009-04-13 18:14:40 +0000326void PCHDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
327 VisitValueDecl(D);
328 // FIXME: Writer.AddExprRef(D->getInitExpr());
329 Writer.AddAPSInt(D->getInitVal(), Record);
330 Code = pch::DECL_ENUM_CONSTANT;
331}
332
Douglas Gregor3a2f7e42009-04-13 22:18:37 +0000333void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
334 VisitValueDecl(D);
335 // FIXME: function body
336 Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
337 Record.push_back(D->getStorageClass()); // FIXME: stable encoding
338 Record.push_back(D->isInline());
339 Record.push_back(D->isVirtual());
340 Record.push_back(D->isPure());
341 Record.push_back(D->inheritedPrototype());
342 Record.push_back(D->hasPrototype() && !D->inheritedPrototype());
343 Record.push_back(D->isDeleted());
344 Writer.AddSourceLocation(D->getTypeSpecStartLoc(), Record);
345 Record.push_back(D->param_size());
346 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
347 P != PEnd; ++P)
348 Writer.AddDeclRef(*P, Record);
349 Code = pch::DECL_FUNCTION;
350}
351
Douglas Gregor8c700062009-04-13 21:20:57 +0000352void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) {
353 VisitValueDecl(D);
354 Record.push_back(D->isMutable());
355 // FIXME: Writer.AddExprRef(D->getBitWidth());
356 Code = pch::DECL_FIELD;
357}
358
Douglas Gregor2cf26342009-04-09 22:27:44 +0000359void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
360 VisitValueDecl(D);
Douglas Gregor3a2f7e42009-04-13 22:18:37 +0000361 Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Douglas Gregor2cf26342009-04-09 22:27:44 +0000362 Record.push_back(D->isThreadSpecified());
363 Record.push_back(D->hasCXXDirectInitializer());
364 Record.push_back(D->isDeclaredInCondition());
365 Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
366 Writer.AddSourceLocation(D->getTypeSpecStartLoc(), Record);
367 // FIXME: emit initializer
368 Code = pch::DECL_VAR;
369}
370
Douglas Gregor3a2f7e42009-04-13 22:18:37 +0000371void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
372 VisitVarDecl(D);
373 Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
374 // FIXME: emit default argument
375 // FIXME: why isn't the "default argument" just stored as the initializer
376 // in VarDecl?
377 Code = pch::DECL_PARM_VAR;
378}
379
380void PCHDeclWriter::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
381 VisitParmVarDecl(D);
382 Writer.AddTypeRef(D->getOriginalType(), Record);
383 Code = pch::DECL_ORIGINAL_PARM_VAR;
384}
385
Douglas Gregor2cf26342009-04-09 22:27:44 +0000386/// \brief Emit the DeclContext part of a declaration context decl.
387///
388/// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL
389/// block for this declaration context is stored. May be 0 to indicate
390/// that there are no declarations stored within this context.
391///
392/// \param VisibleOffset the offset at which the DECL_CONTEXT_VISIBLE
393/// block for this declaration context is stored. May be 0 to indicate
394/// that there are no declarations visible from this context. Note
395/// that this value will not be emitted for non-primary declaration
396/// contexts.
397void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
398 uint64_t VisibleOffset) {
399 Record.push_back(LexicalOffset);
400 if (DC->getPrimaryContext() == DC)
401 Record.push_back(VisibleOffset);
402}
403
404//===----------------------------------------------------------------------===//
405// PCHWriter Implementation
406//===----------------------------------------------------------------------===//
407
Douglas Gregor2bec0412009-04-10 21:16:55 +0000408/// \brief Write the target triple (e.g., i686-apple-darwin9).
409void PCHWriter::WriteTargetTriple(const TargetInfo &Target) {
410 using namespace llvm;
411 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
412 Abbrev->Add(BitCodeAbbrevOp(pch::TARGET_TRIPLE));
413 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name
414 unsigned TripleAbbrev = S.EmitAbbrev(Abbrev);
415
416 RecordData Record;
417 Record.push_back(pch::TARGET_TRIPLE);
418 const char *Triple = Target.getTargetTriple();
419 S.EmitRecordWithBlob(TripleAbbrev, Record, Triple, strlen(Triple));
420}
421
422/// \brief Write the LangOptions structure.
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000423void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
424 RecordData Record;
425 Record.push_back(LangOpts.Trigraphs);
426 Record.push_back(LangOpts.BCPLComment); // BCPL-style '//' comments.
427 Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers.
428 Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode.
429 Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc)
430 Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'.
431 Record.push_back(LangOpts.Digraphs); // C94, C99 and C++
432 Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants.
433 Record.push_back(LangOpts.C99); // C99 Support
434 Record.push_back(LangOpts.Microsoft); // Microsoft extensions.
435 Record.push_back(LangOpts.CPlusPlus); // C++ Support
436 Record.push_back(LangOpts.CPlusPlus0x); // C++0x Support
437 Record.push_back(LangOpts.NoExtensions); // All extensions are disabled, strict mode.
438 Record.push_back(LangOpts.CXXOperatorNames); // Treat C++ operator names as keywords.
439
440 Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled.
441 Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled.
442 Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C modern abi enabled
443
444 Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings
445 Record.push_back(LangOpts.Boolean); // Allow bool/true/false
446 Record.push_back(LangOpts.WritableStrings); // Allow writable strings
447 Record.push_back(LangOpts.LaxVectorConversions);
448 Record.push_back(LangOpts.Exceptions); // Support exception handling.
449
450 Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime.
451 Record.push_back(LangOpts.Freestanding); // Freestanding implementation
452 Record.push_back(LangOpts.NoBuiltin); // Do not use builtin functions (-fno-builtin)
453
454 Record.push_back(LangOpts.ThreadsafeStatics); // Whether static initializers are protected
455 // by locks.
456 Record.push_back(LangOpts.Blocks); // block extension to C
457 Record.push_back(LangOpts.EmitAllDecls); // Emit all declarations, even if
458 // they are unused.
459 Record.push_back(LangOpts.MathErrno); // Math functions must respect errno
460 // (modulo the platform support).
461
462 Record.push_back(LangOpts.OverflowChecking); // Extension to call a handler function when
463 // signed integer arithmetic overflows.
464
465 Record.push_back(LangOpts.HeinousExtensions); // Extensions that we really don't like and
466 // may be ripped out at any time.
467
468 Record.push_back(LangOpts.Optimize); // Whether __OPTIMIZE__ should be defined.
469 Record.push_back(LangOpts.OptimizeSize); // Whether __OPTIMIZE_SIZE__ should be
470 // defined.
471 Record.push_back(LangOpts.Static); // Should __STATIC__ be defined (as
472 // opposed to __DYNAMIC__).
473 Record.push_back(LangOpts.PICLevel); // The value for __PIC__, if non-zero.
474
475 Record.push_back(LangOpts.GNUInline); // Should GNU inline semantics be
476 // used (instead of C99 semantics).
477 Record.push_back(LangOpts.NoInline); // Should __NO_INLINE__ be defined.
478 Record.push_back(LangOpts.getGCMode());
479 Record.push_back(LangOpts.getVisibilityMode());
480 Record.push_back(LangOpts.InstantiationDepth);
481 S.EmitRecord(pch::LANGUAGE_OPTIONS, Record);
482}
483
Douglas Gregor14f79002009-04-10 03:52:48 +0000484//===----------------------------------------------------------------------===//
485// Source Manager Serialization
486//===----------------------------------------------------------------------===//
487
488/// \brief Create an abbreviation for the SLocEntry that refers to a
489/// file.
490static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &S) {
491 using namespace llvm;
492 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
493 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_FILE_ENTRY));
494 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
495 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
496 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
497 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
498 // FIXME: Need an actual encoding for the line directives; maybe
499 // this should be an array?
500 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
501 return S.EmitAbbrev(Abbrev);
502}
503
504/// \brief Create an abbreviation for the SLocEntry that refers to a
505/// buffer.
506static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &S) {
507 using namespace llvm;
508 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
509 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_ENTRY));
510 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
511 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
512 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
513 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
514 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
515 return S.EmitAbbrev(Abbrev);
516}
517
518/// \brief Create an abbreviation for the SLocEntry that refers to a
519/// buffer's blob.
520static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &S) {
521 using namespace llvm;
522 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
523 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_BLOB));
524 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
525 return S.EmitAbbrev(Abbrev);
526}
527
528/// \brief Create an abbreviation for the SLocEntry that refers to an
529/// buffer.
530static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &S) {
531 using namespace llvm;
532 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
533 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_INSTANTIATION_ENTRY));
534 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
535 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
536 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
537 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
538 return S.EmitAbbrev(Abbrev);
539}
540
541/// \brief Writes the block containing the serialized form of the
542/// source manager.
543///
544/// TODO: We should probably use an on-disk hash table (stored in a
545/// blob), indexed based on the file name, so that we only create
546/// entries for files that we actually need. In the common case (no
547/// errors), we probably won't have to create file entries for any of
548/// the files in the AST.
549void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
Chris Lattnerf04ad692009-04-10 17:16:57 +0000550 // Enter the source manager block.
Douglas Gregor14f79002009-04-10 03:52:48 +0000551 S.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
552
553 // Abbreviations for the various kinds of source-location entries.
554 int SLocFileAbbrv = -1;
555 int SLocBufferAbbrv = -1;
556 int SLocBufferBlobAbbrv = -1;
557 int SLocInstantiationAbbrv = -1;
558
559 // Write out the source location entry table. We skip the first
560 // entry, which is always the same dummy entry.
561 RecordData Record;
562 for (SourceManager::sloc_entry_iterator
563 SLoc = SourceMgr.sloc_entry_begin() + 1,
564 SLocEnd = SourceMgr.sloc_entry_end();
565 SLoc != SLocEnd; ++SLoc) {
566 // Figure out which record code to use.
567 unsigned Code;
568 if (SLoc->isFile()) {
569 if (SLoc->getFile().getContentCache()->Entry)
570 Code = pch::SM_SLOC_FILE_ENTRY;
571 else
572 Code = pch::SM_SLOC_BUFFER_ENTRY;
573 } else
574 Code = pch::SM_SLOC_INSTANTIATION_ENTRY;
575 Record.push_back(Code);
576
577 Record.push_back(SLoc->getOffset());
578 if (SLoc->isFile()) {
579 const SrcMgr::FileInfo &File = SLoc->getFile();
580 Record.push_back(File.getIncludeLoc().getRawEncoding());
581 Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
Douglas Gregorbd945002009-04-13 16:31:14 +0000582 Record.push_back(File.hasLineDirectives());
Douglas Gregor14f79002009-04-10 03:52:48 +0000583
584 const SrcMgr::ContentCache *Content = File.getContentCache();
585 if (Content->Entry) {
586 // The source location entry is a file. The blob associated
587 // with this entry is the file name.
588 if (SLocFileAbbrv == -1)
589 SLocFileAbbrv = CreateSLocFileAbbrev(S);
590 S.EmitRecordWithBlob(SLocFileAbbrv, Record,
591 Content->Entry->getName(),
592 strlen(Content->Entry->getName()));
593 } else {
594 // The source location entry is a buffer. The blob associated
595 // with this entry contains the contents of the buffer.
596 if (SLocBufferAbbrv == -1) {
597 SLocBufferAbbrv = CreateSLocBufferAbbrev(S);
598 SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(S);
599 }
600
601 // We add one to the size so that we capture the trailing NULL
602 // that is required by llvm::MemoryBuffer::getMemBuffer (on
603 // the reader side).
604 const llvm::MemoryBuffer *Buffer = Content->getBuffer();
605 const char *Name = Buffer->getBufferIdentifier();
606 S.EmitRecordWithBlob(SLocBufferAbbrv, Record, Name, strlen(Name) + 1);
607 Record.clear();
608 Record.push_back(pch::SM_SLOC_BUFFER_BLOB);
609 S.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
610 Buffer->getBufferStart(),
611 Buffer->getBufferSize() + 1);
612 }
613 } else {
614 // The source location entry is an instantiation.
615 const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation();
616 Record.push_back(Inst.getSpellingLoc().getRawEncoding());
617 Record.push_back(Inst.getInstantiationLocStart().getRawEncoding());
618 Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding());
619
620 if (SLocInstantiationAbbrv == -1)
621 SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(S);
622 S.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record);
623 }
624
625 Record.clear();
626 }
627
Douglas Gregorbd945002009-04-13 16:31:14 +0000628 // Write the line table.
629 if (SourceMgr.hasLineTable()) {
630 LineTableInfo &LineTable = SourceMgr.getLineTable();
631
632 // Emit the file names
633 Record.push_back(LineTable.getNumFilenames());
634 for (unsigned I = 0, N = LineTable.getNumFilenames(); I != N; ++I) {
635 // Emit the file name
636 const char *Filename = LineTable.getFilename(I);
637 unsigned FilenameLen = Filename? strlen(Filename) : 0;
638 Record.push_back(FilenameLen);
639 if (FilenameLen)
640 Record.insert(Record.end(), Filename, Filename + FilenameLen);
641 }
642
643 // Emit the line entries
644 for (LineTableInfo::iterator L = LineTable.begin(), LEnd = LineTable.end();
645 L != LEnd; ++L) {
646 // Emit the file ID
647 Record.push_back(L->first);
648
649 // Emit the line entries
650 Record.push_back(L->second.size());
651 for (std::vector<LineEntry>::iterator LE = L->second.begin(),
652 LEEnd = L->second.end();
653 LE != LEEnd; ++LE) {
654 Record.push_back(LE->FileOffset);
655 Record.push_back(LE->LineNo);
656 Record.push_back(LE->FilenameID);
657 Record.push_back((unsigned)LE->FileKind);
658 Record.push_back(LE->IncludeOffset);
659 }
660 S.EmitRecord(pch::SM_LINE_TABLE, Record);
661 }
662 }
663
Douglas Gregor14f79002009-04-10 03:52:48 +0000664 S.ExitBlock();
665}
666
Chris Lattner0b1fb982009-04-10 17:15:23 +0000667/// \brief Writes the block containing the serialized form of the
668/// preprocessor.
669///
Chris Lattnerdf961c22009-04-10 18:08:30 +0000670void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
Chris Lattnerf04ad692009-04-10 17:16:57 +0000671 // Enter the preprocessor block.
672 S.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 3);
673
Chris Lattner7c5d24e2009-04-10 18:00:12 +0000674 // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
675 // FIXME: use diagnostics subsystem for localization etc.
676 if (PP.SawDateOrTime())
677 fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
Chris Lattnerf04ad692009-04-10 17:16:57 +0000678
Chris Lattner7c5d24e2009-04-10 18:00:12 +0000679 RecordData Record;
Chris Lattnerf04ad692009-04-10 17:16:57 +0000680
Chris Lattnerc1f9d822009-04-13 01:29:17 +0000681 // If the preprocessor __COUNTER__ value has been bumped, remember it.
682 if (PP.getCounterValue() != 0) {
683 Record.push_back(PP.getCounterValue());
684 S.EmitRecord(pch::PP_COUNTER_VALUE, Record);
685 Record.clear();
686 }
687
Chris Lattner7c5d24e2009-04-10 18:00:12 +0000688 // Loop over all the macro definitions that are live at the end of the file,
689 // emitting each to the PP section.
690 // FIXME: Eventually we want to emit an index so that we can lazily load
691 // macros.
692 for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
693 I != E; ++I) {
Chris Lattner42d42b52009-04-10 21:41:48 +0000694 // FIXME: This emits macros in hash table order, we should do it in a stable
695 // order so that output is reproducible.
Chris Lattner7c5d24e2009-04-10 18:00:12 +0000696 MacroInfo *MI = I->second;
697
698 // Don't emit builtin macros like __LINE__ to the PCH file unless they have
699 // been redefined by the header (in which case they are not isBuiltinMacro).
700 if (MI->isBuiltinMacro())
701 continue;
702
Chris Lattner7356a312009-04-11 21:15:38 +0000703 AddIdentifierRef(I->first, Record);
Chris Lattner7c5d24e2009-04-10 18:00:12 +0000704 Record.push_back(MI->getDefinitionLoc().getRawEncoding());
705 Record.push_back(MI->isUsed());
706
707 unsigned Code;
708 if (MI->isObjectLike()) {
709 Code = pch::PP_MACRO_OBJECT_LIKE;
710 } else {
711 Code = pch::PP_MACRO_FUNCTION_LIKE;
712
713 Record.push_back(MI->isC99Varargs());
714 Record.push_back(MI->isGNUVarargs());
715 Record.push_back(MI->getNumArgs());
716 for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
717 I != E; ++I)
Chris Lattner7356a312009-04-11 21:15:38 +0000718 AddIdentifierRef(*I, Record);
Chris Lattner7c5d24e2009-04-10 18:00:12 +0000719 }
720 S.EmitRecord(Code, Record);
721 Record.clear();
722
Chris Lattnerdf961c22009-04-10 18:08:30 +0000723 // Emit the tokens array.
724 for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
725 // Note that we know that the preprocessor does not have any annotation
726 // tokens in it because they are created by the parser, and thus can't be
727 // in a macro definition.
728 const Token &Tok = MI->getReplacementToken(TokNo);
729
730 Record.push_back(Tok.getLocation().getRawEncoding());
731 Record.push_back(Tok.getLength());
732
Chris Lattnerdf961c22009-04-10 18:08:30 +0000733 // FIXME: When reading literal tokens, reconstruct the literal pointer if
734 // it is needed.
Chris Lattner7356a312009-04-11 21:15:38 +0000735 AddIdentifierRef(Tok.getIdentifierInfo(), Record);
Chris Lattnerdf961c22009-04-10 18:08:30 +0000736
737 // FIXME: Should translate token kind to a stable encoding.
738 Record.push_back(Tok.getKind());
739 // FIXME: Should translate token flags to a stable encoding.
740 Record.push_back(Tok.getFlags());
741
742 S.EmitRecord(pch::PP_TOKEN, Record);
743 Record.clear();
744 }
Chris Lattner7c5d24e2009-04-10 18:00:12 +0000745
746 }
747
Chris Lattnerf04ad692009-04-10 17:16:57 +0000748 S.ExitBlock();
Chris Lattner0b1fb982009-04-10 17:15:23 +0000749}
750
751
Douglas Gregor2cf26342009-04-09 22:27:44 +0000752/// \brief Write the representation of a type to the PCH stream.
753void PCHWriter::WriteType(const Type *T) {
Douglas Gregor8038d512009-04-10 17:25:41 +0000754 pch::TypeID &ID = TypeIDs[T];
Chris Lattnerf04ad692009-04-10 17:16:57 +0000755 if (ID == 0) // we haven't seen this type before.
Douglas Gregor2cf26342009-04-09 22:27:44 +0000756 ID = NextTypeID++;
757
758 // Record the offset for this type.
759 if (TypeOffsets.size() == ID - pch::NUM_PREDEF_TYPE_IDS)
760 TypeOffsets.push_back(S.GetCurrentBitNo());
761 else if (TypeOffsets.size() < ID - pch::NUM_PREDEF_TYPE_IDS) {
762 TypeOffsets.resize(ID + 1 - pch::NUM_PREDEF_TYPE_IDS);
763 TypeOffsets[ID - pch::NUM_PREDEF_TYPE_IDS] = S.GetCurrentBitNo();
764 }
765
766 RecordData Record;
767
768 // Emit the type's representation.
769 PCHTypeWriter W(*this, Record);
770 switch (T->getTypeClass()) {
771 // For all of the concrete, non-dependent types, call the
772 // appropriate visitor function.
773#define TYPE(Class, Base) \
774 case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
775#define ABSTRACT_TYPE(Class, Base)
776#define DEPENDENT_TYPE(Class, Base)
777#include "clang/AST/TypeNodes.def"
778
779 // For all of the dependent type nodes (which only occur in C++
780 // templates), produce an error.
781#define TYPE(Class, Base)
782#define DEPENDENT_TYPE(Class, Base) case Type::Class:
783#include "clang/AST/TypeNodes.def"
784 assert(false && "Cannot serialize dependent type nodes");
785 break;
786 }
787
788 // Emit the serialized record.
789 S.EmitRecord(W.Code, Record);
790}
791
792/// \brief Write a block containing all of the types.
793void PCHWriter::WriteTypesBlock(ASTContext &Context) {
Chris Lattnerf04ad692009-04-10 17:16:57 +0000794 // Enter the types block.
Douglas Gregor2cf26342009-04-09 22:27:44 +0000795 S.EnterSubblock(pch::TYPES_BLOCK_ID, 2);
796
797 // Emit all of the types in the ASTContext
798 for (std::vector<Type*>::const_iterator T = Context.getTypes().begin(),
799 TEnd = Context.getTypes().end();
800 T != TEnd; ++T) {
801 // Builtin types are never serialized.
802 if (isa<BuiltinType>(*T))
803 continue;
804
805 WriteType(*T);
806 }
807
808 // Exit the types block
809 S.ExitBlock();
Douglas Gregor2cf26342009-04-09 22:27:44 +0000810}
811
812/// \brief Write the block containing all of the declaration IDs
813/// lexically declared within the given DeclContext.
814///
815/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
816/// bistream, or 0 if no block was written.
817uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
818 DeclContext *DC) {
Douglas Gregor8038d512009-04-10 17:25:41 +0000819 if (DC->decls_empty(Context))
Douglas Gregor2cf26342009-04-09 22:27:44 +0000820 return 0;
821
822 uint64_t Offset = S.GetCurrentBitNo();
823 RecordData Record;
824 for (DeclContext::decl_iterator D = DC->decls_begin(Context),
825 DEnd = DC->decls_end(Context);
826 D != DEnd; ++D)
827 AddDeclRef(*D, Record);
828
829 S.EmitRecord(pch::DECL_CONTEXT_LEXICAL, Record);
830 return Offset;
831}
832
833/// \brief Write the block containing all of the declaration IDs
834/// visible from the given DeclContext.
835///
836/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
837/// bistream, or 0 if no block was written.
838uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
839 DeclContext *DC) {
840 if (DC->getPrimaryContext() != DC)
841 return 0;
842
843 // Force the DeclContext to build a its name-lookup table.
844 DC->lookup(Context, DeclarationName());
845
846 // Serialize the contents of the mapping used for lookup. Note that,
847 // although we have two very different code paths, the serialized
848 // representation is the same for both cases: a declaration name,
849 // followed by a size, followed by references to the visible
850 // declarations that have that name.
851 uint64_t Offset = S.GetCurrentBitNo();
852 RecordData Record;
853 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
Douglas Gregor8c700062009-04-13 21:20:57 +0000854 if (!Map)
855 return 0;
856
Douglas Gregor2cf26342009-04-09 22:27:44 +0000857 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
858 D != DEnd; ++D) {
859 AddDeclarationName(D->first, Record);
860 DeclContext::lookup_result Result = D->second.getLookupResult(Context);
861 Record.push_back(Result.second - Result.first);
862 for(; Result.first != Result.second; ++Result.first)
863 AddDeclRef(*Result.first, Record);
864 }
865
866 if (Record.size() == 0)
867 return 0;
868
869 S.EmitRecord(pch::DECL_CONTEXT_VISIBLE, Record);
870 return Offset;
871}
872
873/// \brief Write a block containing all of the declarations.
874void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
Chris Lattnerf04ad692009-04-10 17:16:57 +0000875 // Enter the declarations block.
Douglas Gregor2cf26342009-04-09 22:27:44 +0000876 S.EnterSubblock(pch::DECLS_BLOCK_ID, 2);
877
878 // Emit all of the declarations.
879 RecordData Record;
880 PCHDeclWriter W(*this, Record);
881 while (!DeclsToEmit.empty()) {
882 // Pull the next declaration off the queue
883 Decl *D = DeclsToEmit.front();
884 DeclsToEmit.pop();
885
886 // If this declaration is also a DeclContext, write blocks for the
887 // declarations that lexically stored inside its context and those
888 // declarations that are visible from its context. These blocks
889 // are written before the declaration itself so that we can put
890 // their offsets into the record for the declaration.
891 uint64_t LexicalOffset = 0;
892 uint64_t VisibleOffset = 0;
893 DeclContext *DC = dyn_cast<DeclContext>(D);
894 if (DC) {
895 LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
896 VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
897 }
898
899 // Determine the ID for this declaration
Douglas Gregor8038d512009-04-10 17:25:41 +0000900 pch::DeclID ID = DeclIDs[D];
Douglas Gregor2cf26342009-04-09 22:27:44 +0000901 if (ID == 0)
902 ID = DeclIDs.size();
903
904 unsigned Index = ID - 1;
905
906 // Record the offset for this declaration
907 if (DeclOffsets.size() == Index)
908 DeclOffsets.push_back(S.GetCurrentBitNo());
909 else if (DeclOffsets.size() < Index) {
910 DeclOffsets.resize(Index+1);
911 DeclOffsets[Index] = S.GetCurrentBitNo();
912 }
913
914 // Build and emit a record for this declaration
915 Record.clear();
916 W.Code = (pch::DeclCode)0;
917 W.Visit(D);
918 if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
919 assert(W.Code && "Visitor did not set record code");
920 S.EmitRecord(W.Code, Record);
921 }
922
923 // Exit the declarations block
924 S.ExitBlock();
Douglas Gregor2cf26342009-04-09 22:27:44 +0000925}
926
Douglas Gregorafaf3082009-04-11 00:14:32 +0000927/// \brief Write the identifier table into the PCH file.
928///
929/// The identifier table consists of a blob containing string data
930/// (the actual identifiers themselves) and a separate "offsets" index
931/// that maps identifier IDs to locations within the blob.
932void PCHWriter::WriteIdentifierTable() {
933 using namespace llvm;
934
935 // Create and write out the blob that contains the identifier
936 // strings.
937 RecordData IdentOffsets;
938 IdentOffsets.resize(IdentifierIDs.size());
939 {
940 // Create the identifier string data.
941 std::vector<char> Data;
942 Data.push_back(0); // Data must not be empty.
943 for (llvm::DenseMap<const IdentifierInfo *, pch::IdentID>::iterator
944 ID = IdentifierIDs.begin(), IDEnd = IdentifierIDs.end();
945 ID != IDEnd; ++ID) {
946 assert(ID->first && "NULL identifier in identifier table");
947
948 // Make sure we're starting on an odd byte. The PCH reader
949 // expects the low bit to be set on all of the offsets.
950 if ((Data.size() & 0x01) == 0)
951 Data.push_back((char)0);
952
953 IdentOffsets[ID->second - 1] = Data.size();
954 Data.insert(Data.end(),
955 ID->first->getName(),
956 ID->first->getName() + ID->first->getLength());
957 Data.push_back((char)0);
958 }
959
960 // Create a blob abbreviation
961 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
962 Abbrev->Add(BitCodeAbbrevOp(pch::IDENTIFIER_TABLE));
963 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Triple name
964 unsigned IDTableAbbrev = S.EmitAbbrev(Abbrev);
965
966 // Write the identifier table
967 RecordData Record;
968 Record.push_back(pch::IDENTIFIER_TABLE);
969 S.EmitRecordWithBlob(IDTableAbbrev, Record, &Data.front(), Data.size());
970 }
971
972 // Write the offsets table for identifier IDs.
973 S.EmitRecord(pch::IDENTIFIER_OFFSET, IdentOffsets);
974}
975
Douglas Gregor2cf26342009-04-09 22:27:44 +0000976PCHWriter::PCHWriter(llvm::BitstreamWriter &S)
977 : S(S), NextTypeID(pch::NUM_PREDEF_TYPE_IDS) { }
978
Chris Lattnerdf961c22009-04-10 18:08:30 +0000979void PCHWriter::WritePCH(ASTContext &Context, const Preprocessor &PP) {
Douglas Gregor2cf26342009-04-09 22:27:44 +0000980 // Emit the file header.
981 S.Emit((unsigned)'C', 8);
982 S.Emit((unsigned)'P', 8);
983 S.Emit((unsigned)'C', 8);
984 S.Emit((unsigned)'H', 8);
985
986 // The translation unit is the first declaration we'll emit.
987 DeclIDs[Context.getTranslationUnitDecl()] = 1;
988 DeclsToEmit.push(Context.getTranslationUnitDecl());
989
990 // Write the remaining PCH contents.
Douglas Gregor2bec0412009-04-10 21:16:55 +0000991 S.EnterSubblock(pch::PCH_BLOCK_ID, 3);
992 WriteTargetTriple(Context.Target);
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000993 WriteLanguageOptions(Context.getLangOptions());
Douglas Gregor14f79002009-04-10 03:52:48 +0000994 WriteSourceManagerBlock(Context.getSourceManager());
Chris Lattner0b1fb982009-04-10 17:15:23 +0000995 WritePreprocessor(PP);
Douglas Gregor2cf26342009-04-09 22:27:44 +0000996 WriteTypesBlock(Context);
997 WriteDeclsBlock(Context);
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000998 S.EmitRecord(pch::TYPE_OFFSET, TypeOffsets);
999 S.EmitRecord(pch::DECL_OFFSET, DeclOffsets);
Douglas Gregorafaf3082009-04-11 00:14:32 +00001000 WriteIdentifierTable();
Douglas Gregor2cf26342009-04-09 22:27:44 +00001001 S.ExitBlock();
1002}
1003
1004void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
1005 Record.push_back(Loc.getRawEncoding());
1006}
1007
1008void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
1009 Record.push_back(Value.getBitWidth());
1010 unsigned N = Value.getNumWords();
1011 const uint64_t* Words = Value.getRawData();
1012 for (unsigned I = 0; I != N; ++I)
1013 Record.push_back(Words[I]);
1014}
1015
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00001016void PCHWriter::AddAPSInt(const llvm::APSInt &Value, RecordData &Record) {
1017 Record.push_back(Value.isUnsigned());
1018 AddAPInt(Value, Record);
1019}
1020
Douglas Gregor2cf26342009-04-09 22:27:44 +00001021void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
Douglas Gregorafaf3082009-04-11 00:14:32 +00001022 if (II == 0) {
1023 Record.push_back(0);
1024 return;
1025 }
1026
1027 pch::IdentID &ID = IdentifierIDs[II];
1028 if (ID == 0)
1029 ID = IdentifierIDs.size();
1030
1031 Record.push_back(ID);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001032}
1033
1034void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
1035 if (T.isNull()) {
1036 Record.push_back(pch::PREDEF_TYPE_NULL_ID);
1037 return;
1038 }
1039
1040 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
Douglas Gregore1d918e2009-04-10 23:10:45 +00001041 pch::TypeID ID = 0;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001042 switch (BT->getKind()) {
1043 case BuiltinType::Void: ID = pch::PREDEF_TYPE_VOID_ID; break;
1044 case BuiltinType::Bool: ID = pch::PREDEF_TYPE_BOOL_ID; break;
1045 case BuiltinType::Char_U: ID = pch::PREDEF_TYPE_CHAR_U_ID; break;
1046 case BuiltinType::UChar: ID = pch::PREDEF_TYPE_UCHAR_ID; break;
1047 case BuiltinType::UShort: ID = pch::PREDEF_TYPE_USHORT_ID; break;
1048 case BuiltinType::UInt: ID = pch::PREDEF_TYPE_UINT_ID; break;
1049 case BuiltinType::ULong: ID = pch::PREDEF_TYPE_ULONG_ID; break;
1050 case BuiltinType::ULongLong: ID = pch::PREDEF_TYPE_ULONGLONG_ID; break;
1051 case BuiltinType::Char_S: ID = pch::PREDEF_TYPE_CHAR_S_ID; break;
1052 case BuiltinType::SChar: ID = pch::PREDEF_TYPE_SCHAR_ID; break;
1053 case BuiltinType::WChar: ID = pch::PREDEF_TYPE_WCHAR_ID; break;
1054 case BuiltinType::Short: ID = pch::PREDEF_TYPE_SHORT_ID; break;
1055 case BuiltinType::Int: ID = pch::PREDEF_TYPE_INT_ID; break;
1056 case BuiltinType::Long: ID = pch::PREDEF_TYPE_LONG_ID; break;
1057 case BuiltinType::LongLong: ID = pch::PREDEF_TYPE_LONGLONG_ID; break;
1058 case BuiltinType::Float: ID = pch::PREDEF_TYPE_FLOAT_ID; break;
1059 case BuiltinType::Double: ID = pch::PREDEF_TYPE_DOUBLE_ID; break;
1060 case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
1061 case BuiltinType::Overload: ID = pch::PREDEF_TYPE_OVERLOAD_ID; break;
1062 case BuiltinType::Dependent: ID = pch::PREDEF_TYPE_DEPENDENT_ID; break;
1063 }
1064
1065 Record.push_back((ID << 3) | T.getCVRQualifiers());
1066 return;
1067 }
1068
Douglas Gregor8038d512009-04-10 17:25:41 +00001069 pch::TypeID &ID = TypeIDs[T.getTypePtr()];
Douglas Gregor2cf26342009-04-09 22:27:44 +00001070 if (ID == 0) // we haven't seen this type before
1071 ID = NextTypeID++;
1072
1073 // Encode the type qualifiers in the type reference.
1074 Record.push_back((ID << 3) | T.getCVRQualifiers());
1075}
1076
1077void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {
1078 if (D == 0) {
1079 Record.push_back(0);
1080 return;
1081 }
1082
Douglas Gregor8038d512009-04-10 17:25:41 +00001083 pch::DeclID &ID = DeclIDs[D];
Douglas Gregor2cf26342009-04-09 22:27:44 +00001084 if (ID == 0) {
1085 // We haven't seen this declaration before. Give it a new ID and
1086 // enqueue it in the list of declarations to emit.
1087 ID = DeclIDs.size();
1088 DeclsToEmit.push(const_cast<Decl *>(D));
1089 }
1090
1091 Record.push_back(ID);
1092}
1093
1094void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
1095 Record.push_back(Name.getNameKind());
1096 switch (Name.getNameKind()) {
1097 case DeclarationName::Identifier:
1098 AddIdentifierRef(Name.getAsIdentifierInfo(), Record);
1099 break;
1100
1101 case DeclarationName::ObjCZeroArgSelector:
1102 case DeclarationName::ObjCOneArgSelector:
1103 case DeclarationName::ObjCMultiArgSelector:
1104 assert(false && "Serialization of Objective-C selectors unavailable");
1105 break;
1106
1107 case DeclarationName::CXXConstructorName:
1108 case DeclarationName::CXXDestructorName:
1109 case DeclarationName::CXXConversionFunctionName:
1110 AddTypeRef(Name.getCXXNameType(), Record);
1111 break;
1112
1113 case DeclarationName::CXXOperatorName:
1114 Record.push_back(Name.getCXXOverloadedOperator());
1115 break;
1116
1117 case DeclarationName::CXXUsingDirective:
1118 // No extra data to emit
1119 break;
1120 }
1121}