blob: 255ce8bf8d77b728a3ab04f6b61068c56919f6de [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///
Chris Lattner850eabd2009-04-10 18:08:30 +0000482void PCHWriter::WritePreprocessor(const 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
Chris Lattner850eabd2009-04-10 18:08:30 +0000530 // Emit the tokens array.
531 for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
532 // Note that we know that the preprocessor does not have any annotation
533 // tokens in it because they are created by the parser, and thus can't be
534 // in a macro definition.
535 const Token &Tok = MI->getReplacementToken(TokNo);
536
537 Record.push_back(Tok.getLocation().getRawEncoding());
538 Record.push_back(Tok.getLength());
539
540 // FIXME: Output the identifier Info ID #!
541 // FIXME: When reading literal tokens, reconstruct the literal pointer if
542 // it is needed.
543 Record.push_back((intptr_t)Tok.getIdentifierInfo());
544
545 // FIXME: Should translate token kind to a stable encoding.
546 Record.push_back(Tok.getKind());
547 // FIXME: Should translate token flags to a stable encoding.
548 Record.push_back(Tok.getFlags());
549
550 S.EmitRecord(pch::PP_TOKEN, Record);
551 Record.clear();
552 }
Chris Lattner1b094952009-04-10 18:00:12 +0000553
554 }
555
556 // TODO: someday when PP supports __COUNTER__, emit a record for its value if
557 // non-zero.
Chris Lattner84b04f12009-04-10 17:16:57 +0000558
559 S.ExitBlock();
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000560}
561
562
Douglas Gregorc34897d2009-04-09 22:27:44 +0000563/// \brief Write the representation of a type to the PCH stream.
564void PCHWriter::WriteType(const Type *T) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000565 pch::TypeID &ID = TypeIDs[T];
Chris Lattner84b04f12009-04-10 17:16:57 +0000566 if (ID == 0) // we haven't seen this type before.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000567 ID = NextTypeID++;
568
569 // Record the offset for this type.
570 if (TypeOffsets.size() == ID - pch::NUM_PREDEF_TYPE_IDS)
571 TypeOffsets.push_back(S.GetCurrentBitNo());
572 else if (TypeOffsets.size() < ID - pch::NUM_PREDEF_TYPE_IDS) {
573 TypeOffsets.resize(ID + 1 - pch::NUM_PREDEF_TYPE_IDS);
574 TypeOffsets[ID - pch::NUM_PREDEF_TYPE_IDS] = S.GetCurrentBitNo();
575 }
576
577 RecordData Record;
578
579 // Emit the type's representation.
580 PCHTypeWriter W(*this, Record);
581 switch (T->getTypeClass()) {
582 // For all of the concrete, non-dependent types, call the
583 // appropriate visitor function.
584#define TYPE(Class, Base) \
585 case Type::Class: W.Visit##Class##Type(cast<Class##Type>(T)); break;
586#define ABSTRACT_TYPE(Class, Base)
587#define DEPENDENT_TYPE(Class, Base)
588#include "clang/AST/TypeNodes.def"
589
590 // For all of the dependent type nodes (which only occur in C++
591 // templates), produce an error.
592#define TYPE(Class, Base)
593#define DEPENDENT_TYPE(Class, Base) case Type::Class:
594#include "clang/AST/TypeNodes.def"
595 assert(false && "Cannot serialize dependent type nodes");
596 break;
597 }
598
599 // Emit the serialized record.
600 S.EmitRecord(W.Code, Record);
601}
602
603/// \brief Write a block containing all of the types.
604void PCHWriter::WriteTypesBlock(ASTContext &Context) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000605 // Enter the types block.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000606 S.EnterSubblock(pch::TYPES_BLOCK_ID, 2);
607
608 // Emit all of the types in the ASTContext
609 for (std::vector<Type*>::const_iterator T = Context.getTypes().begin(),
610 TEnd = Context.getTypes().end();
611 T != TEnd; ++T) {
612 // Builtin types are never serialized.
613 if (isa<BuiltinType>(*T))
614 continue;
615
616 WriteType(*T);
617 }
618
619 // Exit the types block
620 S.ExitBlock();
621
Douglas Gregorac8f2802009-04-10 17:25:41 +0000622 // Write the type offsets record
Douglas Gregorc34897d2009-04-09 22:27:44 +0000623 S.EmitRecord(pch::TYPE_OFFSET, TypeOffsets);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000624}
625
626/// \brief Write the block containing all of the declaration IDs
627/// lexically declared within the given DeclContext.
628///
629/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
630/// bistream, or 0 if no block was written.
631uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
632 DeclContext *DC) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000633 if (DC->decls_empty(Context))
Douglas Gregorc34897d2009-04-09 22:27:44 +0000634 return 0;
635
636 uint64_t Offset = S.GetCurrentBitNo();
637 RecordData Record;
638 for (DeclContext::decl_iterator D = DC->decls_begin(Context),
639 DEnd = DC->decls_end(Context);
640 D != DEnd; ++D)
641 AddDeclRef(*D, Record);
642
643 S.EmitRecord(pch::DECL_CONTEXT_LEXICAL, Record);
644 return Offset;
645}
646
647/// \brief Write the block containing all of the declaration IDs
648/// visible from the given DeclContext.
649///
650/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
651/// bistream, or 0 if no block was written.
652uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
653 DeclContext *DC) {
654 if (DC->getPrimaryContext() != DC)
655 return 0;
656
657 // Force the DeclContext to build a its name-lookup table.
658 DC->lookup(Context, DeclarationName());
659
660 // Serialize the contents of the mapping used for lookup. Note that,
661 // although we have two very different code paths, the serialized
662 // representation is the same for both cases: a declaration name,
663 // followed by a size, followed by references to the visible
664 // declarations that have that name.
665 uint64_t Offset = S.GetCurrentBitNo();
666 RecordData Record;
667 StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
668 for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
669 D != DEnd; ++D) {
670 AddDeclarationName(D->first, Record);
671 DeclContext::lookup_result Result = D->second.getLookupResult(Context);
672 Record.push_back(Result.second - Result.first);
673 for(; Result.first != Result.second; ++Result.first)
674 AddDeclRef(*Result.first, Record);
675 }
676
677 if (Record.size() == 0)
678 return 0;
679
680 S.EmitRecord(pch::DECL_CONTEXT_VISIBLE, Record);
681 return Offset;
682}
683
684/// \brief Write a block containing all of the declarations.
685void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
Chris Lattner84b04f12009-04-10 17:16:57 +0000686 // Enter the declarations block.
Douglas Gregorc34897d2009-04-09 22:27:44 +0000687 S.EnterSubblock(pch::DECLS_BLOCK_ID, 2);
688
689 // Emit all of the declarations.
690 RecordData Record;
691 PCHDeclWriter W(*this, Record);
692 while (!DeclsToEmit.empty()) {
693 // Pull the next declaration off the queue
694 Decl *D = DeclsToEmit.front();
695 DeclsToEmit.pop();
696
697 // If this declaration is also a DeclContext, write blocks for the
698 // declarations that lexically stored inside its context and those
699 // declarations that are visible from its context. These blocks
700 // are written before the declaration itself so that we can put
701 // their offsets into the record for the declaration.
702 uint64_t LexicalOffset = 0;
703 uint64_t VisibleOffset = 0;
704 DeclContext *DC = dyn_cast<DeclContext>(D);
705 if (DC) {
706 LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
707 VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
708 }
709
710 // Determine the ID for this declaration
Douglas Gregorac8f2802009-04-10 17:25:41 +0000711 pch::DeclID ID = DeclIDs[D];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000712 if (ID == 0)
713 ID = DeclIDs.size();
714
715 unsigned Index = ID - 1;
716
717 // Record the offset for this declaration
718 if (DeclOffsets.size() == Index)
719 DeclOffsets.push_back(S.GetCurrentBitNo());
720 else if (DeclOffsets.size() < Index) {
721 DeclOffsets.resize(Index+1);
722 DeclOffsets[Index] = S.GetCurrentBitNo();
723 }
724
725 // Build and emit a record for this declaration
726 Record.clear();
727 W.Code = (pch::DeclCode)0;
728 W.Visit(D);
729 if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
730 assert(W.Code && "Visitor did not set record code");
731 S.EmitRecord(W.Code, Record);
732 }
733
734 // Exit the declarations block
735 S.ExitBlock();
736
Douglas Gregorac8f2802009-04-10 17:25:41 +0000737 // Write the declaration offsets record
Douglas Gregorc34897d2009-04-09 22:27:44 +0000738 S.EmitRecord(pch::DECL_OFFSET, DeclOffsets);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000739}
740
741PCHWriter::PCHWriter(llvm::BitstreamWriter &S)
742 : S(S), NextTypeID(pch::NUM_PREDEF_TYPE_IDS) { }
743
Chris Lattner850eabd2009-04-10 18:08:30 +0000744void PCHWriter::WritePCH(ASTContext &Context, const Preprocessor &PP) {
Douglas Gregorc34897d2009-04-09 22:27:44 +0000745 // Emit the file header.
746 S.Emit((unsigned)'C', 8);
747 S.Emit((unsigned)'P', 8);
748 S.Emit((unsigned)'C', 8);
749 S.Emit((unsigned)'H', 8);
750
751 // The translation unit is the first declaration we'll emit.
752 DeclIDs[Context.getTranslationUnitDecl()] = 1;
753 DeclsToEmit.push(Context.getTranslationUnitDecl());
754
755 // Write the remaining PCH contents.
756 S.EnterSubblock(pch::PCH_BLOCK_ID, 2);
Douglas Gregorab1cef72009-04-10 03:52:48 +0000757 WriteSourceManagerBlock(Context.getSourceManager());
Chris Lattnerffc05ed2009-04-10 17:15:23 +0000758 WritePreprocessor(PP);
Douglas Gregorc34897d2009-04-09 22:27:44 +0000759 WriteTypesBlock(Context);
760 WriteDeclsBlock(Context);
761 S.ExitBlock();
762}
763
764void PCHWriter::AddSourceLocation(SourceLocation Loc, RecordData &Record) {
765 Record.push_back(Loc.getRawEncoding());
766}
767
768void PCHWriter::AddAPInt(const llvm::APInt &Value, RecordData &Record) {
769 Record.push_back(Value.getBitWidth());
770 unsigned N = Value.getNumWords();
771 const uint64_t* Words = Value.getRawData();
772 for (unsigned I = 0; I != N; ++I)
773 Record.push_back(Words[I]);
774}
775
776void PCHWriter::AddIdentifierRef(const IdentifierInfo *II, RecordData &Record) {
777 // FIXME: Emit an identifier ID, not the actual string!
778 const char *Name = II->getName();
779 unsigned Len = strlen(Name);
780 Record.push_back(Len);
781 Record.insert(Record.end(), Name, Name + Len);
782}
783
784void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
785 if (T.isNull()) {
786 Record.push_back(pch::PREDEF_TYPE_NULL_ID);
787 return;
788 }
789
790 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
Douglas Gregorac8f2802009-04-10 17:25:41 +0000791 pch::TypeID ID;
Douglas Gregorc34897d2009-04-09 22:27:44 +0000792 switch (BT->getKind()) {
793 case BuiltinType::Void: ID = pch::PREDEF_TYPE_VOID_ID; break;
794 case BuiltinType::Bool: ID = pch::PREDEF_TYPE_BOOL_ID; break;
795 case BuiltinType::Char_U: ID = pch::PREDEF_TYPE_CHAR_U_ID; break;
796 case BuiltinType::UChar: ID = pch::PREDEF_TYPE_UCHAR_ID; break;
797 case BuiltinType::UShort: ID = pch::PREDEF_TYPE_USHORT_ID; break;
798 case BuiltinType::UInt: ID = pch::PREDEF_TYPE_UINT_ID; break;
799 case BuiltinType::ULong: ID = pch::PREDEF_TYPE_ULONG_ID; break;
800 case BuiltinType::ULongLong: ID = pch::PREDEF_TYPE_ULONGLONG_ID; break;
801 case BuiltinType::Char_S: ID = pch::PREDEF_TYPE_CHAR_S_ID; break;
802 case BuiltinType::SChar: ID = pch::PREDEF_TYPE_SCHAR_ID; break;
803 case BuiltinType::WChar: ID = pch::PREDEF_TYPE_WCHAR_ID; break;
804 case BuiltinType::Short: ID = pch::PREDEF_TYPE_SHORT_ID; break;
805 case BuiltinType::Int: ID = pch::PREDEF_TYPE_INT_ID; break;
806 case BuiltinType::Long: ID = pch::PREDEF_TYPE_LONG_ID; break;
807 case BuiltinType::LongLong: ID = pch::PREDEF_TYPE_LONGLONG_ID; break;
808 case BuiltinType::Float: ID = pch::PREDEF_TYPE_FLOAT_ID; break;
809 case BuiltinType::Double: ID = pch::PREDEF_TYPE_DOUBLE_ID; break;
810 case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
811 case BuiltinType::Overload: ID = pch::PREDEF_TYPE_OVERLOAD_ID; break;
812 case BuiltinType::Dependent: ID = pch::PREDEF_TYPE_DEPENDENT_ID; break;
813 }
814
815 Record.push_back((ID << 3) | T.getCVRQualifiers());
816 return;
817 }
818
Douglas Gregorac8f2802009-04-10 17:25:41 +0000819 pch::TypeID &ID = TypeIDs[T.getTypePtr()];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000820 if (ID == 0) // we haven't seen this type before
821 ID = NextTypeID++;
822
823 // Encode the type qualifiers in the type reference.
824 Record.push_back((ID << 3) | T.getCVRQualifiers());
825}
826
827void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {
828 if (D == 0) {
829 Record.push_back(0);
830 return;
831 }
832
Douglas Gregorac8f2802009-04-10 17:25:41 +0000833 pch::DeclID &ID = DeclIDs[D];
Douglas Gregorc34897d2009-04-09 22:27:44 +0000834 if (ID == 0) {
835 // We haven't seen this declaration before. Give it a new ID and
836 // enqueue it in the list of declarations to emit.
837 ID = DeclIDs.size();
838 DeclsToEmit.push(const_cast<Decl *>(D));
839 }
840
841 Record.push_back(ID);
842}
843
844void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
845 Record.push_back(Name.getNameKind());
846 switch (Name.getNameKind()) {
847 case DeclarationName::Identifier:
848 AddIdentifierRef(Name.getAsIdentifierInfo(), Record);
849 break;
850
851 case DeclarationName::ObjCZeroArgSelector:
852 case DeclarationName::ObjCOneArgSelector:
853 case DeclarationName::ObjCMultiArgSelector:
854 assert(false && "Serialization of Objective-C selectors unavailable");
855 break;
856
857 case DeclarationName::CXXConstructorName:
858 case DeclarationName::CXXDestructorName:
859 case DeclarationName::CXXConversionFunctionName:
860 AddTypeRef(Name.getCXXNameType(), Record);
861 break;
862
863 case DeclarationName::CXXOperatorName:
864 Record.push_back(Name.getCXXOverloadedOperator());
865 break;
866
867 case DeclarationName::CXXUsingDirective:
868 // No extra data to emit
869 break;
870 }
871}