blob: 05447dcd6ac8f5f369b97e0c05bbf3209083e5f4 [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 Gregorab1cef72009-04-10 03:52:48 +0000331//===----------------------------------------------------------------------===//
332// Source Manager Serialization
333//===----------------------------------------------------------------------===//
334
335/// \brief Create an abbreviation for the SLocEntry that refers to a
336/// file.
337static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &S) {
338 using namespace llvm;
339 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
340 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_FILE_ENTRY));
341 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
342 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
343 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
344 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
345 // FIXME: Need an actual encoding for the line directives; maybe
346 // this should be an array?
347 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
348 return S.EmitAbbrev(Abbrev);
349}
350
351/// \brief Create an abbreviation for the SLocEntry that refers to a
352/// buffer.
353static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &S) {
354 using namespace llvm;
355 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
356 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_ENTRY));
357 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
358 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
359 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Characteristic
360 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
361 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
362 return S.EmitAbbrev(Abbrev);
363}
364
365/// \brief Create an abbreviation for the SLocEntry that refers to a
366/// buffer's blob.
367static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &S) {
368 using namespace llvm;
369 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
370 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_BUFFER_BLOB));
371 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
372 return S.EmitAbbrev(Abbrev);
373}
374
375/// \brief Create an abbreviation for the SLocEntry that refers to an
376/// buffer.
377static unsigned CreateSLocInstantiationAbbrev(llvm::BitstreamWriter &S) {
378 using namespace llvm;
379 BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
380 Abbrev->Add(BitCodeAbbrevOp(pch::SM_SLOC_INSTANTIATION_ENTRY));
381 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
382 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
383 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location
384 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location
385 return S.EmitAbbrev(Abbrev);
386}
387
388/// \brief Writes the block containing the serialized form of the
389/// source manager.
390///
391/// TODO: We should probably use an on-disk hash table (stored in a
392/// blob), indexed based on the file name, so that we only create
393/// entries for files that we actually need. In the common case (no
394/// errors), we probably won't have to create file entries for any of
395/// the files in the AST.
396void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000397 // Enter the source manager block.
Douglas Gregorab1cef72009-04-10 03:52:48 +0000398 S.EnterSubblock(pch::SOURCE_MANAGER_BLOCK_ID, 3);
399
400 // Abbreviations for the various kinds of source-location entries.
401 int SLocFileAbbrv = -1;
402 int SLocBufferAbbrv = -1;
403 int SLocBufferBlobAbbrv = -1;
404 int SLocInstantiationAbbrv = -1;
405
406 // Write out the source location entry table. We skip the first
407 // entry, which is always the same dummy entry.
408 RecordData Record;
409 for (SourceManager::sloc_entry_iterator
410 SLoc = SourceMgr.sloc_entry_begin() + 1,
411 SLocEnd = SourceMgr.sloc_entry_end();
412 SLoc != SLocEnd; ++SLoc) {
413 // Figure out which record code to use.
414 unsigned Code;
415 if (SLoc->isFile()) {
416 if (SLoc->getFile().getContentCache()->Entry)
417 Code = pch::SM_SLOC_FILE_ENTRY;
418 else
419 Code = pch::SM_SLOC_BUFFER_ENTRY;
420 } else
421 Code = pch::SM_SLOC_INSTANTIATION_ENTRY;
422 Record.push_back(Code);
423
424 Record.push_back(SLoc->getOffset());
425 if (SLoc->isFile()) {
426 const SrcMgr::FileInfo &File = SLoc->getFile();
427 Record.push_back(File.getIncludeLoc().getRawEncoding());
428 Record.push_back(File.getFileCharacteristic()); // FIXME: stable encoding
429 Record.push_back(File.hasLineDirectives()); // FIXME: encode the
430 // line directives?
431
432 const SrcMgr::ContentCache *Content = File.getContentCache();
433 if (Content->Entry) {
434 // The source location entry is a file. The blob associated
435 // with this entry is the file name.
436 if (SLocFileAbbrv == -1)
437 SLocFileAbbrv = CreateSLocFileAbbrev(S);
438 S.EmitRecordWithBlob(SLocFileAbbrv, Record,
439 Content->Entry->getName(),
440 strlen(Content->Entry->getName()));
441 } else {
442 // The source location entry is a buffer. The blob associated
443 // with this entry contains the contents of the buffer.
444 if (SLocBufferAbbrv == -1) {
445 SLocBufferAbbrv = CreateSLocBufferAbbrev(S);
446 SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(S);
447 }
448
449 // We add one to the size so that we capture the trailing NULL
450 // that is required by llvm::MemoryBuffer::getMemBuffer (on
451 // the reader side).
452 const llvm::MemoryBuffer *Buffer = Content->getBuffer();
453 const char *Name = Buffer->getBufferIdentifier();
454 S.EmitRecordWithBlob(SLocBufferAbbrv, Record, Name, strlen(Name) + 1);
455 Record.clear();
456 Record.push_back(pch::SM_SLOC_BUFFER_BLOB);
457 S.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
458 Buffer->getBufferStart(),
459 Buffer->getBufferSize() + 1);
460 }
461 } else {
462 // The source location entry is an instantiation.
463 const SrcMgr::InstantiationInfo &Inst = SLoc->getInstantiation();
464 Record.push_back(Inst.getSpellingLoc().getRawEncoding());
465 Record.push_back(Inst.getInstantiationLocStart().getRawEncoding());
466 Record.push_back(Inst.getInstantiationLocEnd().getRawEncoding());
467
468 if (SLocInstantiationAbbrv == -1)
469 SLocInstantiationAbbrv = CreateSLocInstantiationAbbrev(S);
470 S.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record);
471 }
472
473 Record.clear();
474 }
475
476 S.ExitBlock();
477}
478
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000479/// \brief Writes the block containing the serialized form of the
480/// preprocessor.
481///
482void PCHWriter::WritePreprocessor(Preprocessor &PP) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000483 // Enter the preprocessor block.
484 S.EnterSubblock(pch::PREPROCESSOR_BLOCK_ID, 3);
485
Chris Lattner1b094952009-04-10 18:00:12 +0000486 // If the PCH file contains __DATE__ or __TIME__ emit a warning about this.
487 // FIXME: use diagnostics subsystem for localization etc.
488 if (PP.SawDateOrTime())
489 fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
Chris Lattner84b04f12009-04-10 17:16:57 +0000490
Chris Lattner1b094952009-04-10 18:00:12 +0000491 RecordData Record;
Chris Lattner84b04f12009-04-10 17:16:57 +0000492
Chris Lattner1b094952009-04-10 18:00:12 +0000493 // Loop over all the macro definitions that are live at the end of the file,
494 // emitting each to the PP section.
495 // FIXME: Eventually we want to emit an index so that we can lazily load
496 // macros.
497 for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
498 I != E; ++I) {
499 MacroInfo *MI = I->second;
500
501 // Don't emit builtin macros like __LINE__ to the PCH file unless they have
502 // been redefined by the header (in which case they are not isBuiltinMacro).
503 if (MI->isBuiltinMacro())
504 continue;
505
506 IdentifierInfo *II = I->first;
507
508 // FIXME: Output the identifier Info ID #!
509 Record.push_back((intptr_t)II);
510 Record.push_back(MI->getDefinitionLoc().getRawEncoding());
511 Record.push_back(MI->isUsed());
512
513 unsigned Code;
514 if (MI->isObjectLike()) {
515 Code = pch::PP_MACRO_OBJECT_LIKE;
516 } else {
517 Code = pch::PP_MACRO_FUNCTION_LIKE;
518
519 Record.push_back(MI->isC99Varargs());
520 Record.push_back(MI->isGNUVarargs());
521 Record.push_back(MI->getNumArgs());
522 for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
523 I != E; ++I)
524 // FIXME: Output the identifier Info ID #!
525 Record.push_back((intptr_t)II);
526 }
527 S.EmitRecord(Code, Record);
528 Record.clear();
529
530 // FIXME: Emit the tokens array.
531
532 }
533
534 // TODO: someday when PP supports __COUNTER__, emit a record for its value if
535 // non-zero.
Chris Lattner84b04f12009-04-10 17:16:57 +0000536
537 S.ExitBlock();
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000538}
539
540
Douglas Gregorc34897d2009-04-09 22:27:44 +0000541/// \brief Write the representation of a type to the PCH stream.
542void PCHWriter::WriteType(const Type *T) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000543 pch::TypeID &ID = TypeIDs[T];
Chris Lattner84b04f12009-04-10 17:16:57 +0000544 if (ID == 0) // we haven't seen this type before.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000545 ID = NextTypeID++;
546
547 // Record the offset for this type.
548 if (TypeOffsets.size() == ID - pch::NUM_PREDEF_TYPE_IDS)
549 TypeOffsets.push_back(S.GetCurrentBitNo());
550 else if (TypeOffsets.size() < ID - pch::NUM_PREDEF_TYPE_IDS) {
551 TypeOffsets.resize(ID + 1 - pch::NUM_PREDEF_TYPE_IDS);
552 TypeOffsets[ID - pch::NUM_PREDEF_TYPE_IDS] = S.GetCurrentBitNo();
553 }
554
555 RecordData Record;
556
557 // Emit the type's representation.
558 PCHTypeWriter W(*this, Record);
559 switch (T->getTypeClass()) {
560 // For all of the concrete, non-dependent types, call the
561 // appropriate visitor function.
562#define TYPE(Class, Base) \
563 case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
564#define ABSTRACT_TYPE(Class, Base)
565#define DEPENDENT_TYPE(Class, Base)
566#include "clang/AST/TypeNodes.def"
567
568 // For all of the dependent type nodes (which only occur in C++
569 // templates), produce an error.
570#define TYPE(Class, Base)
571#define DEPENDENT_TYPE(Class, Base) case Type::Class:
572#include "clang/AST/TypeNodes.def"
573 assert(false && "Cannot serialize dependent type nodes");
574 break;
575 }
576
577 // Emit the serialized record.
578 S.EmitRecord(W.Code, Record);
579}
580
581/// \brief Write a block containing all of the types.
582void PCHWriter::WriteTypesBlock(ASTContext &Context) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000583 // Enter the types block.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000584 S.EnterSubblock(pch::TYPES_BLOCK_ID, 2);
585
586 // Emit all of the types in the ASTContext
587 for (std::vector<Type*>::const_iterator T = Context.getTypes().begin(),
588 TEnd = Context.getTypes().end();
589 T != TEnd; ++T) {
590 // Builtin types are never serialized.
591 if (isa<BuiltinType>(*T))
592 continue;
593
594 WriteType(*T);
595 }
596
597 // Exit the types block
598 S.ExitBlock();
599
Douglas Gregorac8f2802009-04-10 17:25:41 +0000600 // Write the type offsets record
Douglas Gregorc34897d2009-04-09 22:27:44 +0000601 S.EmitRecord(pch::TYPE_OFFSET, TypeOffsets);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000602}
603
604/// \brief Write the block containing all of the declaration IDs
605/// lexically declared within the given DeclContext.
606///
607/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
608/// bistream, or 0 if no block was written.
609uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
610 DeclContext *DC) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000611 if (DC->decls_empty(Context))
Douglas Gregorc34897d2009-04-09 22:27:44 +0000612 return 0;
613
614 uint64_t Offset = S.GetCurrentBitNo();
615 RecordData Record;
616 for (DeclContext::decl_iterator D = DC->decls_begin(Context),
617 DEnd = DC->decls_end(Context);
618 D != DEnd; ++D)
619 AddDeclRef(*D, Record);
620
621 S.EmitRecord(pch::DECL_CONTEXT_LEXICAL, Record);
622 return Offset;
623}
624
625/// \brief Write the block containing all of the declaration IDs
626/// visible from the given DeclContext.
627///
628/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
629/// bistream, or 0 if no block was written.
630uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
631 DeclContext *DC) {
632 if (DC->getPrimaryContext() != DC)
633 return 0;
634
635 // Force the DeclContext to build a its name-lookup table.
636 DC->lookup(Context, DeclarationName());
637
638 // Serialize the contents of the mapping used for lookup. Note that,
639 // although we have two very different code paths, the serialized
640 // representation is the same for both cases: a declaration name,
641 // followed by a size, followed by references to the visible
642 // declarations that have that name.
643 uint64_t Offset = S.GetCurrentBitNo();
644 RecordData Record;
645 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
646 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
647 D != DEnd; ++D) {
648 AddDeclarationName(D->first, Record);
649 DeclContext::lookup_result Result = D->second.getLookupResult(Context);
650 Record.push_back(Result.second - Result.first);
651 for(; Result.first != Result.second; ++Result.first)
652 AddDeclRef(*Result.first, Record);
653 }
654
655 if (Record.size() == 0)
656 return 0;
657
658 S.EmitRecord(pch::DECL_CONTEXT_VISIBLE, Record);
659 return Offset;
660}
661
662/// \brief Write a block containing all of the declarations.
663void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000664 // Enter the declarations block.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000665 S.EnterSubblock(pch::DECLS_BLOCK_ID, 2);
666
667 // Emit all of the declarations.
668 RecordData Record;
669 PCHDeclWriter W(*this, Record);
670 while (!DeclsToEmit.empty()) {
671 // Pull the next declaration off the queue
672 Decl *D = DeclsToEmit.front();
673 DeclsToEmit.pop();
674
675 // If this declaration is also a DeclContext, write blocks for the
676 // declarations that lexically stored inside its context and those
677 // declarations that are visible from its context. These blocks
678 // are written before the declaration itself so that we can put
679 // their offsets into the record for the declaration.
680 uint64_t LexicalOffset = 0;
681 uint64_t VisibleOffset = 0;
682 DeclContext *DC = dyn_cast<DeclContext>(D);
683 if (DC) {
684 LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
685 VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
686 }
687
688 // Determine the ID for this declaration
Douglas Gregorac8f2802009-04-10 17:25:41 +0000689 pch::DeclID ID = DeclIDs[D];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000690 if (ID == 0)
691 ID = DeclIDs.size();
692
693 unsigned Index = ID - 1;
694
695 // Record the offset for this declaration
696 if (DeclOffsets.size() == Index)
697 DeclOffsets.push_back(S.GetCurrentBitNo());
698 else if (DeclOffsets.size() < Index) {
699 DeclOffsets.resize(Index+1);
700 DeclOffsets[Index] = S.GetCurrentBitNo();
701 }
702
703 // Build and emit a record for this declaration
704 Record.clear();
705 W.Code = (pch::DeclCode)0;
706 W.Visit(D);
707 if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
708 assert(W.Code && "Visitor did not set record code");
709 S.EmitRecord(W.Code, Record);
710 }
711
712 // Exit the declarations block
713 S.ExitBlock();
714
Douglas Gregorac8f2802009-04-10 17:25:41 +0000715 // Write the declaration offsets record
Douglas Gregorc34897d2009-04-09 22:27:44 +0000716 S.EmitRecord(pch::DECL_OFFSET, DeclOffsets);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000717}
718
719PCHWriter::PCHWriter(llvm::BitstreamWriter &S)
720 : S(S), NextTypeID(pch::NUM_PREDEF_TYPE_IDS) { }
721
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000722void PCHWriter::WritePCH(ASTContext &Context, Preprocessor &PP) {
Douglas Gregorc34897d2009-04-09 22:27:44 +0000723 // Emit the file header.
724 S.Emit((unsigned)'C', 8);
725 S.Emit((unsigned)'P', 8);
726 S.Emit((unsigned)'C', 8);
727 S.Emit((unsigned)'H', 8);
728
729 // The translation unit is the first declaration we'll emit.
730 DeclIDs[Context.getTranslationUnitDecl()] = 1;
731 DeclsToEmit.push(Context.getTranslationUnitDecl());
732
733 // Write the remaining PCH contents.
734 S.EnterSubblock(pch::PCH_BLOCK_ID, 2);
Douglas Gregorab1cef72009-04-10 03:52:48 +0000735 WriteSourceManagerBlock(Context.getSourceManager());
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000736 WritePreprocessor(PP);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000737 WriteTypesBlock(Context);
738 WriteDeclsBlock(Context);
739 S.ExitBlock();
740}
741
742void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
743 Record.push_back(Loc.getRawEncoding());
744}
745
746void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
747 Record.push_back(Value.getBitWidth());
748 unsigned N = Value.getNumWords();
749 const uint64_t* Words = Value.getRawData();
750 for (unsigned I = 0; I != N; ++I)
751 Record.push_back(Words[I]);
752}
753
754void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
755 // FIXME: Emit an identifier ID, not the actual string!
756 const char *Name = II->getName();
757 unsigned Len = strlen(Name);
758 Record.push_back(Len);
759 Record.insert(Record.end(), Name, Name + Len);
760}
761
762void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
763 if (T.isNull()) {
764 Record.push_back(pch::PREDEF_TYPE_NULL_ID);
765 return;
766 }
767
768 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000769 pch::TypeID ID;
Douglas Gregorc34897d2009-04-09 22:27:44 +0000770 switch (BT->getKind()) {
771 case BuiltinType::Void: ID = pch::PREDEF_TYPE_VOID_ID; break;
772 case BuiltinType::Bool: ID = pch::PREDEF_TYPE_BOOL_ID; break;
773 case BuiltinType::Char_U: ID = pch::PREDEF_TYPE_CHAR_U_ID; break;
774 case BuiltinType::UChar: ID = pch::PREDEF_TYPE_UCHAR_ID; break;
775 case BuiltinType::UShort: ID = pch::PREDEF_TYPE_USHORT_ID; break;
776 case BuiltinType::UInt: ID = pch::PREDEF_TYPE_UINT_ID; break;
777 case BuiltinType::ULong: ID = pch::PREDEF_TYPE_ULONG_ID; break;
778 case BuiltinType::ULongLong: ID = pch::PREDEF_TYPE_ULONGLONG_ID; break;
779 case BuiltinType::Char_S: ID = pch::PREDEF_TYPE_CHAR_S_ID; break;
780 case BuiltinType::SChar: ID = pch::PREDEF_TYPE_SCHAR_ID; break;
781 case BuiltinType::WChar: ID = pch::PREDEF_TYPE_WCHAR_ID; break;
782 case BuiltinType::Short: ID = pch::PREDEF_TYPE_SHORT_ID; break;
783 case BuiltinType::Int: ID = pch::PREDEF_TYPE_INT_ID; break;
784 case BuiltinType::Long: ID = pch::PREDEF_TYPE_LONG_ID; break;
785 case BuiltinType::LongLong: ID = pch::PREDEF_TYPE_LONGLONG_ID; break;
786 case BuiltinType::Float: ID = pch::PREDEF_TYPE_FLOAT_ID; break;
787 case BuiltinType::Double: ID = pch::PREDEF_TYPE_DOUBLE_ID; break;
788 case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
789 case BuiltinType::Overload: ID = pch::PREDEF_TYPE_OVERLOAD_ID; break;
790 case BuiltinType::Dependent: ID = pch::PREDEF_TYPE_DEPENDENT_ID; break;
791 }
792
793 Record.push_back((ID << 3) | T.getCVRQualifiers());
794 return;
795 }
796
Douglas Gregorac8f2802009-04-10 17:25:41 +0000797 pch::TypeID &ID = TypeIDs[T.getTypePtr()];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000798 if (ID == 0) // we haven't seen this type before
799 ID = NextTypeID++;
800
801 // Encode the type qualifiers in the type reference.
802 Record.push_back((ID << 3) | T.getCVRQualifiers());
803}
804
805void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {
806 if (D == 0) {
807 Record.push_back(0);
808 return;
809 }
810
Douglas Gregorac8f2802009-04-10 17:25:41 +0000811 pch::DeclID &ID = DeclIDs[D];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000812 if (ID == 0) {
813 // We haven't seen this declaration before. Give it a new ID and
814 // enqueue it in the list of declarations to emit.
815 ID = DeclIDs.size();
816 DeclsToEmit.push(const_cast<Decl *>(D));
817 }
818
819 Record.push_back(ID);
820}
821
822void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
823 Record.push_back(Name.getNameKind());
824 switch (Name.getNameKind()) {
825 case DeclarationName::Identifier:
826 AddIdentifierRef(Name.getAsIdentifierInfo(), Record);
827 break;
828
829 case DeclarationName::ObjCZeroArgSelector:
830 case DeclarationName::ObjCOneArgSelector:
831 case DeclarationName::ObjCMultiArgSelector:
832 assert(false && "Serialization of Objective-C selectors unavailable");
833 break;
834
835 case DeclarationName::CXXConstructorName:
836 case DeclarationName::CXXDestructorName:
837 case DeclarationName::CXXConversionFunctionName:
838 AddTypeRef(Name.getCXXNameType(), Record);
839 break;
840
841 case DeclarationName::CXXOperatorName:
842 Record.push_back(Name.getCXXOverloadedOperator());
843 break;
844
845 case DeclarationName::CXXUsingDirective:
846 // No extra data to emit
847 break;
848 }
849}