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