blob: c605148e2bf2319556770664ee30b20352c207f2 [file] [log] [blame]
Chris Lattner12b1c762009-04-27 06:16:06 +00001//===--- PCHWriterDecl.cpp - Declaration Serialization --------------------===//
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 implements serialization for Declarations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Frontend/PCHWriter.h"
15#include "clang/AST/DeclVisitor.h"
16#include "clang/AST/Expr.h"
Argyrios Kyrtzidisd4a7e542009-08-19 01:28:35 +000017#include "clang/AST/TypeLoc.h"
Chris Lattner12b1c762009-04-27 06:16:06 +000018#include "llvm/Bitcode/BitstreamWriter.h"
19using namespace clang;
20
21//===----------------------------------------------------------------------===//
22// Declaration serialization
23//===----------------------------------------------------------------------===//
24
25namespace {
26 class PCHDeclWriter : public DeclVisitor<PCHDeclWriter, void> {
27
28 PCHWriter &Writer;
29 ASTContext &Context;
30 PCHWriter::RecordData &Record;
31
32 public:
33 pch::DeclCode Code;
Chris Lattnerea5ce472009-04-27 07:35:58 +000034 unsigned AbbrevToUse;
Chris Lattner12b1c762009-04-27 06:16:06 +000035
36 PCHDeclWriter(PCHWriter &Writer, ASTContext &Context,
37 PCHWriter::RecordData &Record)
Chris Lattnerea5ce472009-04-27 07:35:58 +000038 : Writer(Writer), Context(Context), Record(Record) {
39 }
Chris Lattner12b1c762009-04-27 06:16:06 +000040
41 void VisitDecl(Decl *D);
42 void VisitTranslationUnitDecl(TranslationUnitDecl *D);
43 void VisitNamedDecl(NamedDecl *D);
44 void VisitTypeDecl(TypeDecl *D);
45 void VisitTypedefDecl(TypedefDecl *D);
46 void VisitTagDecl(TagDecl *D);
47 void VisitEnumDecl(EnumDecl *D);
48 void VisitRecordDecl(RecordDecl *D);
49 void VisitValueDecl(ValueDecl *D);
50 void VisitEnumConstantDecl(EnumConstantDecl *D);
Argyrios Kyrtzidisd4a7e542009-08-19 01:28:35 +000051 void VisitDeclaratorDecl(DeclaratorDecl *D);
Chris Lattner12b1c762009-04-27 06:16:06 +000052 void VisitFunctionDecl(FunctionDecl *D);
53 void VisitFieldDecl(FieldDecl *D);
54 void VisitVarDecl(VarDecl *D);
55 void VisitImplicitParamDecl(ImplicitParamDecl *D);
56 void VisitParmVarDecl(ParmVarDecl *D);
57 void VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
58 void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
59 void VisitBlockDecl(BlockDecl *D);
60 void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
61 uint64_t VisibleOffset);
62 void VisitObjCMethodDecl(ObjCMethodDecl *D);
63 void VisitObjCContainerDecl(ObjCContainerDecl *D);
64 void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
65 void VisitObjCIvarDecl(ObjCIvarDecl *D);
66 void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
67 void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
68 void VisitObjCClassDecl(ObjCClassDecl *D);
69 void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
70 void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
71 void VisitObjCImplDecl(ObjCImplDecl *D);
72 void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
73 void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
74 void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
75 void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
76 void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
77 };
78}
79
80void PCHDeclWriter::VisitDecl(Decl *D) {
81 Writer.AddDeclRef(cast_or_null<Decl>(D->getDeclContext()), Record);
82 Writer.AddDeclRef(cast_or_null<Decl>(D->getLexicalDeclContext()), Record);
83 Writer.AddSourceLocation(D->getLocation(), Record);
84 Record.push_back(D->isInvalidDecl());
85 Record.push_back(D->hasAttrs());
86 Record.push_back(D->isImplicit());
Douglas Gregore0762c92009-06-19 23:52:42 +000087 Record.push_back(D->isUsed());
Chris Lattner12b1c762009-04-27 06:16:06 +000088 Record.push_back(D->getAccess());
89}
90
91void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
92 VisitDecl(D);
93 Code = pch::DECL_TRANSLATION_UNIT;
94}
95
96void PCHDeclWriter::VisitNamedDecl(NamedDecl *D) {
97 VisitDecl(D);
98 Writer.AddDeclarationName(D->getDeclName(), Record);
99}
100
101void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
102 VisitNamedDecl(D);
103 Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
104}
105
106void PCHDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
107 VisitTypeDecl(D);
108 Writer.AddTypeRef(D->getUnderlyingType(), Record);
109 Code = pch::DECL_TYPEDEF;
110}
111
112void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
113 VisitTypeDecl(D);
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000114 Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Chris Lattner12b1c762009-04-27 06:16:06 +0000115 Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
116 Record.push_back(D->isDefinition());
117 Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
Argyrios Kyrtzidisad93a742009-07-14 03:18:02 +0000118 Writer.AddSourceLocation(D->getRBraceLoc(), Record);
Douglas Gregor741dd9a2009-07-21 14:46:17 +0000119 Writer.AddSourceLocation(D->getTagKeywordLoc(), Record);
Chris Lattner12b1c762009-04-27 06:16:06 +0000120}
121
122void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) {
123 VisitTagDecl(D);
124 Writer.AddTypeRef(D->getIntegerType(), Record);
Douglas Gregor8dbc3c62009-05-27 17:20:35 +0000125 // FIXME: C++ InstantiatedFrom
Chris Lattner12b1c762009-04-27 06:16:06 +0000126 Code = pch::DECL_ENUM;
127}
128
129void PCHDeclWriter::VisitRecordDecl(RecordDecl *D) {
130 VisitTagDecl(D);
131 Record.push_back(D->hasFlexibleArrayMember());
132 Record.push_back(D->isAnonymousStructOrUnion());
Fariborz Jahanian643b7df2009-07-08 16:37:44 +0000133 Record.push_back(D->hasObjectMember());
Chris Lattner12b1c762009-04-27 06:16:06 +0000134 Code = pch::DECL_RECORD;
135}
136
137void PCHDeclWriter::VisitValueDecl(ValueDecl *D) {
138 VisitNamedDecl(D);
139 Writer.AddTypeRef(D->getType(), Record);
140}
141
142void PCHDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {
143 VisitValueDecl(D);
144 Record.push_back(D->getInitExpr()? 1 : 0);
145 if (D->getInitExpr())
146 Writer.AddStmt(D->getInitExpr());
147 Writer.AddAPSInt(D->getInitVal(), Record);
148 Code = pch::DECL_ENUM_CONSTANT;
149}
Argyrios Kyrtzidisd4a7e542009-08-19 01:28:35 +0000150namespace {
151
152class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
153 PCHWriter &Writer;
154 PCHWriter::RecordData &Record;
155
156public:
157 TypeLocWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
158 : Writer(Writer), Record(Record) { }
159
160#define ABSTRACT_TYPELOC(CLASS)
161#define TYPELOC(CLASS, PARENT, TYPE) \
162 void Visit##CLASS(CLASS TyLoc);
163#include "clang/AST/TypeLocNodes.def"
164
165 void VisitTypeLoc(TypeLoc TyLoc) {
166 assert(0 && "A type loc wrapper was not handled!");
167 }
168};
169
170}
171
172void TypeLocWriter::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) {
173 Writer.AddSourceLocation(TyLoc.getStartLoc(), Record);
174}
175void TypeLocWriter::VisitTypedefLoc(TypedefLoc TyLoc) {
176 Writer.AddSourceLocation(TyLoc.getNameLoc(), Record);
177}
178void TypeLocWriter::VisitPointerLoc(PointerLoc TyLoc) {
179 Writer.AddSourceLocation(TyLoc.getStarLoc(), Record);
180}
181void TypeLocWriter::VisitBlockPointerLoc(BlockPointerLoc TyLoc) {
182 Writer.AddSourceLocation(TyLoc.getCaretLoc(), Record);
183}
184void TypeLocWriter::VisitMemberPointerLoc(MemberPointerLoc TyLoc) {
185 Writer.AddSourceLocation(TyLoc.getStarLoc(), Record);
186}
187void TypeLocWriter::VisitReferenceLoc(ReferenceLoc TyLoc) {
188 Writer.AddSourceLocation(TyLoc.getAmpLoc(), Record);
189}
190void TypeLocWriter::VisitFunctionLoc(FunctionLoc TyLoc) {
191 Writer.AddSourceLocation(TyLoc.getLParenLoc(), Record);
192 Writer.AddSourceLocation(TyLoc.getRParenLoc(), Record);
193 for (unsigned i = 0, e = TyLoc.getNumArgs(); i != e; ++i)
194 Writer.AddDeclRef(TyLoc.getArg(i), Record);
195}
196void TypeLocWriter::VisitArrayLoc(ArrayLoc TyLoc) {
197 Writer.AddSourceLocation(TyLoc.getLBracketLoc(), Record);
198 Writer.AddSourceLocation(TyLoc.getRBracketLoc(), Record);
199 Record.push_back(TyLoc.getSizeExpr() ? 1 : 0);
200 if (TyLoc.getSizeExpr())
201 Writer.AddStmt(TyLoc.getSizeExpr());
202}
203
204void PCHDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {
205 VisitValueDecl(D);
206 DeclaratorInfo *DInfo = D->getDeclaratorInfo();
207 if (DInfo == 0) {
208 Writer.AddTypeRef(QualType(), Record);
209 return;
210 }
211
212 Writer.AddTypeRef(DInfo->getTypeLoc().getSourceType(), Record);
213 TypeLocWriter TLW(Writer, Record);
214 for (TypeLoc TL = DInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
215 TLW.Visit(TL);
216}
Chris Lattner12b1c762009-04-27 06:16:06 +0000217
218void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Argyrios Kyrtzidisd4a7e542009-08-19 01:28:35 +0000219 VisitDeclaratorDecl(D);
Chris Lattner12b1c762009-04-27 06:16:06 +0000220 Record.push_back(D->isThisDeclarationADefinition());
221 if (D->isThisDeclarationADefinition())
Argyrios Kyrtzidis6fb0aee2009-06-30 02:35:26 +0000222 Writer.AddStmt(D->getBody());
Chris Lattner12b1c762009-04-27 06:16:06 +0000223 Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
224 Record.push_back(D->getStorageClass()); // FIXME: stable encoding
225 Record.push_back(D->isInline());
226 Record.push_back(D->isC99InlineDefinition());
Anders Carlsson77b7f1d2009-05-14 22:15:41 +0000227 Record.push_back(D->isVirtualAsWritten());
Chris Lattner12b1c762009-04-27 06:16:06 +0000228 Record.push_back(D->isPure());
Anders Carlssona75e8532009-05-14 21:46:00 +0000229 Record.push_back(D->hasInheritedPrototype());
230 Record.push_back(D->hasWrittenPrototype());
Chris Lattner12b1c762009-04-27 06:16:06 +0000231 Record.push_back(D->isDeleted());
Argyrios Kyrtzidis8cff90e2009-06-20 08:09:34 +0000232 Writer.AddSourceLocation(D->getLocEnd(), Record);
Douglas Gregor1eee0e72009-05-14 21:06:31 +0000233 // FIXME: C++ TemplateOrInstantiation
Chris Lattner12b1c762009-04-27 06:16:06 +0000234 Record.push_back(D->param_size());
235 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
236 P != PEnd; ++P)
237 Writer.AddDeclRef(*P, Record);
238 Code = pch::DECL_FUNCTION;
239}
240
241void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
242 VisitNamedDecl(D);
243 // FIXME: convert to LazyStmtPtr?
244 // Unlike C/C++, method bodies will never be in header files.
245 Record.push_back(D->getBody() != 0);
246 if (D->getBody() != 0) {
Argyrios Kyrtzidis6fb0aee2009-06-30 02:35:26 +0000247 Writer.AddStmt(D->getBody());
Chris Lattner12b1c762009-04-27 06:16:06 +0000248 Writer.AddDeclRef(D->getSelfDecl(), Record);
249 Writer.AddDeclRef(D->getCmdDecl(), Record);
250 }
251 Record.push_back(D->isInstanceMethod());
252 Record.push_back(D->isVariadic());
253 Record.push_back(D->isSynthesized());
254 // FIXME: stable encoding for @required/@optional
255 Record.push_back(D->getImplementationControl());
256 // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
257 Record.push_back(D->getObjCDeclQualifier());
258 Writer.AddTypeRef(D->getResultType(), Record);
259 Writer.AddSourceLocation(D->getLocEnd(), Record);
260 Record.push_back(D->param_size());
261 for (ObjCMethodDecl::param_iterator P = D->param_begin(),
262 PEnd = D->param_end(); P != PEnd; ++P)
263 Writer.AddDeclRef(*P, Record);
264 Code = pch::DECL_OBJC_METHOD;
265}
266
267void PCHDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
268 VisitNamedDecl(D);
269 Writer.AddSourceLocation(D->getAtEndLoc(), Record);
270 // Abstract class (no need to define a stable pch::DECL code).
271}
272
273void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
274 VisitObjCContainerDecl(D);
275 Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
276 Writer.AddDeclRef(D->getSuperClass(), Record);
277 Record.push_back(D->protocol_size());
278 for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
279 PEnd = D->protocol_end();
280 P != PEnd; ++P)
281 Writer.AddDeclRef(*P, Record);
282 Record.push_back(D->ivar_size());
283 for (ObjCInterfaceDecl::ivar_iterator I = D->ivar_begin(),
284 IEnd = D->ivar_end(); I != IEnd; ++I)
285 Writer.AddDeclRef(*I, Record);
286 Writer.AddDeclRef(D->getCategoryList(), Record);
287 Record.push_back(D->isForwardDecl());
288 Record.push_back(D->isImplicitInterfaceDecl());
289 Writer.AddSourceLocation(D->getClassLoc(), Record);
290 Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
291 Writer.AddSourceLocation(D->getLocEnd(), Record);
292 Code = pch::DECL_OBJC_INTERFACE;
293}
294
295void PCHDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
296 VisitFieldDecl(D);
297 // FIXME: stable encoding for @public/@private/@protected/@package
298 Record.push_back(D->getAccessControl());
299 Code = pch::DECL_OBJC_IVAR;
300}
301
302void PCHDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
303 VisitObjCContainerDecl(D);
304 Record.push_back(D->isForwardDecl());
305 Writer.AddSourceLocation(D->getLocEnd(), Record);
306 Record.push_back(D->protocol_size());
307 for (ObjCProtocolDecl::protocol_iterator
308 I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
309 Writer.AddDeclRef(*I, Record);
310 Code = pch::DECL_OBJC_PROTOCOL;
311}
312
313void PCHDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
314 VisitFieldDecl(D);
315 Code = pch::DECL_OBJC_AT_DEFS_FIELD;
316}
317
318void PCHDeclWriter::VisitObjCClassDecl(ObjCClassDecl *D) {
319 VisitDecl(D);
320 Record.push_back(D->size());
321 for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
322 Writer.AddDeclRef(*I, Record);
323 Code = pch::DECL_OBJC_CLASS;
324}
325
326void PCHDeclWriter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
327 VisitDecl(D);
328 Record.push_back(D->protocol_size());
329 for (ObjCProtocolDecl::protocol_iterator
330 I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
331 Writer.AddDeclRef(*I, Record);
332 Code = pch::DECL_OBJC_FORWARD_PROTOCOL;
333}
334
335void PCHDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
336 VisitObjCContainerDecl(D);
337 Writer.AddDeclRef(D->getClassInterface(), Record);
338 Record.push_back(D->protocol_size());
339 for (ObjCProtocolDecl::protocol_iterator
340 I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
341 Writer.AddDeclRef(*I, Record);
342 Writer.AddDeclRef(D->getNextClassCategory(), Record);
343 Writer.AddSourceLocation(D->getLocEnd(), Record);
344 Code = pch::DECL_OBJC_CATEGORY;
345}
346
347void PCHDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
348 VisitNamedDecl(D);
349 Writer.AddDeclRef(D->getClassInterface(), Record);
350 Code = pch::DECL_OBJC_COMPATIBLE_ALIAS;
351}
352
353void PCHDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
354 VisitNamedDecl(D);
355 Writer.AddTypeRef(D->getType(), Record);
356 // FIXME: stable encoding
357 Record.push_back((unsigned)D->getPropertyAttributes());
358 // FIXME: stable encoding
359 Record.push_back((unsigned)D->getPropertyImplementation());
360 Writer.AddDeclarationName(D->getGetterName(), Record);
361 Writer.AddDeclarationName(D->getSetterName(), Record);
362 Writer.AddDeclRef(D->getGetterMethodDecl(), Record);
363 Writer.AddDeclRef(D->getSetterMethodDecl(), Record);
364 Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
365 Code = pch::DECL_OBJC_PROPERTY;
366}
367
368void PCHDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
Argyrios Kyrtzidisaecae622009-07-27 19:04:32 +0000369 VisitObjCContainerDecl(D);
Chris Lattner12b1c762009-04-27 06:16:06 +0000370 Writer.AddDeclRef(D->getClassInterface(), Record);
Chris Lattner12b1c762009-04-27 06:16:06 +0000371 // Abstract class (no need to define a stable pch::DECL code).
372}
373
374void PCHDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
375 VisitObjCImplDecl(D);
376 Writer.AddIdentifierRef(D->getIdentifier(), Record);
377 Code = pch::DECL_OBJC_CATEGORY_IMPL;
378}
379
380void PCHDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
381 VisitObjCImplDecl(D);
382 Writer.AddDeclRef(D->getSuperClass(), Record);
383 Code = pch::DECL_OBJC_IMPLEMENTATION;
384}
385
386void PCHDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
387 VisitDecl(D);
388 Writer.AddSourceLocation(D->getLocStart(), Record);
389 Writer.AddDeclRef(D->getPropertyDecl(), Record);
390 Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
391 Code = pch::DECL_OBJC_PROPERTY_IMPL;
392}
393
394void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) {
Argyrios Kyrtzidisd4a7e542009-08-19 01:28:35 +0000395 VisitDeclaratorDecl(D);
Chris Lattner12b1c762009-04-27 06:16:06 +0000396 Record.push_back(D->isMutable());
397 Record.push_back(D->getBitWidth()? 1 : 0);
398 if (D->getBitWidth())
399 Writer.AddStmt(D->getBitWidth());
400 Code = pch::DECL_FIELD;
401}
402
403void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
Argyrios Kyrtzidisd4a7e542009-08-19 01:28:35 +0000404 VisitDeclaratorDecl(D);
Chris Lattner12b1c762009-04-27 06:16:06 +0000405 Record.push_back(D->getStorageClass()); // FIXME: stable encoding
406 Record.push_back(D->isThreadSpecified());
407 Record.push_back(D->hasCXXDirectInitializer());
408 Record.push_back(D->isDeclaredInCondition());
409 Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Chris Lattner12b1c762009-04-27 06:16:06 +0000410 Record.push_back(D->getInit()? 1 : 0);
411 if (D->getInit())
412 Writer.AddStmt(D->getInit());
413 Code = pch::DECL_VAR;
414}
415
416void PCHDeclWriter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
417 VisitVarDecl(D);
418 Code = pch::DECL_IMPLICIT_PARAM;
419}
420
421void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
422 VisitVarDecl(D);
423 Record.push_back(D->getObjCDeclQualifier()); // FIXME: stable encoding
Chris Lattner12b1c762009-04-27 06:16:06 +0000424 Code = pch::DECL_PARM_VAR;
Chris Lattnerea5ce472009-04-27 07:35:58 +0000425
426
427 // If the assumptions about the DECL_PARM_VAR abbrev are true, use it. Here
428 // we dynamically check for the properties that we optimize for, but don't
429 // know are true of all PARM_VAR_DECLs.
Argyrios Kyrtzidisd4a7e542009-08-19 01:28:35 +0000430 if (!D->getDeclaratorInfo() &&
431 !D->hasAttrs() &&
Chris Lattnerea5ce472009-04-27 07:35:58 +0000432 !D->isImplicit() &&
Douglas Gregore0762c92009-06-19 23:52:42 +0000433 !D->isUsed() &&
Chris Lattnerea5ce472009-04-27 07:35:58 +0000434 D->getAccess() == AS_none &&
435 D->getStorageClass() == 0 &&
436 !D->hasCXXDirectInitializer() && // Can params have this ever?
437 D->getObjCDeclQualifier() == 0)
438 AbbrevToUse = Writer.getParmVarDeclAbbrev();
439
440 // Check things we know are true of *every* PARM_VAR_DECL, which is more than
441 // just us assuming it.
442 assert(!D->isInvalidDecl() && "Shouldn't emit invalid decls");
443 assert(!D->isThreadSpecified() && "PARM_VAR_DECL can't be __thread");
444 assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
445 assert(!D->isDeclaredInCondition() && "PARM_VAR_DECL can't be in condition");
446 assert(D->getPreviousDeclaration() == 0 && "PARM_VAR_DECL can't be redecl");
447 assert(D->getInit() == 0 && "PARM_VAR_DECL never has init");
Chris Lattner12b1c762009-04-27 06:16:06 +0000448}
449
450void PCHDeclWriter::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
451 VisitParmVarDecl(D);
452 Writer.AddTypeRef(D->getOriginalType(), Record);
453 Code = pch::DECL_ORIGINAL_PARM_VAR;
Chris Lattnerea5ce472009-04-27 07:35:58 +0000454 AbbrevToUse = 0;
Chris Lattner12b1c762009-04-27 06:16:06 +0000455}
456
457void PCHDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
458 VisitDecl(D);
459 Writer.AddStmt(D->getAsmString());
460 Code = pch::DECL_FILE_SCOPE_ASM;
461}
462
463void PCHDeclWriter::VisitBlockDecl(BlockDecl *D) {
464 VisitDecl(D);
465 Writer.AddStmt(D->getBody());
466 Record.push_back(D->param_size());
467 for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
468 P != PEnd; ++P)
469 Writer.AddDeclRef(*P, Record);
470 Code = pch::DECL_BLOCK;
471}
472
473/// \brief Emit the DeclContext part of a declaration context decl.
474///
475/// \param LexicalOffset the offset at which the DECL_CONTEXT_LEXICAL
476/// block for this declaration context is stored. May be 0 to indicate
477/// that there are no declarations stored within this context.
478///
479/// \param VisibleOffset the offset at which the DECL_CONTEXT_VISIBLE
480/// block for this declaration context is stored. May be 0 to indicate
481/// that there are no declarations visible from this context. Note
482/// that this value will not be emitted for non-primary declaration
483/// contexts.
484void PCHDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
485 uint64_t VisibleOffset) {
486 Record.push_back(LexicalOffset);
487 Record.push_back(VisibleOffset);
488}
489
490
491//===----------------------------------------------------------------------===//
492// PCHWriter Implementation
493//===----------------------------------------------------------------------===//
494
Chris Lattnerea5ce472009-04-27 07:35:58 +0000495void PCHWriter::WriteDeclsBlockAbbrevs() {
496 using namespace llvm;
497 // Abbreviation for DECL_PARM_VAR.
498 BitCodeAbbrev *Abv = new BitCodeAbbrev();
499 Abv->Add(BitCodeAbbrevOp(pch::DECL_PARM_VAR));
500
501 // Decl
502 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
503 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
504 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
505 Abv->Add(BitCodeAbbrevOp(0)); // isInvalidDecl (!?)
506 Abv->Add(BitCodeAbbrevOp(0)); // HasAttrs
507 Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
Douglas Gregore0762c92009-06-19 23:52:42 +0000508 Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Chris Lattnerea5ce472009-04-27 07:35:58 +0000509 Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
510
511 // NamedDecl
512 Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
513 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name
514 // ValueDecl
515 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Argyrios Kyrtzidisd4a7e542009-08-19 01:28:35 +0000516 // DeclaratorDecl
517 Abv->Add(BitCodeAbbrevOp(pch::PREDEF_TYPE_NULL_ID)); // InfoType
Chris Lattnerea5ce472009-04-27 07:35:58 +0000518 // VarDecl
519 Abv->Add(BitCodeAbbrevOp(0)); // StorageClass
520 Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified
521 Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer
522 Abv->Add(BitCodeAbbrevOp(0)); // isDeclaredInCondition
523 Abv->Add(BitCodeAbbrevOp(0)); // PrevDecl
Chris Lattnerea5ce472009-04-27 07:35:58 +0000524 Abv->Add(BitCodeAbbrevOp(0)); // HasInit
525 // ParmVarDecl
526 Abv->Add(BitCodeAbbrevOp(0)); // ObjCDeclQualifier
527
528 ParmVarDeclAbbrev = Stream.EmitAbbrev(Abv);
529}
530
Chris Lattner12b1c762009-04-27 06:16:06 +0000531/// \brief Write a block containing all of the declarations.
532void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
533 // Enter the declarations block.
Chris Lattnerea5ce472009-04-27 07:35:58 +0000534 Stream.EnterSubblock(pch::DECLS_BLOCK_ID, 3);
Chris Lattner12b1c762009-04-27 06:16:06 +0000535
Chris Lattnerea5ce472009-04-27 07:35:58 +0000536 // Output the abbreviations that we will use in this block.
537 WriteDeclsBlockAbbrevs();
538
Chris Lattner12b1c762009-04-27 06:16:06 +0000539 // Emit all of the declarations.
540 RecordData Record;
541 PCHDeclWriter W(*this, Context, Record);
542 while (!DeclsToEmit.empty()) {
543 // Pull the next declaration off the queue
544 Decl *D = DeclsToEmit.front();
545 DeclsToEmit.pop();
546
547 // If this declaration is also a DeclContext, write blocks for the
548 // declarations that lexically stored inside its context and those
549 // declarations that are visible from its context. These blocks
550 // are written before the declaration itself so that we can put
551 // their offsets into the record for the declaration.
552 uint64_t LexicalOffset = 0;
553 uint64_t VisibleOffset = 0;
554 DeclContext *DC = dyn_cast<DeclContext>(D);
555 if (DC) {
556 LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
557 VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
558 }
559
560 // Determine the ID for this declaration
Zhongxing Xu44dfc982009-06-01 00:50:23 +0000561 pch::DeclID &ID = DeclIDs[D];
Chris Lattner12b1c762009-04-27 06:16:06 +0000562 if (ID == 0)
563 ID = DeclIDs.size();
564
565 unsigned Index = ID - 1;
566
567 // Record the offset for this declaration
568 if (DeclOffsets.size() == Index)
569 DeclOffsets.push_back(Stream.GetCurrentBitNo());
570 else if (DeclOffsets.size() < Index) {
571 DeclOffsets.resize(Index+1);
572 DeclOffsets[Index] = Stream.GetCurrentBitNo();
573 }
574
575 // Build and emit a record for this declaration
576 Record.clear();
577 W.Code = (pch::DeclCode)0;
Chris Lattnerea5ce472009-04-27 07:35:58 +0000578 W.AbbrevToUse = 0;
Chris Lattner12b1c762009-04-27 06:16:06 +0000579 W.Visit(D);
580 if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
581
582 if (!W.Code) {
583 fprintf(stderr, "Cannot serialize declaration of kind %s\n",
584 D->getDeclKindName());
585 assert(false && "Unhandled declaration kind while generating PCH");
586 exit(-1);
587 }
Chris Lattnerea5ce472009-04-27 07:35:58 +0000588 Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
589
Chris Lattner12b1c762009-04-27 06:16:06 +0000590 // If the declaration had any attributes, write them now.
591 if (D->hasAttrs())
Argyrios Kyrtzidis40b598e2009-06-30 02:34:44 +0000592 WriteAttributeRecord(D->getAttrs());
Chris Lattner12b1c762009-04-27 06:16:06 +0000593
594 // Flush any expressions that were written as part of this declaration.
595 FlushStmts();
596
597 // Note external declarations so that we can add them to a record
598 // in the PCH file later.
599 if (isa<FileScopeAsmDecl>(D))
600 ExternalDefinitions.push_back(ID);
601 }
602
603 // Exit the declarations block
604 Stream.ExitBlock();
605}