blob: 0dcdf8d3fd8df3e6452c9b589d5551e2ca6066e9 [file] [log] [blame]
Douglas Gregorc34897d2009-04-09 22:27:44 +00001//===--- PCHReader.cpp - Precompiled Headers Reader -------------*- 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 PCHReader class, which reads a precompiled header.
11//
12//===----------------------------------------------------------------------===//
13#include "clang/Frontend/PCHReader.h"
Douglas Gregor179cfb12009-04-10 20:39:37 +000014#include "clang/Frontend/FrontendDiagnostic.h"
Douglas Gregor631f6c62009-04-14 00:24:19 +000015#include "clang/AST/ASTConsumer.h"
Douglas Gregorc34897d2009-04-09 22:27:44 +000016#include "clang/AST/ASTContext.h"
17#include "clang/AST/Decl.h"
Douglas Gregor631f6c62009-04-14 00:24:19 +000018#include "clang/AST/DeclGroup.h"
Douglas Gregorddf4d092009-04-16 22:29:51 +000019#include "clang/AST/DeclVisitor.h"
Douglas Gregorc10f86f2009-04-14 21:18:50 +000020#include "clang/AST/Expr.h"
21#include "clang/AST/StmtVisitor.h"
Douglas Gregorc34897d2009-04-09 22:27:44 +000022#include "clang/AST/Type.h"
Chris Lattnerdb1c81b2009-04-10 21:41:48 +000023#include "clang/Lex/MacroInfo.h"
Douglas Gregorab1cef72009-04-10 03:52:48 +000024#include "clang/Lex/Preprocessor.h"
25#include "clang/Basic/SourceManager.h"
Douglas Gregor635f97f2009-04-13 16:31:14 +000026#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregorab1cef72009-04-10 03:52:48 +000027#include "clang/Basic/FileManager.h"
Douglas Gregorb5887f32009-04-10 21:16:55 +000028#include "clang/Basic/TargetInfo.h"
Douglas Gregorc34897d2009-04-09 22:27:44 +000029#include "llvm/Bitcode/BitstreamReader.h"
30#include "llvm/Support/Compiler.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include <algorithm>
33#include <cstdio>
34
35using namespace clang;
36
37//===----------------------------------------------------------------------===//
38// Declaration deserialization
39//===----------------------------------------------------------------------===//
40namespace {
Douglas Gregorddf4d092009-04-16 22:29:51 +000041 class VISIBILITY_HIDDEN PCHDeclReader
42 : public DeclVisitor<PCHDeclReader, void> {
Douglas Gregorc34897d2009-04-09 22:27:44 +000043 PCHReader &Reader;
44 const PCHReader::RecordData &Record;
45 unsigned &Idx;
46
47 public:
48 PCHDeclReader(PCHReader &Reader, const PCHReader::RecordData &Record,
49 unsigned &Idx)
50 : Reader(Reader), Record(Record), Idx(Idx) { }
51
52 void VisitDecl(Decl *D);
53 void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
54 void VisitNamedDecl(NamedDecl *ND);
55 void VisitTypeDecl(TypeDecl *TD);
56 void VisitTypedefDecl(TypedefDecl *TD);
Douglas Gregor47f1b2c2009-04-13 18:14:40 +000057 void VisitTagDecl(TagDecl *TD);
58 void VisitEnumDecl(EnumDecl *ED);
Douglas Gregor982365e2009-04-13 21:20:57 +000059 void VisitRecordDecl(RecordDecl *RD);
Douglas Gregorc34897d2009-04-09 22:27:44 +000060 void VisitValueDecl(ValueDecl *VD);
Douglas Gregor47f1b2c2009-04-13 18:14:40 +000061 void VisitEnumConstantDecl(EnumConstantDecl *ECD);
Douglas Gregor23ce3a52009-04-13 22:18:37 +000062 void VisitFunctionDecl(FunctionDecl *FD);
Douglas Gregor982365e2009-04-13 21:20:57 +000063 void VisitFieldDecl(FieldDecl *FD);
Douglas Gregorc34897d2009-04-09 22:27:44 +000064 void VisitVarDecl(VarDecl *VD);
Douglas Gregor23ce3a52009-04-13 22:18:37 +000065 void VisitParmVarDecl(ParmVarDecl *PD);
66 void VisitOriginalParmVarDecl(OriginalParmVarDecl *PD);
Douglas Gregor2a491792009-04-13 22:49:25 +000067 void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
68 void VisitBlockDecl(BlockDecl *BD);
Douglas Gregorc34897d2009-04-09 22:27:44 +000069 std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
70 };
71}
72
73void PCHDeclReader::VisitDecl(Decl *D) {
74 D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
75 D->setLexicalDeclContext(
76 cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
77 D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
78 D->setInvalidDecl(Record[Idx++]);
Douglas Gregor1c507882009-04-15 21:30:51 +000079 if (Record[Idx++])
80 D->addAttr(Reader.ReadAttributes());
Douglas Gregorc34897d2009-04-09 22:27:44 +000081 D->setImplicit(Record[Idx++]);
82 D->setAccess((AccessSpecifier)Record[Idx++]);
83}
84
85void PCHDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
86 VisitDecl(TU);
87}
88
89void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
90 VisitDecl(ND);
91 ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
92}
93
94void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
95 VisitNamedDecl(TD);
Douglas Gregorc34897d2009-04-09 22:27:44 +000096 TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
97}
98
99void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
Douglas Gregor88fd09d2009-04-13 20:46:52 +0000100 // Note that we cannot use VisitTypeDecl here, because we need to
101 // set the underlying type of the typedef *before* we try to read
102 // the type associated with the TypedefDecl.
103 VisitNamedDecl(TD);
104 TD->setUnderlyingType(Reader.GetType(Record[Idx + 1]));
105 TD->setTypeForDecl(Reader.GetType(Record[Idx]).getTypePtr());
106 Idx += 2;
Douglas Gregorc34897d2009-04-09 22:27:44 +0000107}
108
Douglas Gregor47f1b2c2009-04-13 18:14:40 +0000109void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
110 VisitTypeDecl(TD);
111 TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
112 TD->setDefinition(Record[Idx++]);
113 TD->setTypedefForAnonDecl(
114 cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
115}
116
117void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
118 VisitTagDecl(ED);
119 ED->setIntegerType(Reader.GetType(Record[Idx++]));
120}
121
Douglas Gregor982365e2009-04-13 21:20:57 +0000122void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) {
123 VisitTagDecl(RD);
124 RD->setHasFlexibleArrayMember(Record[Idx++]);
125 RD->setAnonymousStructOrUnion(Record[Idx++]);
126}
127
Douglas Gregorc34897d2009-04-09 22:27:44 +0000128void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {
129 VisitNamedDecl(VD);
130 VD->setType(Reader.GetType(Record[Idx++]));
131}
132
Douglas Gregor47f1b2c2009-04-13 18:14:40 +0000133void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {
134 VisitValueDecl(ECD);
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000135 if (Record[Idx++])
136 ECD->setInitExpr(Reader.ReadExpr());
Douglas Gregor47f1b2c2009-04-13 18:14:40 +0000137 ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));
138}
139
Douglas Gregor23ce3a52009-04-13 22:18:37 +0000140void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
141 VisitValueDecl(FD);
Douglas Gregor9c4782a2009-04-17 00:04:06 +0000142 if (Record[Idx++])
143 FD->setBody(cast<CompoundStmt>(Reader.ReadStmt()));
Douglas Gregor23ce3a52009-04-13 22:18:37 +0000144 FD->setPreviousDeclaration(
145 cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
146 FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
147 FD->setInline(Record[Idx++]);
148 FD->setVirtual(Record[Idx++]);
149 FD->setPure(Record[Idx++]);
150 FD->setInheritedPrototype(Record[Idx++]);
151 FD->setHasPrototype(Record[Idx++]);
152 FD->setDeleted(Record[Idx++]);
153 FD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
154 unsigned NumParams = Record[Idx++];
155 llvm::SmallVector<ParmVarDecl *, 16> Params;
156 Params.reserve(NumParams);
157 for (unsigned I = 0; I != NumParams; ++I)
158 Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
159 FD->setParams(Reader.getContext(), &Params[0], NumParams);
160}
161
Douglas Gregor982365e2009-04-13 21:20:57 +0000162void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
163 VisitValueDecl(FD);
164 FD->setMutable(Record[Idx++]);
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000165 if (Record[Idx++])
166 FD->setBitWidth(Reader.ReadExpr());
Douglas Gregor982365e2009-04-13 21:20:57 +0000167}
168
Douglas Gregorc34897d2009-04-09 22:27:44 +0000169void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
170 VisitValueDecl(VD);
171 VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
172 VD->setThreadSpecified(Record[Idx++]);
173 VD->setCXXDirectInitializer(Record[Idx++]);
174 VD->setDeclaredInCondition(Record[Idx++]);
175 VD->setPreviousDeclaration(
176 cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
177 VD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000178 if (Record[Idx++])
179 VD->setInit(Reader.ReadExpr());
Douglas Gregorc34897d2009-04-09 22:27:44 +0000180}
181
Douglas Gregor23ce3a52009-04-13 22:18:37 +0000182void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {
183 VisitVarDecl(PD);
184 PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
Douglas Gregor21ddd8c2009-04-15 22:19:53 +0000185 // FIXME: default argument (C++ only)
Douglas Gregor23ce3a52009-04-13 22:18:37 +0000186}
187
188void PCHDeclReader::VisitOriginalParmVarDecl(OriginalParmVarDecl *PD) {
189 VisitParmVarDecl(PD);
190 PD->setOriginalType(Reader.GetType(Record[Idx++]));
191}
192
Douglas Gregor2a491792009-04-13 22:49:25 +0000193void PCHDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {
194 VisitDecl(AD);
Douglas Gregor3c8ff3e2009-04-15 18:43:11 +0000195 AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr()));
Douglas Gregor2a491792009-04-13 22:49:25 +0000196}
197
198void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {
199 VisitDecl(BD);
200 unsigned NumParams = Record[Idx++];
201 llvm::SmallVector<ParmVarDecl *, 16> Params;
202 Params.reserve(NumParams);
203 for (unsigned I = 0; I != NumParams; ++I)
204 Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
205 BD->setParams(Reader.getContext(), &Params[0], NumParams);
206}
207
Douglas Gregorc34897d2009-04-09 22:27:44 +0000208std::pair<uint64_t, uint64_t>
209PCHDeclReader::VisitDeclContext(DeclContext *DC) {
210 uint64_t LexicalOffset = Record[Idx++];
211 uint64_t VisibleOffset = 0;
212 if (DC->getPrimaryContext() == DC)
213 VisibleOffset = Record[Idx++];
214 return std::make_pair(LexicalOffset, VisibleOffset);
215}
216
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000217//===----------------------------------------------------------------------===//
218// Statement/expression deserialization
219//===----------------------------------------------------------------------===//
220namespace {
221 class VISIBILITY_HIDDEN PCHStmtReader
Douglas Gregora151ba42009-04-14 23:32:43 +0000222 : public StmtVisitor<PCHStmtReader, unsigned> {
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000223 PCHReader &Reader;
224 const PCHReader::RecordData &Record;
225 unsigned &Idx;
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000226 llvm::SmallVectorImpl<Stmt *> &StmtStack;
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000227
228 public:
229 PCHStmtReader(PCHReader &Reader, const PCHReader::RecordData &Record,
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000230 unsigned &Idx, llvm::SmallVectorImpl<Stmt *> &StmtStack)
231 : Reader(Reader), Record(Record), Idx(Idx), StmtStack(StmtStack) { }
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000232
Douglas Gregor9c4782a2009-04-17 00:04:06 +0000233 /// \brief The number of record fields required for the Stmt class
234 /// itself.
235 static const unsigned NumStmtFields = 0;
236
Douglas Gregor596e0932009-04-15 16:35:07 +0000237 /// \brief The number of record fields required for the Expr class
238 /// itself.
Douglas Gregor9c4782a2009-04-17 00:04:06 +0000239 static const unsigned NumExprFields = NumStmtFields + 3;
Douglas Gregor596e0932009-04-15 16:35:07 +0000240
Douglas Gregora151ba42009-04-14 23:32:43 +0000241 // Each of the Visit* functions reads in part of the expression
242 // from the given record and the current expression stack, then
243 // return the total number of operands that it read from the
244 // expression stack.
245
Douglas Gregor9c4782a2009-04-17 00:04:06 +0000246 unsigned VisitStmt(Stmt *S);
247 unsigned VisitNullStmt(NullStmt *S);
248 unsigned VisitCompoundStmt(CompoundStmt *S);
249 unsigned VisitSwitchCase(SwitchCase *S);
250 unsigned VisitCaseStmt(CaseStmt *S);
251 unsigned VisitDefaultStmt(DefaultStmt *S);
252 unsigned VisitIfStmt(IfStmt *S);
253 unsigned VisitSwitchStmt(SwitchStmt *S);
Douglas Gregora6b503f2009-04-17 00:16:09 +0000254 unsigned VisitWhileStmt(WhileStmt *S);
Douglas Gregorfb5f25b2009-04-17 00:29:51 +0000255 unsigned VisitDoStmt(DoStmt *S);
256 unsigned VisitForStmt(ForStmt *S);
Douglas Gregora6b503f2009-04-17 00:16:09 +0000257 unsigned VisitContinueStmt(ContinueStmt *S);
Douglas Gregor9c4782a2009-04-17 00:04:06 +0000258 unsigned VisitBreakStmt(BreakStmt *S);
Douglas Gregor22d2dcd2009-04-17 16:34:57 +0000259 unsigned VisitReturnStmt(ReturnStmt *S);
Douglas Gregora151ba42009-04-14 23:32:43 +0000260 unsigned VisitExpr(Expr *E);
261 unsigned VisitPredefinedExpr(PredefinedExpr *E);
262 unsigned VisitDeclRefExpr(DeclRefExpr *E);
263 unsigned VisitIntegerLiteral(IntegerLiteral *E);
264 unsigned VisitFloatingLiteral(FloatingLiteral *E);
Douglas Gregor21ddd8c2009-04-15 22:19:53 +0000265 unsigned VisitImaginaryLiteral(ImaginaryLiteral *E);
Douglas Gregor596e0932009-04-15 16:35:07 +0000266 unsigned VisitStringLiteral(StringLiteral *E);
Douglas Gregora151ba42009-04-14 23:32:43 +0000267 unsigned VisitCharacterLiteral(CharacterLiteral *E);
Douglas Gregor4ea0b1f2009-04-14 23:59:37 +0000268 unsigned VisitParenExpr(ParenExpr *E);
Douglas Gregor12d74052009-04-15 15:58:59 +0000269 unsigned VisitUnaryOperator(UnaryOperator *E);
270 unsigned VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
Douglas Gregor21ddd8c2009-04-15 22:19:53 +0000271 unsigned VisitArraySubscriptExpr(ArraySubscriptExpr *E);
Douglas Gregor7e2b1cd2009-04-15 17:43:59 +0000272 unsigned VisitCallExpr(CallExpr *E);
273 unsigned VisitMemberExpr(MemberExpr *E);
Douglas Gregora151ba42009-04-14 23:32:43 +0000274 unsigned VisitCastExpr(CastExpr *E);
Douglas Gregorc75d0cb2009-04-15 00:25:59 +0000275 unsigned VisitBinaryOperator(BinaryOperator *E);
Douglas Gregorc599bbf2009-04-15 22:40:36 +0000276 unsigned VisitCompoundAssignOperator(CompoundAssignOperator *E);
277 unsigned VisitConditionalOperator(ConditionalOperator *E);
Douglas Gregora151ba42009-04-14 23:32:43 +0000278 unsigned VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregorc75d0cb2009-04-15 00:25:59 +0000279 unsigned VisitExplicitCastExpr(ExplicitCastExpr *E);
280 unsigned VisitCStyleCastExpr(CStyleCastExpr *E);
Douglas Gregorb70b48f2009-04-16 02:33:48 +0000281 unsigned VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
Douglas Gregorec0b8292009-04-15 23:02:49 +0000282 unsigned VisitExtVectorElementExpr(ExtVectorElementExpr *E);
Douglas Gregor6710a3c2009-04-16 00:55:48 +0000283 unsigned VisitInitListExpr(InitListExpr *E);
284 unsigned VisitDesignatedInitExpr(DesignatedInitExpr *E);
285 unsigned VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
Douglas Gregorec0b8292009-04-15 23:02:49 +0000286 unsigned VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor209d4622009-04-15 23:33:31 +0000287 unsigned VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
288 unsigned VisitChooseExpr(ChooseExpr *E);
289 unsigned VisitGNUNullExpr(GNUNullExpr *E);
Douglas Gregor725e94b2009-04-16 00:01:45 +0000290 unsigned VisitShuffleVectorExpr(ShuffleVectorExpr *E);
291 unsigned VisitBlockDeclRefExpr(BlockDeclRefExpr *E);
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000292 };
293}
294
Douglas Gregor9c4782a2009-04-17 00:04:06 +0000295unsigned PCHStmtReader::VisitStmt(Stmt *S) {
296 assert(Idx == NumStmtFields && "Incorrect statement field count");
297 return 0;
298}
299
300unsigned PCHStmtReader::VisitNullStmt(NullStmt *S) {
301 VisitStmt(S);
302 S->setSemiLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
303 return 0;
304}
305
306unsigned PCHStmtReader::VisitCompoundStmt(CompoundStmt *S) {
307 VisitStmt(S);
308 unsigned NumStmts = Record[Idx++];
309 S->setStmts(Reader.getContext(),
310 &StmtStack[StmtStack.size() - NumStmts], NumStmts);
311 S->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
312 S->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
313 return NumStmts;
314}
315
316unsigned PCHStmtReader::VisitSwitchCase(SwitchCase *S) {
317 VisitStmt(S);
318 Reader.RecordSwitchCaseID(S, Record[Idx++]);
319 return 0;
320}
321
322unsigned PCHStmtReader::VisitCaseStmt(CaseStmt *S) {
323 VisitSwitchCase(S);
324 S->setLHS(cast<Expr>(StmtStack[StmtStack.size() - 3]));
325 S->setRHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
326 S->setSubStmt(StmtStack.back());
327 S->setCaseLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
328 return 3;
329}
330
331unsigned PCHStmtReader::VisitDefaultStmt(DefaultStmt *S) {
332 VisitSwitchCase(S);
333 S->setSubStmt(StmtStack.back());
334 S->setDefaultLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
335 return 1;
336}
337
338unsigned PCHStmtReader::VisitIfStmt(IfStmt *S) {
339 VisitStmt(S);
340 S->setCond(cast<Expr>(StmtStack[StmtStack.size() - 3]));
341 S->setThen(StmtStack[StmtStack.size() - 2]);
342 S->setElse(StmtStack[StmtStack.size() - 1]);
343 S->setIfLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
344 return 3;
345}
346
347unsigned PCHStmtReader::VisitSwitchStmt(SwitchStmt *S) {
348 VisitStmt(S);
349 S->setCond(cast<Expr>(StmtStack[StmtStack.size() - 2]));
350 S->setBody(StmtStack.back());
351 S->setSwitchLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
352 SwitchCase *PrevSC = 0;
353 for (unsigned N = Record.size(); Idx != N; ++Idx) {
354 SwitchCase *SC = Reader.getSwitchCaseWithID(Record[Idx]);
355 if (PrevSC)
356 PrevSC->setNextSwitchCase(SC);
357 else
358 S->setSwitchCaseList(SC);
359 PrevSC = SC;
360 }
361 return 2;
362}
363
Douglas Gregora6b503f2009-04-17 00:16:09 +0000364unsigned PCHStmtReader::VisitWhileStmt(WhileStmt *S) {
365 VisitStmt(S);
366 S->setCond(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
367 S->setBody(StmtStack.back());
368 S->setWhileLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
369 return 2;
370}
371
Douglas Gregorfb5f25b2009-04-17 00:29:51 +0000372unsigned PCHStmtReader::VisitDoStmt(DoStmt *S) {
373 VisitStmt(S);
374 S->setCond(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
375 S->setBody(StmtStack.back());
376 S->setDoLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
377 return 2;
378}
379
380unsigned PCHStmtReader::VisitForStmt(ForStmt *S) {
381 VisitStmt(S);
382 S->setInit(StmtStack[StmtStack.size() - 4]);
383 S->setCond(cast_or_null<Expr>(StmtStack[StmtStack.size() - 3]));
384 S->setInc(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
385 S->setBody(StmtStack.back());
386 S->setForLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
387 return 4;
388}
389
Douglas Gregora6b503f2009-04-17 00:16:09 +0000390unsigned PCHStmtReader::VisitContinueStmt(ContinueStmt *S) {
391 VisitStmt(S);
392 S->setContinueLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
393 return 0;
394}
395
Douglas Gregor9c4782a2009-04-17 00:04:06 +0000396unsigned PCHStmtReader::VisitBreakStmt(BreakStmt *S) {
397 VisitStmt(S);
398 S->setBreakLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
399 return 0;
400}
401
Douglas Gregor22d2dcd2009-04-17 16:34:57 +0000402unsigned PCHStmtReader::VisitReturnStmt(ReturnStmt *S) {
403 VisitStmt(S);
404 S->setRetValue(cast_or_null<Expr>(StmtStack.back()));
405 S->setReturnLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
406 return 1;
407}
408
Douglas Gregora151ba42009-04-14 23:32:43 +0000409unsigned PCHStmtReader::VisitExpr(Expr *E) {
Douglas Gregor9c4782a2009-04-17 00:04:06 +0000410 VisitStmt(E);
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000411 E->setType(Reader.GetType(Record[Idx++]));
412 E->setTypeDependent(Record[Idx++]);
413 E->setValueDependent(Record[Idx++]);
Douglas Gregor596e0932009-04-15 16:35:07 +0000414 assert(Idx == NumExprFields && "Incorrect expression field count");
Douglas Gregora151ba42009-04-14 23:32:43 +0000415 return 0;
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000416}
417
Douglas Gregora151ba42009-04-14 23:32:43 +0000418unsigned PCHStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
Douglas Gregore2f37202009-04-14 21:55:33 +0000419 VisitExpr(E);
420 E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
421 E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]);
Douglas Gregora151ba42009-04-14 23:32:43 +0000422 return 0;
Douglas Gregore2f37202009-04-14 21:55:33 +0000423}
424
Douglas Gregora151ba42009-04-14 23:32:43 +0000425unsigned PCHStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000426 VisitExpr(E);
427 E->setDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
428 E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
Douglas Gregora151ba42009-04-14 23:32:43 +0000429 return 0;
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000430}
431
Douglas Gregora151ba42009-04-14 23:32:43 +0000432unsigned PCHStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000433 VisitExpr(E);
434 E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
435 E->setValue(Reader.ReadAPInt(Record, Idx));
Douglas Gregora151ba42009-04-14 23:32:43 +0000436 return 0;
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000437}
438
Douglas Gregora151ba42009-04-14 23:32:43 +0000439unsigned PCHStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
Douglas Gregore2f37202009-04-14 21:55:33 +0000440 VisitExpr(E);
441 E->setValue(Reader.ReadAPFloat(Record, Idx));
442 E->setExact(Record[Idx++]);
443 E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
Douglas Gregora151ba42009-04-14 23:32:43 +0000444 return 0;
Douglas Gregore2f37202009-04-14 21:55:33 +0000445}
446
Douglas Gregor21ddd8c2009-04-15 22:19:53 +0000447unsigned PCHStmtReader::VisitImaginaryLiteral(ImaginaryLiteral *E) {
448 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000449 E->setSubExpr(cast<Expr>(StmtStack.back()));
Douglas Gregor21ddd8c2009-04-15 22:19:53 +0000450 return 1;
451}
452
Douglas Gregor596e0932009-04-15 16:35:07 +0000453unsigned PCHStmtReader::VisitStringLiteral(StringLiteral *E) {
454 VisitExpr(E);
455 unsigned Len = Record[Idx++];
456 assert(Record[Idx] == E->getNumConcatenated() &&
457 "Wrong number of concatenated tokens!");
458 ++Idx;
459 E->setWide(Record[Idx++]);
460
461 // Read string data
462 llvm::SmallVector<char, 16> Str(&Record[Idx], &Record[Idx] + Len);
463 E->setStrData(Reader.getContext(), &Str[0], Len);
464 Idx += Len;
465
466 // Read source locations
467 for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
468 E->setStrTokenLoc(I, SourceLocation::getFromRawEncoding(Record[Idx++]));
469
470 return 0;
471}
472
Douglas Gregora151ba42009-04-14 23:32:43 +0000473unsigned PCHStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000474 VisitExpr(E);
475 E->setValue(Record[Idx++]);
476 E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
477 E->setWide(Record[Idx++]);
Douglas Gregora151ba42009-04-14 23:32:43 +0000478 return 0;
479}
480
Douglas Gregor4ea0b1f2009-04-14 23:59:37 +0000481unsigned PCHStmtReader::VisitParenExpr(ParenExpr *E) {
482 VisitExpr(E);
483 E->setLParen(SourceLocation::getFromRawEncoding(Record[Idx++]));
484 E->setRParen(SourceLocation::getFromRawEncoding(Record[Idx++]));
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000485 E->setSubExpr(cast<Expr>(StmtStack.back()));
Douglas Gregor4ea0b1f2009-04-14 23:59:37 +0000486 return 1;
487}
488
Douglas Gregor12d74052009-04-15 15:58:59 +0000489unsigned PCHStmtReader::VisitUnaryOperator(UnaryOperator *E) {
490 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000491 E->setSubExpr(cast<Expr>(StmtStack.back()));
Douglas Gregor12d74052009-04-15 15:58:59 +0000492 E->setOpcode((UnaryOperator::Opcode)Record[Idx++]);
493 E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
494 return 1;
495}
496
497unsigned PCHStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
498 VisitExpr(E);
499 E->setSizeof(Record[Idx++]);
500 if (Record[Idx] == 0) {
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000501 E->setArgument(cast<Expr>(StmtStack.back()));
Douglas Gregor12d74052009-04-15 15:58:59 +0000502 ++Idx;
503 } else {
504 E->setArgument(Reader.GetType(Record[Idx++]));
505 }
506 E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
507 E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
508 return E->isArgumentType()? 0 : 1;
509}
510
Douglas Gregor21ddd8c2009-04-15 22:19:53 +0000511unsigned PCHStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
512 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000513 E->setLHS(cast<Expr>(StmtStack[StmtStack.size() - 2]));
514 E->setRHS(cast<Expr>(StmtStack[StmtStack.size() - 2]));
Douglas Gregor21ddd8c2009-04-15 22:19:53 +0000515 E->setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
516 return 2;
517}
518
Douglas Gregor7e2b1cd2009-04-15 17:43:59 +0000519unsigned PCHStmtReader::VisitCallExpr(CallExpr *E) {
520 VisitExpr(E);
521 E->setNumArgs(Reader.getContext(), Record[Idx++]);
522 E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000523 E->setCallee(cast<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
Douglas Gregor7e2b1cd2009-04-15 17:43:59 +0000524 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000525 E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
Douglas Gregor7e2b1cd2009-04-15 17:43:59 +0000526 return E->getNumArgs() + 1;
527}
528
529unsigned PCHStmtReader::VisitMemberExpr(MemberExpr *E) {
530 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000531 E->setBase(cast<Expr>(StmtStack.back()));
Douglas Gregor7e2b1cd2009-04-15 17:43:59 +0000532 E->setMemberDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));
533 E->setMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
534 E->setArrow(Record[Idx++]);
535 return 1;
536}
537
Douglas Gregora151ba42009-04-14 23:32:43 +0000538unsigned PCHStmtReader::VisitCastExpr(CastExpr *E) {
539 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000540 E->setSubExpr(cast<Expr>(StmtStack.back()));
Douglas Gregora151ba42009-04-14 23:32:43 +0000541 return 1;
542}
543
Douglas Gregorc75d0cb2009-04-15 00:25:59 +0000544unsigned PCHStmtReader::VisitBinaryOperator(BinaryOperator *E) {
545 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000546 E->setLHS(cast<Expr>(StmtStack.end()[-2]));
547 E->setRHS(cast<Expr>(StmtStack.end()[-1]));
Douglas Gregorc75d0cb2009-04-15 00:25:59 +0000548 E->setOpcode((BinaryOperator::Opcode)Record[Idx++]);
549 E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
550 return 2;
551}
552
Douglas Gregorc599bbf2009-04-15 22:40:36 +0000553unsigned PCHStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
554 VisitBinaryOperator(E);
555 E->setComputationLHSType(Reader.GetType(Record[Idx++]));
556 E->setComputationResultType(Reader.GetType(Record[Idx++]));
557 return 2;
558}
559
560unsigned PCHStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
561 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000562 E->setCond(cast<Expr>(StmtStack[StmtStack.size() - 3]));
563 E->setLHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
564 E->setRHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 1]));
Douglas Gregorc599bbf2009-04-15 22:40:36 +0000565 return 3;
566}
567
Douglas Gregora151ba42009-04-14 23:32:43 +0000568unsigned PCHStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
569 VisitCastExpr(E);
570 E->setLvalueCast(Record[Idx++]);
571 return 1;
Douglas Gregorc10f86f2009-04-14 21:18:50 +0000572}
573
Douglas Gregorc75d0cb2009-04-15 00:25:59 +0000574unsigned PCHStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
575 VisitCastExpr(E);
576 E->setTypeAsWritten(Reader.GetType(Record[Idx++]));
577 return 1;
578}
579
580unsigned PCHStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) {
581 VisitExplicitCastExpr(E);
582 E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
583 E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
584 return 1;
585}
586
Douglas Gregorb70b48f2009-04-16 02:33:48 +0000587unsigned PCHStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
588 VisitExpr(E);
589 E->setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000590 E->setInitializer(cast<Expr>(StmtStack.back()));
Douglas Gregorb70b48f2009-04-16 02:33:48 +0000591 E->setFileScope(Record[Idx++]);
592 return 1;
593}
594
Douglas Gregorec0b8292009-04-15 23:02:49 +0000595unsigned PCHStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
596 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000597 E->setBase(cast<Expr>(StmtStack.back()));
Douglas Gregorec0b8292009-04-15 23:02:49 +0000598 E->setAccessor(Reader.GetIdentifierInfo(Record, Idx));
599 E->setAccessorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
600 return 1;
601}
602
Douglas Gregor6710a3c2009-04-16 00:55:48 +0000603unsigned PCHStmtReader::VisitInitListExpr(InitListExpr *E) {
604 VisitExpr(E);
605 unsigned NumInits = Record[Idx++];
606 E->reserveInits(NumInits);
607 for (unsigned I = 0; I != NumInits; ++I)
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000608 E->updateInit(I,
609 cast<Expr>(StmtStack[StmtStack.size() - NumInits - 1 + I]));
610 E->setSyntacticForm(cast_or_null<InitListExpr>(StmtStack.back()));
Douglas Gregor6710a3c2009-04-16 00:55:48 +0000611 E->setLBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
612 E->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
613 E->setInitializedFieldInUnion(
614 cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])));
615 E->sawArrayRangeDesignator(Record[Idx++]);
616 return NumInits + 1;
617}
618
619unsigned PCHStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
620 typedef DesignatedInitExpr::Designator Designator;
621
622 VisitExpr(E);
623 unsigned NumSubExprs = Record[Idx++];
624 assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs");
625 for (unsigned I = 0; I != NumSubExprs; ++I)
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000626 E->setSubExpr(I, cast<Expr>(StmtStack[StmtStack.size() - NumSubExprs + I]));
Douglas Gregor6710a3c2009-04-16 00:55:48 +0000627 E->setEqualOrColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
628 E->setGNUSyntax(Record[Idx++]);
629
630 llvm::SmallVector<Designator, 4> Designators;
631 while (Idx < Record.size()) {
632 switch ((pch::DesignatorTypes)Record[Idx++]) {
633 case pch::DESIG_FIELD_DECL: {
634 FieldDecl *Field = cast<FieldDecl>(Reader.GetDecl(Record[Idx++]));
635 SourceLocation DotLoc
636 = SourceLocation::getFromRawEncoding(Record[Idx++]);
637 SourceLocation FieldLoc
638 = SourceLocation::getFromRawEncoding(Record[Idx++]);
639 Designators.push_back(Designator(Field->getIdentifier(), DotLoc,
640 FieldLoc));
641 Designators.back().setField(Field);
642 break;
643 }
644
645 case pch::DESIG_FIELD_NAME: {
646 const IdentifierInfo *Name = Reader.GetIdentifierInfo(Record, Idx);
647 SourceLocation DotLoc
648 = SourceLocation::getFromRawEncoding(Record[Idx++]);
649 SourceLocation FieldLoc
650 = SourceLocation::getFromRawEncoding(Record[Idx++]);
651 Designators.push_back(Designator(Name, DotLoc, FieldLoc));
652 break;
653 }
654
655 case pch::DESIG_ARRAY: {
656 unsigned Index = Record[Idx++];
657 SourceLocation LBracketLoc
658 = SourceLocation::getFromRawEncoding(Record[Idx++]);
659 SourceLocation RBracketLoc
660 = SourceLocation::getFromRawEncoding(Record[Idx++]);
661 Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc));
662 break;
663 }
664
665 case pch::DESIG_ARRAY_RANGE: {
666 unsigned Index = Record[Idx++];
667 SourceLocation LBracketLoc
668 = SourceLocation::getFromRawEncoding(Record[Idx++]);
669 SourceLocation EllipsisLoc
670 = SourceLocation::getFromRawEncoding(Record[Idx++]);
671 SourceLocation RBracketLoc
672 = SourceLocation::getFromRawEncoding(Record[Idx++]);
673 Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc,
674 RBracketLoc));
675 break;
676 }
677 }
678 }
679 E->setDesignators(&Designators[0], Designators.size());
680
681 return NumSubExprs;
682}
683
684unsigned PCHStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
685 VisitExpr(E);
686 return 0;
687}
688
Douglas Gregorec0b8292009-04-15 23:02:49 +0000689unsigned PCHStmtReader::VisitVAArgExpr(VAArgExpr *E) {
690 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000691 E->setSubExpr(cast<Expr>(StmtStack.back()));
Douglas Gregorec0b8292009-04-15 23:02:49 +0000692 E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
693 E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
694 return 1;
695}
696
Douglas Gregor209d4622009-04-15 23:33:31 +0000697unsigned PCHStmtReader::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
698 VisitExpr(E);
699 E->setArgType1(Reader.GetType(Record[Idx++]));
700 E->setArgType2(Reader.GetType(Record[Idx++]));
701 E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
702 E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
703 return 0;
704}
705
706unsigned PCHStmtReader::VisitChooseExpr(ChooseExpr *E) {
707 VisitExpr(E);
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000708 E->setCond(cast<Expr>(StmtStack[StmtStack.size() - 3]));
709 E->setLHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 2]));
710 E->setRHS(cast_or_null<Expr>(StmtStack[StmtStack.size() - 1]));
Douglas Gregor209d4622009-04-15 23:33:31 +0000711 E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
712 E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
713 return 3;
714}
715
716unsigned PCHStmtReader::VisitGNUNullExpr(GNUNullExpr *E) {
717 VisitExpr(E);
718 E->setTokenLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
719 return 0;
720}
Douglas Gregorec0b8292009-04-15 23:02:49 +0000721
Douglas Gregor725e94b2009-04-16 00:01:45 +0000722unsigned PCHStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
723 VisitExpr(E);
724 unsigned NumExprs = Record[Idx++];
Douglas Gregorc72f6c82009-04-16 22:23:12 +0000725 E->setExprs((Expr **)&StmtStack[StmtStack.size() - NumExprs], NumExprs);
Douglas Gregor725e94b2009-04-16 00:01:45 +0000726 E->setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
727 E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
728 return NumExprs;
729}
730
731unsigned PCHStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
732 VisitExpr(E);
733 E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
734 E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
735 E->setByRef(Record[Idx++]);
736 return 0;
737}
738
Douglas Gregorc34897d2009-04-09 22:27:44 +0000739// FIXME: use the diagnostics machinery
740static bool Error(const char *Str) {
741 std::fprintf(stderr, "%s\n", Str);
742 return true;
743}
744
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000745/// \brief Check the contents of the predefines buffer against the
746/// contents of the predefines buffer used to build the PCH file.
747///
748/// The contents of the two predefines buffers should be the same. If
749/// not, then some command-line option changed the preprocessor state
750/// and we must reject the PCH file.
751///
752/// \param PCHPredef The start of the predefines buffer in the PCH
753/// file.
754///
755/// \param PCHPredefLen The length of the predefines buffer in the PCH
756/// file.
757///
758/// \param PCHBufferID The FileID for the PCH predefines buffer.
759///
760/// \returns true if there was a mismatch (in which case the PCH file
761/// should be ignored), or false otherwise.
762bool PCHReader::CheckPredefinesBuffer(const char *PCHPredef,
763 unsigned PCHPredefLen,
764 FileID PCHBufferID) {
765 const char *Predef = PP.getPredefines().c_str();
766 unsigned PredefLen = PP.getPredefines().size();
767
768 // If the two predefines buffers compare equal, we're done!.
769 if (PredefLen == PCHPredefLen &&
770 strncmp(Predef, PCHPredef, PCHPredefLen) == 0)
771 return false;
772
773 // The predefines buffers are different. Produce a reasonable
774 // diagnostic showing where they are different.
775
776 // The source locations (potentially in the two different predefines
777 // buffers)
778 SourceLocation Loc1, Loc2;
779 SourceManager &SourceMgr = PP.getSourceManager();
780
781 // Create a source buffer for our predefines string, so
782 // that we can build a diagnostic that points into that
783 // source buffer.
784 FileID BufferID;
785 if (Predef && Predef[0]) {
786 llvm::MemoryBuffer *Buffer
787 = llvm::MemoryBuffer::getMemBuffer(Predef, Predef + PredefLen,
788 "<built-in>");
789 BufferID = SourceMgr.createFileIDForMemBuffer(Buffer);
790 }
791
792 unsigned MinLen = std::min(PredefLen, PCHPredefLen);
793 std::pair<const char *, const char *> Locations
794 = std::mismatch(Predef, Predef + MinLen, PCHPredef);
795
796 if (Locations.first != Predef + MinLen) {
797 // We found the location in the two buffers where there is a
798 // difference. Form source locations to point there (in both
799 // buffers).
800 unsigned Offset = Locations.first - Predef;
801 Loc1 = SourceMgr.getLocForStartOfFile(BufferID)
802 .getFileLocWithOffset(Offset);
803 Loc2 = SourceMgr.getLocForStartOfFile(PCHBufferID)
804 .getFileLocWithOffset(Offset);
805 } else if (PredefLen > PCHPredefLen) {
806 Loc1 = SourceMgr.getLocForStartOfFile(BufferID)
807 .getFileLocWithOffset(MinLen);
808 } else {
809 Loc1 = SourceMgr.getLocForStartOfFile(PCHBufferID)
810 .getFileLocWithOffset(MinLen);
811 }
812
813 Diag(Loc1, diag::warn_pch_preprocessor);
814 if (Loc2.isValid())
815 Diag(Loc2, diag::note_predef_in_pch);
816 Diag(diag::note_ignoring_pch) << FileName;
817 return true;
818}
819
Douglas Gregor635f97f2009-04-13 16:31:14 +0000820/// \brief Read the line table in the source manager block.
821/// \returns true if ther was an error.
822static bool ParseLineTable(SourceManager &SourceMgr,
823 llvm::SmallVectorImpl<uint64_t> &Record) {
824 unsigned Idx = 0;
825 LineTableInfo &LineTable = SourceMgr.getLineTable();
826
827 // Parse the file names
Douglas Gregor183ad602009-04-13 17:12:42 +0000828 std::map<int, int> FileIDs;
829 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregor635f97f2009-04-13 16:31:14 +0000830 // Extract the file name
831 unsigned FilenameLen = Record[Idx++];
832 std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
833 Idx += FilenameLen;
Douglas Gregor183ad602009-04-13 17:12:42 +0000834 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
835 Filename.size());
Douglas Gregor635f97f2009-04-13 16:31:14 +0000836 }
837
838 // Parse the line entries
839 std::vector<LineEntry> Entries;
840 while (Idx < Record.size()) {
Douglas Gregor183ad602009-04-13 17:12:42 +0000841 int FID = FileIDs[Record[Idx++]];
Douglas Gregor635f97f2009-04-13 16:31:14 +0000842
843 // Extract the line entries
844 unsigned NumEntries = Record[Idx++];
845 Entries.clear();
846 Entries.reserve(NumEntries);
847 for (unsigned I = 0; I != NumEntries; ++I) {
848 unsigned FileOffset = Record[Idx++];
849 unsigned LineNo = Record[Idx++];
850 int FilenameID = Record[Idx++];
851 SrcMgr::CharacteristicKind FileKind
852 = (SrcMgr::CharacteristicKind)Record[Idx++];
853 unsigned IncludeOffset = Record[Idx++];
854 Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
855 FileKind, IncludeOffset));
856 }
857 LineTable.AddEntry(FID, Entries);
858 }
859
860 return false;
861}
862
Douglas Gregorab1cef72009-04-10 03:52:48 +0000863/// \brief Read the source manager block
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000864PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
Douglas Gregorab1cef72009-04-10 03:52:48 +0000865 using namespace SrcMgr;
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000866 if (Stream.EnterSubBlock(pch::SOURCE_MANAGER_BLOCK_ID)) {
867 Error("Malformed source manager block record");
868 return Failure;
869 }
Douglas Gregorab1cef72009-04-10 03:52:48 +0000870
871 SourceManager &SourceMgr = Context.getSourceManager();
872 RecordData Record;
873 while (true) {
874 unsigned Code = Stream.ReadCode();
875 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000876 if (Stream.ReadBlockEnd()) {
877 Error("Error at end of Source Manager block");
878 return Failure;
879 }
880
881 return Success;
Douglas Gregorab1cef72009-04-10 03:52:48 +0000882 }
883
884 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
885 // No known subblocks, always skip them.
886 Stream.ReadSubBlockID();
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000887 if (Stream.SkipBlock()) {
888 Error("Malformed block record");
889 return Failure;
890 }
Douglas Gregorab1cef72009-04-10 03:52:48 +0000891 continue;
892 }
893
894 if (Code == llvm::bitc::DEFINE_ABBREV) {
895 Stream.ReadAbbrevRecord();
896 continue;
897 }
898
899 // Read a record.
900 const char *BlobStart;
901 unsigned BlobLen;
902 Record.clear();
903 switch (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
904 default: // Default behavior: ignore.
905 break;
906
907 case pch::SM_SLOC_FILE_ENTRY: {
908 // FIXME: We would really like to delay the creation of this
909 // FileEntry until it is actually required, e.g., when producing
910 // a diagnostic with a source location in this file.
911 const FileEntry *File
912 = PP.getFileManager().getFile(BlobStart, BlobStart + BlobLen);
913 // FIXME: Error recovery if file cannot be found.
Douglas Gregor635f97f2009-04-13 16:31:14 +0000914 FileID ID = SourceMgr.createFileID(File,
915 SourceLocation::getFromRawEncoding(Record[1]),
916 (CharacteristicKind)Record[2]);
917 if (Record[3])
918 const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(ID).getFile())
919 .setHasLineDirectives();
Douglas Gregorab1cef72009-04-10 03:52:48 +0000920 break;
921 }
922
923 case pch::SM_SLOC_BUFFER_ENTRY: {
924 const char *Name = BlobStart;
925 unsigned Code = Stream.ReadCode();
926 Record.clear();
927 unsigned RecCode = Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen);
928 assert(RecCode == pch::SM_SLOC_BUFFER_BLOB && "Ill-formed PCH file");
Douglas Gregor3c8ff3e2009-04-15 18:43:11 +0000929 (void)RecCode;
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000930 llvm::MemoryBuffer *Buffer
931 = llvm::MemoryBuffer::getMemBuffer(BlobStart,
932 BlobStart + BlobLen - 1,
933 Name);
934 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer);
935
936 if (strcmp(Name, "<built-in>") == 0
937 && CheckPredefinesBuffer(BlobStart, BlobLen - 1, BufferID))
938 return IgnorePCH;
Douglas Gregorab1cef72009-04-10 03:52:48 +0000939 break;
940 }
941
942 case pch::SM_SLOC_INSTANTIATION_ENTRY: {
943 SourceLocation SpellingLoc
944 = SourceLocation::getFromRawEncoding(Record[1]);
945 SourceMgr.createInstantiationLoc(
946 SpellingLoc,
947 SourceLocation::getFromRawEncoding(Record[2]),
948 SourceLocation::getFromRawEncoding(Record[3]),
Douglas Gregor364e5802009-04-15 18:05:10 +0000949 Record[4]);
Douglas Gregorab1cef72009-04-10 03:52:48 +0000950 break;
951 }
952
Chris Lattnere1be6022009-04-14 23:22:57 +0000953 case pch::SM_LINE_TABLE:
Douglas Gregor635f97f2009-04-13 16:31:14 +0000954 if (ParseLineTable(SourceMgr, Record))
955 return Failure;
Chris Lattnere1be6022009-04-14 23:22:57 +0000956 break;
Douglas Gregorab1cef72009-04-10 03:52:48 +0000957 }
958 }
959}
960
Chris Lattnerdb1c81b2009-04-10 21:41:48 +0000961bool PCHReader::ReadPreprocessorBlock() {
962 if (Stream.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID))
963 return Error("Malformed preprocessor block record");
964
Chris Lattnerdb1c81b2009-04-10 21:41:48 +0000965 RecordData Record;
966 llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
967 MacroInfo *LastMacro = 0;
968
969 while (true) {
970 unsigned Code = Stream.ReadCode();
971 switch (Code) {
972 case llvm::bitc::END_BLOCK:
973 if (Stream.ReadBlockEnd())
974 return Error("Error at end of preprocessor block");
975 return false;
976
977 case llvm::bitc::ENTER_SUBBLOCK:
978 // No known subblocks, always skip them.
979 Stream.ReadSubBlockID();
980 if (Stream.SkipBlock())
981 return Error("Malformed block record");
982 continue;
983
984 case llvm::bitc::DEFINE_ABBREV:
985 Stream.ReadAbbrevRecord();
986 continue;
987 default: break;
988 }
989
990 // Read a record.
991 Record.clear();
992 pch::PreprocessorRecordTypes RecType =
993 (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
994 switch (RecType) {
995 default: // Default behavior: ignore unknown records.
996 break;
Chris Lattner4b21c202009-04-13 01:29:17 +0000997 case pch::PP_COUNTER_VALUE:
998 if (!Record.empty())
999 PP.setCounterValue(Record[0]);
1000 break;
1001
Chris Lattnerdb1c81b2009-04-10 21:41:48 +00001002 case pch::PP_MACRO_OBJECT_LIKE:
1003 case pch::PP_MACRO_FUNCTION_LIKE: {
Chris Lattner29241862009-04-11 21:15:38 +00001004 IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
1005 if (II == 0)
1006 return Error("Macro must have a name");
Chris Lattnerdb1c81b2009-04-10 21:41:48 +00001007 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
1008 bool isUsed = Record[2];
1009
1010 MacroInfo *MI = PP.AllocateMacroInfo(Loc);
1011 MI->setIsUsed(isUsed);
1012
1013 if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
1014 // Decode function-like macro info.
1015 bool isC99VarArgs = Record[3];
1016 bool isGNUVarArgs = Record[4];
1017 MacroArgs.clear();
1018 unsigned NumArgs = Record[5];
1019 for (unsigned i = 0; i != NumArgs; ++i)
Chris Lattner29241862009-04-11 21:15:38 +00001020 MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
Chris Lattnerdb1c81b2009-04-10 21:41:48 +00001021
1022 // Install function-like macro info.
1023 MI->setIsFunctionLike();
1024 if (isC99VarArgs) MI->setIsC99Varargs();
1025 if (isGNUVarArgs) MI->setIsGNUVarargs();
1026 MI->setArgumentList(&MacroArgs[0], MacroArgs.size(),
1027 PP.getPreprocessorAllocator());
1028 }
1029
1030 // Finally, install the macro.
Chris Lattnerdb1c81b2009-04-10 21:41:48 +00001031 PP.setMacroInfo(II, MI);
Chris Lattnerdb1c81b2009-04-10 21:41:48 +00001032
1033 // Remember that we saw this macro last so that we add the tokens that
1034 // form its body to it.
1035 LastMacro = MI;
1036 break;
1037 }
1038
1039 case pch::PP_TOKEN: {
1040 // If we see a TOKEN before a PP_MACRO_*, then the file is eroneous, just
1041 // pretend we didn't see this.
1042 if (LastMacro == 0) break;
1043
1044 Token Tok;
1045 Tok.startToken();
1046 Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
1047 Tok.setLength(Record[1]);
Chris Lattner29241862009-04-11 21:15:38 +00001048 if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
1049 Tok.setIdentifierInfo(II);
Chris Lattnerdb1c81b2009-04-10 21:41:48 +00001050 Tok.setKind((tok::TokenKind)Record[3]);
1051 Tok.setFlag((Token::TokenFlags)Record[4]);
1052 LastMacro->AddTokenToBody(Tok);
1053 break;
1054 }
1055 }
1056 }
1057}
1058
Douglas Gregor179cfb12009-04-10 20:39:37 +00001059PCHReader::PCHReadResult PCHReader::ReadPCHBlock() {
1060 if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
1061 Error("Malformed block record");
1062 return Failure;
1063 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001064
Chris Lattner29241862009-04-11 21:15:38 +00001065 uint64_t PreprocessorBlockBit = 0;
1066
Douglas Gregorc34897d2009-04-09 22:27:44 +00001067 // Read all of the records and blocks for the PCH file.
Douglas Gregorac8f2802009-04-10 17:25:41 +00001068 RecordData Record;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001069 while (!Stream.AtEndOfStream()) {
1070 unsigned Code = Stream.ReadCode();
1071 if (Code == llvm::bitc::END_BLOCK) {
Chris Lattner29241862009-04-11 21:15:38 +00001072 // If we saw the preprocessor block, read it now.
1073 if (PreprocessorBlockBit) {
1074 uint64_t SavedPos = Stream.GetCurrentBitNo();
1075 Stream.JumpToBit(PreprocessorBlockBit);
1076 if (ReadPreprocessorBlock()) {
1077 Error("Malformed preprocessor block");
1078 return Failure;
1079 }
1080 Stream.JumpToBit(SavedPos);
1081 }
1082
Douglas Gregor179cfb12009-04-10 20:39:37 +00001083 if (Stream.ReadBlockEnd()) {
1084 Error("Error at end of module block");
1085 return Failure;
1086 }
Chris Lattner29241862009-04-11 21:15:38 +00001087
Douglas Gregor179cfb12009-04-10 20:39:37 +00001088 return Success;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001089 }
1090
1091 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1092 switch (Stream.ReadSubBlockID()) {
1093 case pch::DECLS_BLOCK_ID: // Skip decls block (lazily loaded)
1094 case pch::TYPES_BLOCK_ID: // Skip types block (lazily loaded)
1095 default: // Skip unknown content.
Douglas Gregor179cfb12009-04-10 20:39:37 +00001096 if (Stream.SkipBlock()) {
1097 Error("Malformed block record");
1098 return Failure;
1099 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001100 break;
1101
Chris Lattner29241862009-04-11 21:15:38 +00001102 case pch::PREPROCESSOR_BLOCK_ID:
1103 // Skip the preprocessor block for now, but remember where it is. We
1104 // want to read it in after the identifier table.
1105 if (PreprocessorBlockBit) {
1106 Error("Multiple preprocessor blocks found.");
1107 return Failure;
1108 }
1109 PreprocessorBlockBit = Stream.GetCurrentBitNo();
1110 if (Stream.SkipBlock()) {
1111 Error("Malformed block record");
1112 return Failure;
1113 }
1114 break;
1115
Douglas Gregorab1cef72009-04-10 03:52:48 +00001116 case pch::SOURCE_MANAGER_BLOCK_ID:
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001117 switch (ReadSourceManagerBlock()) {
1118 case Success:
1119 break;
1120
1121 case Failure:
Douglas Gregor179cfb12009-04-10 20:39:37 +00001122 Error("Malformed source manager block");
1123 return Failure;
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001124
1125 case IgnorePCH:
1126 return IgnorePCH;
Douglas Gregor179cfb12009-04-10 20:39:37 +00001127 }
Douglas Gregorab1cef72009-04-10 03:52:48 +00001128 break;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001129 }
Douglas Gregorac8f2802009-04-10 17:25:41 +00001130 continue;
1131 }
1132
1133 if (Code == llvm::bitc::DEFINE_ABBREV) {
1134 Stream.ReadAbbrevRecord();
1135 continue;
1136 }
1137
1138 // Read and process a record.
1139 Record.clear();
Douglas Gregorb5887f32009-04-10 21:16:55 +00001140 const char *BlobStart = 0;
1141 unsigned BlobLen = 0;
1142 switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record,
1143 &BlobStart, &BlobLen)) {
Douglas Gregorac8f2802009-04-10 17:25:41 +00001144 default: // Default behavior: ignore.
1145 break;
1146
1147 case pch::TYPE_OFFSET:
Douglas Gregor179cfb12009-04-10 20:39:37 +00001148 if (!TypeOffsets.empty()) {
1149 Error("Duplicate TYPE_OFFSET record in PCH file");
1150 return Failure;
1151 }
Douglas Gregorac8f2802009-04-10 17:25:41 +00001152 TypeOffsets.swap(Record);
1153 TypeAlreadyLoaded.resize(TypeOffsets.size(), false);
1154 break;
1155
1156 case pch::DECL_OFFSET:
Douglas Gregor179cfb12009-04-10 20:39:37 +00001157 if (!DeclOffsets.empty()) {
1158 Error("Duplicate DECL_OFFSET record in PCH file");
1159 return Failure;
1160 }
Douglas Gregorac8f2802009-04-10 17:25:41 +00001161 DeclOffsets.swap(Record);
1162 DeclAlreadyLoaded.resize(DeclOffsets.size(), false);
1163 break;
Douglas Gregor179cfb12009-04-10 20:39:37 +00001164
1165 case pch::LANGUAGE_OPTIONS:
1166 if (ParseLanguageOptions(Record))
1167 return IgnorePCH;
1168 break;
Douglas Gregorb5887f32009-04-10 21:16:55 +00001169
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001170 case pch::TARGET_TRIPLE: {
Douglas Gregorb5887f32009-04-10 21:16:55 +00001171 std::string TargetTriple(BlobStart, BlobLen);
1172 if (TargetTriple != Context.Target.getTargetTriple()) {
1173 Diag(diag::warn_pch_target_triple)
1174 << TargetTriple << Context.Target.getTargetTriple();
1175 Diag(diag::note_ignoring_pch) << FileName;
1176 return IgnorePCH;
1177 }
1178 break;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001179 }
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001180
1181 case pch::IDENTIFIER_TABLE:
1182 IdentifierTable = BlobStart;
1183 break;
1184
1185 case pch::IDENTIFIER_OFFSET:
1186 if (!IdentifierData.empty()) {
1187 Error("Duplicate IDENTIFIER_OFFSET record in PCH file");
1188 return Failure;
1189 }
1190 IdentifierData.swap(Record);
1191#ifndef NDEBUG
1192 for (unsigned I = 0, N = IdentifierData.size(); I != N; ++I) {
1193 if ((IdentifierData[I] & 0x01) == 0) {
1194 Error("Malformed identifier table in the precompiled header");
1195 return Failure;
1196 }
1197 }
1198#endif
1199 break;
Douglas Gregor631f6c62009-04-14 00:24:19 +00001200
1201 case pch::EXTERNAL_DEFINITIONS:
1202 if (!ExternalDefinitions.empty()) {
1203 Error("Duplicate EXTERNAL_DEFINITIONS record in PCH file");
1204 return Failure;
1205 }
1206 ExternalDefinitions.swap(Record);
1207 break;
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001208 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001209 }
1210
Douglas Gregor179cfb12009-04-10 20:39:37 +00001211 Error("Premature end of bitstream");
1212 return Failure;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001213}
1214
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001215PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
Douglas Gregor179cfb12009-04-10 20:39:37 +00001216 // Set the PCH file name.
1217 this->FileName = FileName;
1218
Douglas Gregorc34897d2009-04-09 22:27:44 +00001219 // Open the PCH file.
1220 std::string ErrStr;
1221 Buffer.reset(llvm::MemoryBuffer::getFile(FileName.c_str(), &ErrStr));
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001222 if (!Buffer) {
1223 Error(ErrStr.c_str());
1224 return IgnorePCH;
1225 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001226
1227 // Initialize the stream
1228 Stream.init((const unsigned char *)Buffer->getBufferStart(),
1229 (const unsigned char *)Buffer->getBufferEnd());
1230
1231 // Sniff for the signature.
1232 if (Stream.Read(8) != 'C' ||
1233 Stream.Read(8) != 'P' ||
1234 Stream.Read(8) != 'C' ||
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001235 Stream.Read(8) != 'H') {
1236 Error("Not a PCH file");
1237 return IgnorePCH;
1238 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001239
1240 // We expect a number of well-defined blocks, though we don't necessarily
1241 // need to understand them all.
1242 while (!Stream.AtEndOfStream()) {
1243 unsigned Code = Stream.ReadCode();
1244
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001245 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
1246 Error("Invalid record at top-level");
1247 return Failure;
1248 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001249
1250 unsigned BlockID = Stream.ReadSubBlockID();
1251
1252 // We only know the PCH subblock ID.
1253 switch (BlockID) {
1254 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001255 if (Stream.ReadBlockInfoBlock()) {
1256 Error("Malformed BlockInfoBlock");
1257 return Failure;
1258 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001259 break;
1260 case pch::PCH_BLOCK_ID:
Douglas Gregor179cfb12009-04-10 20:39:37 +00001261 switch (ReadPCHBlock()) {
1262 case Success:
1263 break;
1264
1265 case Failure:
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001266 return Failure;
Douglas Gregor179cfb12009-04-10 20:39:37 +00001267
1268 case IgnorePCH:
Douglas Gregorb5887f32009-04-10 21:16:55 +00001269 // FIXME: We could consider reading through to the end of this
1270 // PCH block, skipping subblocks, to see if there are other
1271 // PCH blocks elsewhere.
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001272 return IgnorePCH;
Douglas Gregor179cfb12009-04-10 20:39:37 +00001273 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001274 break;
1275 default:
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001276 if (Stream.SkipBlock()) {
1277 Error("Malformed block record");
1278 return Failure;
1279 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001280 break;
1281 }
1282 }
1283
1284 // Load the translation unit declaration
1285 ReadDeclRecord(DeclOffsets[0], 0);
1286
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001287 return Success;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001288}
1289
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001290namespace {
1291 /// \brief Helper class that saves the current stream position and
1292 /// then restores it when destroyed.
1293 struct VISIBILITY_HIDDEN SavedStreamPosition {
1294 explicit SavedStreamPosition(llvm::BitstreamReader &Stream)
Douglas Gregor6dc849b2009-04-15 04:54:29 +00001295 : Stream(Stream), Offset(Stream.GetCurrentBitNo()) { }
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001296
1297 ~SavedStreamPosition() {
Douglas Gregor6dc849b2009-04-15 04:54:29 +00001298 Stream.JumpToBit(Offset);
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001299 }
1300
1301 private:
1302 llvm::BitstreamReader &Stream;
1303 uint64_t Offset;
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001304 };
1305}
1306
Douglas Gregor179cfb12009-04-10 20:39:37 +00001307/// \brief Parse the record that corresponds to a LangOptions data
1308/// structure.
1309///
1310/// This routine compares the language options used to generate the
1311/// PCH file against the language options set for the current
1312/// compilation. For each option, we classify differences between the
1313/// two compiler states as either "benign" or "important". Benign
1314/// differences don't matter, and we accept them without complaint
1315/// (and without modifying the language options). Differences between
1316/// the states for important options cause the PCH file to be
1317/// unusable, so we emit a warning and return true to indicate that
1318/// there was an error.
1319///
1320/// \returns true if the PCH file is unacceptable, false otherwise.
1321bool PCHReader::ParseLanguageOptions(
1322 const llvm::SmallVectorImpl<uint64_t> &Record) {
1323 const LangOptions &LangOpts = Context.getLangOptions();
1324#define PARSE_LANGOPT_BENIGN(Option) ++Idx
1325#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
1326 if (Record[Idx] != LangOpts.Option) { \
1327 Diag(DiagID) << (unsigned)Record[Idx] << LangOpts.Option; \
1328 Diag(diag::note_ignoring_pch) << FileName; \
1329 return true; \
1330 } \
1331 ++Idx
1332
1333 unsigned Idx = 0;
1334 PARSE_LANGOPT_BENIGN(Trigraphs);
1335 PARSE_LANGOPT_BENIGN(BCPLComment);
1336 PARSE_LANGOPT_BENIGN(DollarIdents);
1337 PARSE_LANGOPT_BENIGN(AsmPreprocessor);
1338 PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
1339 PARSE_LANGOPT_BENIGN(ImplicitInt);
1340 PARSE_LANGOPT_BENIGN(Digraphs);
1341 PARSE_LANGOPT_BENIGN(HexFloats);
1342 PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
1343 PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
1344 PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
1345 PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
1346 PARSE_LANGOPT_IMPORTANT(NoExtensions, diag::warn_pch_extensions);
1347 PARSE_LANGOPT_BENIGN(CXXOperatorName);
1348 PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
1349 PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
1350 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
1351 PARSE_LANGOPT_BENIGN(PascalStrings);
1352 PARSE_LANGOPT_BENIGN(Boolean);
1353 PARSE_LANGOPT_BENIGN(WritableStrings);
1354 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
1355 diag::warn_pch_lax_vector_conversions);
1356 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
1357 PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
1358 PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
1359 PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
1360 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
1361 diag::warn_pch_thread_safe_statics);
1362 PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
1363 PARSE_LANGOPT_BENIGN(EmitAllDecls);
1364 PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
1365 PARSE_LANGOPT_IMPORTANT(OverflowChecking, diag::warn_pch_overflow_checking);
1366 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
1367 diag::warn_pch_heinous_extensions);
1368 // FIXME: Most of the options below are benign if the macro wasn't
1369 // used. Unfortunately, this means that a PCH compiled without
1370 // optimization can't be used with optimization turned on, even
1371 // though the only thing that changes is whether __OPTIMIZE__ was
1372 // defined... but if __OPTIMIZE__ never showed up in the header, it
1373 // doesn't matter. We could consider making this some special kind
1374 // of check.
1375 PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
1376 PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
1377 PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
1378 PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
1379 PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
1380 PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
1381 if ((LangOpts.getGCMode() != 0) != (Record[Idx] != 0)) {
1382 Diag(diag::warn_pch_gc_mode)
1383 << (unsigned)Record[Idx] << LangOpts.getGCMode();
1384 Diag(diag::note_ignoring_pch) << FileName;
1385 return true;
1386 }
1387 ++Idx;
1388 PARSE_LANGOPT_BENIGN(getVisibilityMode());
1389 PARSE_LANGOPT_BENIGN(InstantiationDepth);
1390#undef PARSE_LANGOPT_IRRELEVANT
1391#undef PARSE_LANGOPT_BENIGN
1392
1393 return false;
1394}
1395
Douglas Gregorc34897d2009-04-09 22:27:44 +00001396/// \brief Read and return the type at the given offset.
1397///
1398/// This routine actually reads the record corresponding to the type
1399/// at the given offset in the bitstream. It is a helper routine for
1400/// GetType, which deals with reading type IDs.
1401QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001402 // Keep track of where we are in the stream, then jump back there
1403 // after reading this type.
1404 SavedStreamPosition SavedPosition(Stream);
1405
Douglas Gregorc34897d2009-04-09 22:27:44 +00001406 Stream.JumpToBit(Offset);
1407 RecordData Record;
1408 unsigned Code = Stream.ReadCode();
1409 switch ((pch::TypeCode)Stream.ReadRecord(Code, Record)) {
Douglas Gregorbdd4ba52009-04-15 22:00:08 +00001410 case pch::TYPE_EXT_QUAL: {
1411 assert(Record.size() == 3 &&
1412 "Incorrect encoding of extended qualifier type");
1413 QualType Base = GetType(Record[0]);
1414 QualType::GCAttrTypes GCAttr = (QualType::GCAttrTypes)Record[1];
1415 unsigned AddressSpace = Record[2];
1416
1417 QualType T = Base;
1418 if (GCAttr != QualType::GCNone)
1419 T = Context.getObjCGCQualType(T, GCAttr);
1420 if (AddressSpace)
1421 T = Context.getAddrSpaceQualType(T, AddressSpace);
1422 return T;
1423 }
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001424
Douglas Gregorc34897d2009-04-09 22:27:44 +00001425 case pch::TYPE_FIXED_WIDTH_INT: {
1426 assert(Record.size() == 2 && "Incorrect encoding of fixed-width int type");
1427 return Context.getFixedWidthIntType(Record[0], Record[1]);
1428 }
1429
1430 case pch::TYPE_COMPLEX: {
1431 assert(Record.size() == 1 && "Incorrect encoding of complex type");
1432 QualType ElemType = GetType(Record[0]);
1433 return Context.getComplexType(ElemType);
1434 }
1435
1436 case pch::TYPE_POINTER: {
1437 assert(Record.size() == 1 && "Incorrect encoding of pointer type");
1438 QualType PointeeType = GetType(Record[0]);
1439 return Context.getPointerType(PointeeType);
1440 }
1441
1442 case pch::TYPE_BLOCK_POINTER: {
1443 assert(Record.size() == 1 && "Incorrect encoding of block pointer type");
1444 QualType PointeeType = GetType(Record[0]);
1445 return Context.getBlockPointerType(PointeeType);
1446 }
1447
1448 case pch::TYPE_LVALUE_REFERENCE: {
1449 assert(Record.size() == 1 && "Incorrect encoding of lvalue reference type");
1450 QualType PointeeType = GetType(Record[0]);
1451 return Context.getLValueReferenceType(PointeeType);
1452 }
1453
1454 case pch::TYPE_RVALUE_REFERENCE: {
1455 assert(Record.size() == 1 && "Incorrect encoding of rvalue reference type");
1456 QualType PointeeType = GetType(Record[0]);
1457 return Context.getRValueReferenceType(PointeeType);
1458 }
1459
1460 case pch::TYPE_MEMBER_POINTER: {
1461 assert(Record.size() == 1 && "Incorrect encoding of member pointer type");
1462 QualType PointeeType = GetType(Record[0]);
1463 QualType ClassType = GetType(Record[1]);
1464 return Context.getMemberPointerType(PointeeType, ClassType.getTypePtr());
1465 }
1466
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001467 case pch::TYPE_CONSTANT_ARRAY: {
1468 QualType ElementType = GetType(Record[0]);
1469 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1470 unsigned IndexTypeQuals = Record[2];
1471 unsigned Idx = 3;
1472 llvm::APInt Size = ReadAPInt(Record, Idx);
1473 return Context.getConstantArrayType(ElementType, Size, ASM, IndexTypeQuals);
1474 }
1475
1476 case pch::TYPE_INCOMPLETE_ARRAY: {
1477 QualType ElementType = GetType(Record[0]);
1478 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1479 unsigned IndexTypeQuals = Record[2];
1480 return Context.getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
1481 }
1482
1483 case pch::TYPE_VARIABLE_ARRAY: {
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001484 QualType ElementType = GetType(Record[0]);
1485 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1486 unsigned IndexTypeQuals = Record[2];
1487 return Context.getVariableArrayType(ElementType, ReadExpr(),
1488 ASM, IndexTypeQuals);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001489 }
1490
1491 case pch::TYPE_VECTOR: {
1492 if (Record.size() != 2) {
1493 Error("Incorrect encoding of vector type in PCH file");
1494 return QualType();
1495 }
1496
1497 QualType ElementType = GetType(Record[0]);
1498 unsigned NumElements = Record[1];
1499 return Context.getVectorType(ElementType, NumElements);
1500 }
1501
1502 case pch::TYPE_EXT_VECTOR: {
1503 if (Record.size() != 2) {
1504 Error("Incorrect encoding of extended vector type in PCH file");
1505 return QualType();
1506 }
1507
1508 QualType ElementType = GetType(Record[0]);
1509 unsigned NumElements = Record[1];
1510 return Context.getExtVectorType(ElementType, NumElements);
1511 }
1512
1513 case pch::TYPE_FUNCTION_NO_PROTO: {
1514 if (Record.size() != 1) {
1515 Error("Incorrect encoding of no-proto function type");
1516 return QualType();
1517 }
1518 QualType ResultType = GetType(Record[0]);
1519 return Context.getFunctionNoProtoType(ResultType);
1520 }
1521
1522 case pch::TYPE_FUNCTION_PROTO: {
1523 QualType ResultType = GetType(Record[0]);
1524 unsigned Idx = 1;
1525 unsigned NumParams = Record[Idx++];
1526 llvm::SmallVector<QualType, 16> ParamTypes;
1527 for (unsigned I = 0; I != NumParams; ++I)
1528 ParamTypes.push_back(GetType(Record[Idx++]));
1529 bool isVariadic = Record[Idx++];
1530 unsigned Quals = Record[Idx++];
1531 return Context.getFunctionType(ResultType, &ParamTypes[0], NumParams,
1532 isVariadic, Quals);
1533 }
1534
1535 case pch::TYPE_TYPEDEF:
1536 assert(Record.size() == 1 && "Incorrect encoding of typedef type");
1537 return Context.getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));
1538
1539 case pch::TYPE_TYPEOF_EXPR:
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001540 return Context.getTypeOfExprType(ReadExpr());
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001541
1542 case pch::TYPE_TYPEOF: {
1543 if (Record.size() != 1) {
1544 Error("Incorrect encoding of typeof(type) in PCH file");
1545 return QualType();
1546 }
1547 QualType UnderlyingType = GetType(Record[0]);
1548 return Context.getTypeOfType(UnderlyingType);
1549 }
1550
1551 case pch::TYPE_RECORD:
Douglas Gregor982365e2009-04-13 21:20:57 +00001552 assert(Record.size() == 1 && "Incorrect encoding of record type");
1553 return Context.getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001554
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001555 case pch::TYPE_ENUM:
1556 assert(Record.size() == 1 && "Incorrect encoding of enum type");
1557 return Context.getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
1558
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001559 case pch::TYPE_OBJC_INTERFACE:
1560 // FIXME: Deserialize ObjCInterfaceType
1561 assert(false && "Cannot de-serialize ObjC interface types yet");
1562 return QualType();
1563
1564 case pch::TYPE_OBJC_QUALIFIED_INTERFACE:
1565 // FIXME: Deserialize ObjCQualifiedInterfaceType
1566 assert(false && "Cannot de-serialize ObjC qualified interface types yet");
1567 return QualType();
1568
1569 case pch::TYPE_OBJC_QUALIFIED_ID:
1570 // FIXME: Deserialize ObjCQualifiedIdType
1571 assert(false && "Cannot de-serialize ObjC qualified id types yet");
1572 return QualType();
1573
1574 case pch::TYPE_OBJC_QUALIFIED_CLASS:
1575 // FIXME: Deserialize ObjCQualifiedClassType
1576 assert(false && "Cannot de-serialize ObjC qualified class types yet");
1577 return QualType();
Douglas Gregorc34897d2009-04-09 22:27:44 +00001578 }
1579
1580 // Suppress a GCC warning
1581 return QualType();
1582}
1583
1584/// \brief Note that we have loaded the declaration with the given
1585/// Index.
1586///
1587/// This routine notes that this declaration has already been loaded,
1588/// so that future GetDecl calls will return this declaration rather
1589/// than trying to load a new declaration.
1590inline void PCHReader::LoadedDecl(unsigned Index, Decl *D) {
1591 assert(!DeclAlreadyLoaded[Index] && "Decl loaded twice?");
1592 DeclAlreadyLoaded[Index] = true;
1593 DeclOffsets[Index] = reinterpret_cast<uint64_t>(D);
1594}
1595
1596/// \brief Read the declaration at the given offset from the PCH file.
1597Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001598 // Keep track of where we are in the stream, then jump back there
1599 // after reading this declaration.
1600 SavedStreamPosition SavedPosition(Stream);
1601
Douglas Gregorc34897d2009-04-09 22:27:44 +00001602 Decl *D = 0;
1603 Stream.JumpToBit(Offset);
1604 RecordData Record;
1605 unsigned Code = Stream.ReadCode();
1606 unsigned Idx = 0;
1607 PCHDeclReader Reader(*this, Record, Idx);
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001608
Douglas Gregorc34897d2009-04-09 22:27:44 +00001609 switch ((pch::DeclCode)Stream.ReadRecord(Code, Record)) {
Douglas Gregor1c507882009-04-15 21:30:51 +00001610 case pch::DECL_ATTR:
1611 case pch::DECL_CONTEXT_LEXICAL:
1612 case pch::DECL_CONTEXT_VISIBLE:
1613 assert(false && "Record cannot be de-serialized with ReadDeclRecord");
1614 break;
1615
Douglas Gregorc34897d2009-04-09 22:27:44 +00001616 case pch::DECL_TRANSLATION_UNIT:
1617 assert(Index == 0 && "Translation unit must be at index 0");
Douglas Gregorc34897d2009-04-09 22:27:44 +00001618 D = Context.getTranslationUnitDecl();
Douglas Gregorc34897d2009-04-09 22:27:44 +00001619 break;
1620
1621 case pch::DECL_TYPEDEF: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001622 D = TypedefDecl::Create(Context, 0, SourceLocation(), 0, QualType());
Douglas Gregorc34897d2009-04-09 22:27:44 +00001623 break;
1624 }
1625
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001626 case pch::DECL_ENUM: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001627 D = EnumDecl::Create(Context, 0, SourceLocation(), 0, 0);
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001628 break;
1629 }
1630
Douglas Gregor982365e2009-04-13 21:20:57 +00001631 case pch::DECL_RECORD: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001632 D = RecordDecl::Create(Context, TagDecl::TK_struct, 0, SourceLocation(),
1633 0, 0);
Douglas Gregor982365e2009-04-13 21:20:57 +00001634 break;
1635 }
1636
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001637 case pch::DECL_ENUM_CONSTANT: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001638 D = EnumConstantDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
1639 0, llvm::APSInt());
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001640 break;
1641 }
Douglas Gregor23ce3a52009-04-13 22:18:37 +00001642
1643 case pch::DECL_FUNCTION: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001644 D = FunctionDecl::Create(Context, 0, SourceLocation(), DeclarationName(),
1645 QualType());
Douglas Gregor23ce3a52009-04-13 22:18:37 +00001646 break;
1647 }
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001648
Douglas Gregor982365e2009-04-13 21:20:57 +00001649 case pch::DECL_FIELD: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001650 D = FieldDecl::Create(Context, 0, SourceLocation(), 0, QualType(), 0,
1651 false);
Douglas Gregor982365e2009-04-13 21:20:57 +00001652 break;
1653 }
1654
Douglas Gregorc34897d2009-04-09 22:27:44 +00001655 case pch::DECL_VAR: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001656 D = VarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
1657 VarDecl::None, SourceLocation());
Douglas Gregorc34897d2009-04-09 22:27:44 +00001658 break;
1659 }
1660
Douglas Gregor23ce3a52009-04-13 22:18:37 +00001661 case pch::DECL_PARM_VAR: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001662 D = ParmVarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
1663 VarDecl::None, 0);
Douglas Gregor23ce3a52009-04-13 22:18:37 +00001664 break;
1665 }
1666
1667 case pch::DECL_ORIGINAL_PARM_VAR: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001668 D = OriginalParmVarDecl::Create(Context, 0, SourceLocation(), 0,
Douglas Gregor23ce3a52009-04-13 22:18:37 +00001669 QualType(), QualType(), VarDecl::None,
1670 0);
Douglas Gregor23ce3a52009-04-13 22:18:37 +00001671 break;
1672 }
1673
Douglas Gregor2a491792009-04-13 22:49:25 +00001674 case pch::DECL_FILE_SCOPE_ASM: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001675 D = FileScopeAsmDecl::Create(Context, 0, SourceLocation(), 0);
Douglas Gregor2a491792009-04-13 22:49:25 +00001676 break;
1677 }
1678
1679 case pch::DECL_BLOCK: {
Douglas Gregorddf4d092009-04-16 22:29:51 +00001680 D = BlockDecl::Create(Context, 0, SourceLocation());
Douglas Gregor2a491792009-04-13 22:49:25 +00001681 break;
1682 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001683 }
1684
Douglas Gregorddf4d092009-04-16 22:29:51 +00001685 assert(D && "Unknown declaration creating PCH file");
1686 if (D) {
1687 LoadedDecl(Index, D);
1688 Reader.Visit(D);
1689 }
1690
Douglas Gregorc34897d2009-04-09 22:27:44 +00001691 // If this declaration is also a declaration context, get the
1692 // offsets for its tables of lexical and visible declarations.
1693 if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
1694 std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
1695 if (Offsets.first || Offsets.second) {
1696 DC->setHasExternalLexicalStorage(Offsets.first != 0);
1697 DC->setHasExternalVisibleStorage(Offsets.second != 0);
1698 DeclContextOffsets[DC] = Offsets;
1699 }
1700 }
1701 assert(Idx == Record.size());
1702
1703 return D;
1704}
1705
Douglas Gregorac8f2802009-04-10 17:25:41 +00001706QualType PCHReader::GetType(pch::TypeID ID) {
Douglas Gregorc34897d2009-04-09 22:27:44 +00001707 unsigned Quals = ID & 0x07;
1708 unsigned Index = ID >> 3;
1709
1710 if (Index < pch::NUM_PREDEF_TYPE_IDS) {
1711 QualType T;
1712 switch ((pch::PredefinedTypeIDs)Index) {
1713 case pch::PREDEF_TYPE_NULL_ID: return QualType();
1714 case pch::PREDEF_TYPE_VOID_ID: T = Context.VoidTy; break;
1715 case pch::PREDEF_TYPE_BOOL_ID: T = Context.BoolTy; break;
1716
1717 case pch::PREDEF_TYPE_CHAR_U_ID:
1718 case pch::PREDEF_TYPE_CHAR_S_ID:
1719 // FIXME: Check that the signedness of CharTy is correct!
1720 T = Context.CharTy;
1721 break;
1722
1723 case pch::PREDEF_TYPE_UCHAR_ID: T = Context.UnsignedCharTy; break;
1724 case pch::PREDEF_TYPE_USHORT_ID: T = Context.UnsignedShortTy; break;
1725 case pch::PREDEF_TYPE_UINT_ID: T = Context.UnsignedIntTy; break;
1726 case pch::PREDEF_TYPE_ULONG_ID: T = Context.UnsignedLongTy; break;
1727 case pch::PREDEF_TYPE_ULONGLONG_ID: T = Context.UnsignedLongLongTy; break;
1728 case pch::PREDEF_TYPE_SCHAR_ID: T = Context.SignedCharTy; break;
1729 case pch::PREDEF_TYPE_WCHAR_ID: T = Context.WCharTy; break;
1730 case pch::PREDEF_TYPE_SHORT_ID: T = Context.ShortTy; break;
1731 case pch::PREDEF_TYPE_INT_ID: T = Context.IntTy; break;
1732 case pch::PREDEF_TYPE_LONG_ID: T = Context.LongTy; break;
1733 case pch::PREDEF_TYPE_LONGLONG_ID: T = Context.LongLongTy; break;
1734 case pch::PREDEF_TYPE_FLOAT_ID: T = Context.FloatTy; break;
1735 case pch::PREDEF_TYPE_DOUBLE_ID: T = Context.DoubleTy; break;
1736 case pch::PREDEF_TYPE_LONGDOUBLE_ID: T = Context.LongDoubleTy; break;
1737 case pch::PREDEF_TYPE_OVERLOAD_ID: T = Context.OverloadTy; break;
1738 case pch::PREDEF_TYPE_DEPENDENT_ID: T = Context.DependentTy; break;
1739 }
1740
1741 assert(!T.isNull() && "Unknown predefined type");
1742 return T.getQualifiedType(Quals);
1743 }
1744
1745 Index -= pch::NUM_PREDEF_TYPE_IDS;
1746 if (!TypeAlreadyLoaded[Index]) {
1747 // Load the type from the PCH file.
1748 TypeOffsets[Index] = reinterpret_cast<uint64_t>(
1749 ReadTypeRecord(TypeOffsets[Index]).getTypePtr());
1750 TypeAlreadyLoaded[Index] = true;
1751 }
1752
1753 return QualType(reinterpret_cast<Type *>(TypeOffsets[Index]), Quals);
1754}
1755
Douglas Gregorac8f2802009-04-10 17:25:41 +00001756Decl *PCHReader::GetDecl(pch::DeclID ID) {
Douglas Gregorc34897d2009-04-09 22:27:44 +00001757 if (ID == 0)
1758 return 0;
1759
1760 unsigned Index = ID - 1;
1761 if (DeclAlreadyLoaded[Index])
1762 return reinterpret_cast<Decl *>(DeclOffsets[Index]);
1763
1764 // Load the declaration from the PCH file.
1765 return ReadDeclRecord(DeclOffsets[Index], Index);
1766}
1767
1768bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
Douglas Gregorac8f2802009-04-10 17:25:41 +00001769 llvm::SmallVectorImpl<pch::DeclID> &Decls) {
Douglas Gregorc34897d2009-04-09 22:27:44 +00001770 assert(DC->hasExternalLexicalStorage() &&
1771 "DeclContext has no lexical decls in storage");
1772 uint64_t Offset = DeclContextOffsets[DC].first;
1773 assert(Offset && "DeclContext has no lexical decls in storage");
1774
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001775 // Keep track of where we are in the stream, then jump back there
1776 // after reading this context.
1777 SavedStreamPosition SavedPosition(Stream);
1778
Douglas Gregorc34897d2009-04-09 22:27:44 +00001779 // Load the record containing all of the declarations lexically in
1780 // this context.
1781 Stream.JumpToBit(Offset);
1782 RecordData Record;
1783 unsigned Code = Stream.ReadCode();
1784 unsigned RecCode = Stream.ReadRecord(Code, Record);
Douglas Gregor3c8ff3e2009-04-15 18:43:11 +00001785 (void)RecCode;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001786 assert(RecCode == pch::DECL_CONTEXT_LEXICAL && "Expected lexical block");
1787
1788 // Load all of the declaration IDs
1789 Decls.clear();
1790 Decls.insert(Decls.end(), Record.begin(), Record.end());
1791 return false;
1792}
1793
1794bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
1795 llvm::SmallVectorImpl<VisibleDeclaration> & Decls) {
1796 assert(DC->hasExternalVisibleStorage() &&
1797 "DeclContext has no visible decls in storage");
1798 uint64_t Offset = DeclContextOffsets[DC].second;
1799 assert(Offset && "DeclContext has no visible decls in storage");
1800
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001801 // Keep track of where we are in the stream, then jump back there
1802 // after reading this context.
1803 SavedStreamPosition SavedPosition(Stream);
1804
Douglas Gregorc34897d2009-04-09 22:27:44 +00001805 // Load the record containing all of the declarations visible in
1806 // this context.
1807 Stream.JumpToBit(Offset);
1808 RecordData Record;
1809 unsigned Code = Stream.ReadCode();
1810 unsigned RecCode = Stream.ReadRecord(Code, Record);
Douglas Gregor3c8ff3e2009-04-15 18:43:11 +00001811 (void)RecCode;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001812 assert(RecCode == pch::DECL_CONTEXT_VISIBLE && "Expected visible block");
1813 if (Record.size() == 0)
1814 return false;
1815
1816 Decls.clear();
1817
1818 unsigned Idx = 0;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001819 while (Idx < Record.size()) {
1820 Decls.push_back(VisibleDeclaration());
1821 Decls.back().Name = ReadDeclarationName(Record, Idx);
1822
Douglas Gregorc34897d2009-04-09 22:27:44 +00001823 unsigned Size = Record[Idx++];
1824 llvm::SmallVector<unsigned, 4> & LoadedDecls
1825 = Decls.back().Declarations;
1826 LoadedDecls.reserve(Size);
1827 for (unsigned I = 0; I < Size; ++I)
1828 LoadedDecls.push_back(Record[Idx++]);
1829 }
1830
1831 return false;
1832}
1833
Douglas Gregor631f6c62009-04-14 00:24:19 +00001834void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
1835 if (!Consumer)
1836 return;
1837
1838 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
1839 Decl *D = GetDecl(ExternalDefinitions[I]);
1840 DeclGroupRef DG(D);
1841 Consumer->HandleTopLevelDecl(DG);
1842 }
1843}
1844
Douglas Gregorc34897d2009-04-09 22:27:44 +00001845void PCHReader::PrintStats() {
1846 std::fprintf(stderr, "*** PCH Statistics:\n");
1847
1848 unsigned NumTypesLoaded = std::count(TypeAlreadyLoaded.begin(),
1849 TypeAlreadyLoaded.end(),
1850 true);
1851 unsigned NumDeclsLoaded = std::count(DeclAlreadyLoaded.begin(),
1852 DeclAlreadyLoaded.end(),
1853 true);
Douglas Gregor9cf47422009-04-13 20:50:16 +00001854 unsigned NumIdentifiersLoaded = 0;
1855 for (unsigned I = 0; I < IdentifierData.size(); ++I) {
1856 if ((IdentifierData[I] & 0x01) == 0)
1857 ++NumIdentifiersLoaded;
1858 }
1859
Douglas Gregorc34897d2009-04-09 22:27:44 +00001860 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
1861 NumTypesLoaded, (unsigned)TypeAlreadyLoaded.size(),
Douglas Gregor9cf47422009-04-13 20:50:16 +00001862 ((float)NumTypesLoaded/TypeAlreadyLoaded.size() * 100));
Douglas Gregorc34897d2009-04-09 22:27:44 +00001863 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
1864 NumDeclsLoaded, (unsigned)DeclAlreadyLoaded.size(),
Douglas Gregor9cf47422009-04-13 20:50:16 +00001865 ((float)NumDeclsLoaded/DeclAlreadyLoaded.size() * 100));
1866 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
1867 NumIdentifiersLoaded, (unsigned)IdentifierData.size(),
1868 ((float)NumIdentifiersLoaded/IdentifierData.size() * 100));
Douglas Gregorc34897d2009-04-09 22:27:44 +00001869 std::fprintf(stderr, "\n");
1870}
1871
Chris Lattner29241862009-04-11 21:15:38 +00001872IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001873 if (ID == 0)
1874 return 0;
Chris Lattner29241862009-04-11 21:15:38 +00001875
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001876 if (!IdentifierTable || IdentifierData.empty()) {
1877 Error("No identifier table in PCH file");
1878 return 0;
1879 }
Chris Lattner29241862009-04-11 21:15:38 +00001880
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001881 if (IdentifierData[ID - 1] & 0x01) {
1882 uint64_t Offset = IdentifierData[ID - 1];
1883 IdentifierData[ID - 1] = reinterpret_cast<uint64_t>(
Chris Lattner29241862009-04-11 21:15:38 +00001884 &Context.Idents.get(IdentifierTable + Offset));
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001885 }
Chris Lattner29241862009-04-11 21:15:38 +00001886
1887 return reinterpret_cast<IdentifierInfo *>(IdentifierData[ID - 1]);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001888}
1889
1890DeclarationName
1891PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
1892 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
1893 switch (Kind) {
1894 case DeclarationName::Identifier:
1895 return DeclarationName(GetIdentifierInfo(Record, Idx));
1896
1897 case DeclarationName::ObjCZeroArgSelector:
1898 case DeclarationName::ObjCOneArgSelector:
1899 case DeclarationName::ObjCMultiArgSelector:
1900 assert(false && "Unable to de-serialize Objective-C selectors");
1901 break;
1902
1903 case DeclarationName::CXXConstructorName:
1904 return Context.DeclarationNames.getCXXConstructorName(
1905 GetType(Record[Idx++]));
1906
1907 case DeclarationName::CXXDestructorName:
1908 return Context.DeclarationNames.getCXXDestructorName(
1909 GetType(Record[Idx++]));
1910
1911 case DeclarationName::CXXConversionFunctionName:
1912 return Context.DeclarationNames.getCXXConversionFunctionName(
1913 GetType(Record[Idx++]));
1914
1915 case DeclarationName::CXXOperatorName:
1916 return Context.DeclarationNames.getCXXOperatorName(
1917 (OverloadedOperatorKind)Record[Idx++]);
1918
1919 case DeclarationName::CXXUsingDirective:
1920 return DeclarationName::getUsingDirectiveName();
1921 }
1922
1923 // Required to silence GCC warning
1924 return DeclarationName();
1925}
Douglas Gregor179cfb12009-04-10 20:39:37 +00001926
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001927/// \brief Read an integral value
1928llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
1929 unsigned BitWidth = Record[Idx++];
1930 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
1931 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
1932 Idx += NumWords;
1933 return Result;
1934}
1935
1936/// \brief Read a signed integral value
1937llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
1938 bool isUnsigned = Record[Idx++];
1939 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
1940}
1941
Douglas Gregore2f37202009-04-14 21:55:33 +00001942/// \brief Read a floating-point value
1943llvm::APFloat PCHReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregore2f37202009-04-14 21:55:33 +00001944 return llvm::APFloat(ReadAPInt(Record, Idx));
1945}
1946
Douglas Gregor1c507882009-04-15 21:30:51 +00001947// \brief Read a string
1948std::string PCHReader::ReadString(const RecordData &Record, unsigned &Idx) {
1949 unsigned Len = Record[Idx++];
1950 std::string Result(&Record[Idx], &Record[Idx] + Len);
1951 Idx += Len;
1952 return Result;
1953}
1954
1955/// \brief Reads attributes from the current stream position.
1956Attr *PCHReader::ReadAttributes() {
1957 unsigned Code = Stream.ReadCode();
1958 assert(Code == llvm::bitc::UNABBREV_RECORD &&
1959 "Expected unabbreviated record"); (void)Code;
1960
1961 RecordData Record;
1962 unsigned Idx = 0;
1963 unsigned RecCode = Stream.ReadRecord(Code, Record);
1964 assert(RecCode == pch::DECL_ATTR && "Expected attribute record");
1965 (void)RecCode;
1966
1967#define SIMPLE_ATTR(Name) \
1968 case Attr::Name: \
1969 New = ::new (Context) Name##Attr(); \
1970 break
1971
1972#define STRING_ATTR(Name) \
1973 case Attr::Name: \
1974 New = ::new (Context) Name##Attr(ReadString(Record, Idx)); \
1975 break
1976
1977#define UNSIGNED_ATTR(Name) \
1978 case Attr::Name: \
1979 New = ::new (Context) Name##Attr(Record[Idx++]); \
1980 break
1981
1982 Attr *Attrs = 0;
1983 while (Idx < Record.size()) {
1984 Attr *New = 0;
1985 Attr::Kind Kind = (Attr::Kind)Record[Idx++];
1986 bool IsInherited = Record[Idx++];
1987
1988 switch (Kind) {
1989 STRING_ATTR(Alias);
1990 UNSIGNED_ATTR(Aligned);
1991 SIMPLE_ATTR(AlwaysInline);
1992 SIMPLE_ATTR(AnalyzerNoReturn);
1993 STRING_ATTR(Annotate);
1994 STRING_ATTR(AsmLabel);
1995
1996 case Attr::Blocks:
1997 New = ::new (Context) BlocksAttr(
1998 (BlocksAttr::BlocksAttrTypes)Record[Idx++]);
1999 break;
2000
2001 case Attr::Cleanup:
2002 New = ::new (Context) CleanupAttr(
2003 cast<FunctionDecl>(GetDecl(Record[Idx++])));
2004 break;
2005
2006 SIMPLE_ATTR(Const);
2007 UNSIGNED_ATTR(Constructor);
2008 SIMPLE_ATTR(DLLExport);
2009 SIMPLE_ATTR(DLLImport);
2010 SIMPLE_ATTR(Deprecated);
2011 UNSIGNED_ATTR(Destructor);
2012 SIMPLE_ATTR(FastCall);
2013
2014 case Attr::Format: {
2015 std::string Type = ReadString(Record, Idx);
2016 unsigned FormatIdx = Record[Idx++];
2017 unsigned FirstArg = Record[Idx++];
2018 New = ::new (Context) FormatAttr(Type, FormatIdx, FirstArg);
2019 break;
2020 }
2021
2022 SIMPLE_ATTR(GNUCInline);
2023
2024 case Attr::IBOutletKind:
2025 New = ::new (Context) IBOutletAttr();
2026 break;
2027
2028 SIMPLE_ATTR(NoReturn);
2029 SIMPLE_ATTR(NoThrow);
2030 SIMPLE_ATTR(Nodebug);
2031 SIMPLE_ATTR(Noinline);
2032
2033 case Attr::NonNull: {
2034 unsigned Size = Record[Idx++];
2035 llvm::SmallVector<unsigned, 16> ArgNums;
2036 ArgNums.insert(ArgNums.end(), &Record[Idx], &Record[Idx] + Size);
2037 Idx += Size;
2038 New = ::new (Context) NonNullAttr(&ArgNums[0], Size);
2039 break;
2040 }
2041
2042 SIMPLE_ATTR(ObjCException);
2043 SIMPLE_ATTR(ObjCNSObject);
2044 SIMPLE_ATTR(Overloadable);
2045 UNSIGNED_ATTR(Packed);
2046 SIMPLE_ATTR(Pure);
2047 UNSIGNED_ATTR(Regparm);
2048 STRING_ATTR(Section);
2049 SIMPLE_ATTR(StdCall);
2050 SIMPLE_ATTR(TransparentUnion);
2051 SIMPLE_ATTR(Unavailable);
2052 SIMPLE_ATTR(Unused);
2053 SIMPLE_ATTR(Used);
2054
2055 case Attr::Visibility:
2056 New = ::new (Context) VisibilityAttr(
2057 (VisibilityAttr::VisibilityTypes)Record[Idx++]);
2058 break;
2059
2060 SIMPLE_ATTR(WarnUnusedResult);
2061 SIMPLE_ATTR(Weak);
2062 SIMPLE_ATTR(WeakImport);
2063 }
2064
2065 assert(New && "Unable to decode attribute?");
2066 New->setInherited(IsInherited);
2067 New->setNext(Attrs);
2068 Attrs = New;
2069 }
2070#undef UNSIGNED_ATTR
2071#undef STRING_ATTR
2072#undef SIMPLE_ATTR
2073
2074 // The list of attributes was built backwards. Reverse the list
2075 // before returning it.
2076 Attr *PrevAttr = 0, *NextAttr = 0;
2077 while (Attrs) {
2078 NextAttr = Attrs->getNext();
2079 Attrs->setNext(PrevAttr);
2080 PrevAttr = Attrs;
2081 Attrs = NextAttr;
2082 }
2083
2084 return PrevAttr;
2085}
2086
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002087Stmt *PCHReader::ReadStmt() {
Douglas Gregora151ba42009-04-14 23:32:43 +00002088 // Within the bitstream, expressions are stored in Reverse Polish
2089 // Notation, with each of the subexpressions preceding the
2090 // expression they are stored in. To evaluate expressions, we
2091 // continue reading expressions and placing them on the stack, with
2092 // expressions having operands removing those operands from the
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002093 // stack. Evaluation terminates when we see a STMT_STOP record, and
Douglas Gregora151ba42009-04-14 23:32:43 +00002094 // the single remaining expression on the stack is our result.
Douglas Gregorc10f86f2009-04-14 21:18:50 +00002095 RecordData Record;
Douglas Gregora151ba42009-04-14 23:32:43 +00002096 unsigned Idx;
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002097 llvm::SmallVector<Stmt *, 16> StmtStack;
2098 PCHStmtReader Reader(*this, Record, Idx, StmtStack);
Douglas Gregorc10f86f2009-04-14 21:18:50 +00002099 Stmt::EmptyShell Empty;
2100
Douglas Gregora151ba42009-04-14 23:32:43 +00002101 while (true) {
2102 unsigned Code = Stream.ReadCode();
2103 if (Code == llvm::bitc::END_BLOCK) {
2104 if (Stream.ReadBlockEnd()) {
2105 Error("Error at end of Source Manager block");
2106 return 0;
2107 }
2108 break;
2109 }
Douglas Gregorc10f86f2009-04-14 21:18:50 +00002110
Douglas Gregora151ba42009-04-14 23:32:43 +00002111 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
2112 // No known subblocks, always skip them.
2113 Stream.ReadSubBlockID();
2114 if (Stream.SkipBlock()) {
2115 Error("Malformed block record");
2116 return 0;
2117 }
2118 continue;
2119 }
Douglas Gregore2f37202009-04-14 21:55:33 +00002120
Douglas Gregora151ba42009-04-14 23:32:43 +00002121 if (Code == llvm::bitc::DEFINE_ABBREV) {
2122 Stream.ReadAbbrevRecord();
2123 continue;
2124 }
Douglas Gregorc10f86f2009-04-14 21:18:50 +00002125
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002126 Stmt *S = 0;
Douglas Gregora151ba42009-04-14 23:32:43 +00002127 Idx = 0;
2128 Record.clear();
2129 bool Finished = false;
2130 switch ((pch::StmtCode)Stream.ReadRecord(Code, Record)) {
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002131 case pch::STMT_STOP:
Douglas Gregora151ba42009-04-14 23:32:43 +00002132 Finished = true;
2133 break;
Douglas Gregorc10f86f2009-04-14 21:18:50 +00002134
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002135 case pch::STMT_NULL_PTR:
2136 S = 0;
Douglas Gregora151ba42009-04-14 23:32:43 +00002137 break;
Douglas Gregorc10f86f2009-04-14 21:18:50 +00002138
Douglas Gregor9c4782a2009-04-17 00:04:06 +00002139 case pch::STMT_NULL:
2140 S = new (Context) NullStmt(Empty);
2141 break;
2142
2143 case pch::STMT_COMPOUND:
2144 S = new (Context) CompoundStmt(Empty);
2145 break;
2146
2147 case pch::STMT_CASE:
2148 S = new (Context) CaseStmt(Empty);
2149 break;
2150
2151 case pch::STMT_DEFAULT:
2152 S = new (Context) DefaultStmt(Empty);
2153 break;
2154
2155 case pch::STMT_IF:
2156 S = new (Context) IfStmt(Empty);
2157 break;
2158
2159 case pch::STMT_SWITCH:
2160 S = new (Context) SwitchStmt(Empty);
2161 break;
2162
Douglas Gregora6b503f2009-04-17 00:16:09 +00002163 case pch::STMT_WHILE:
2164 S = new (Context) WhileStmt(Empty);
2165 break;
2166
Douglas Gregorfb5f25b2009-04-17 00:29:51 +00002167 case pch::STMT_DO:
2168 S = new (Context) DoStmt(Empty);
2169 break;
2170
2171 case pch::STMT_FOR:
2172 S = new (Context) ForStmt(Empty);
2173 break;
2174
Douglas Gregora6b503f2009-04-17 00:16:09 +00002175 case pch::STMT_CONTINUE:
2176 S = new (Context) ContinueStmt(Empty);
2177 break;
2178
Douglas Gregor9c4782a2009-04-17 00:04:06 +00002179 case pch::STMT_BREAK:
2180 S = new (Context) BreakStmt(Empty);
2181 break;
2182
Douglas Gregor22d2dcd2009-04-17 16:34:57 +00002183 case pch::STMT_RETURN:
2184 S = new (Context) ReturnStmt(Empty);
2185 break;
2186
Douglas Gregora151ba42009-04-14 23:32:43 +00002187 case pch::EXPR_PREDEFINED:
2188 // FIXME: untested (until we can serialize function bodies).
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002189 S = new (Context) PredefinedExpr(Empty);
Douglas Gregora151ba42009-04-14 23:32:43 +00002190 break;
2191
2192 case pch::EXPR_DECL_REF:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002193 S = new (Context) DeclRefExpr(Empty);
Douglas Gregora151ba42009-04-14 23:32:43 +00002194 break;
2195
2196 case pch::EXPR_INTEGER_LITERAL:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002197 S = new (Context) IntegerLiteral(Empty);
Douglas Gregora151ba42009-04-14 23:32:43 +00002198 break;
2199
2200 case pch::EXPR_FLOATING_LITERAL:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002201 S = new (Context) FloatingLiteral(Empty);
Douglas Gregora151ba42009-04-14 23:32:43 +00002202 break;
2203
Douglas Gregor21ddd8c2009-04-15 22:19:53 +00002204 case pch::EXPR_IMAGINARY_LITERAL:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002205 S = new (Context) ImaginaryLiteral(Empty);
Douglas Gregor21ddd8c2009-04-15 22:19:53 +00002206 break;
2207
Douglas Gregor596e0932009-04-15 16:35:07 +00002208 case pch::EXPR_STRING_LITERAL:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002209 S = StringLiteral::CreateEmpty(Context,
Douglas Gregor596e0932009-04-15 16:35:07 +00002210 Record[PCHStmtReader::NumExprFields + 1]);
2211 break;
2212
Douglas Gregora151ba42009-04-14 23:32:43 +00002213 case pch::EXPR_CHARACTER_LITERAL:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002214 S = new (Context) CharacterLiteral(Empty);
Douglas Gregora151ba42009-04-14 23:32:43 +00002215 break;
2216
Douglas Gregor4ea0b1f2009-04-14 23:59:37 +00002217 case pch::EXPR_PAREN:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002218 S = new (Context) ParenExpr(Empty);
Douglas Gregor4ea0b1f2009-04-14 23:59:37 +00002219 break;
2220
Douglas Gregor12d74052009-04-15 15:58:59 +00002221 case pch::EXPR_UNARY_OPERATOR:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002222 S = new (Context) UnaryOperator(Empty);
Douglas Gregor12d74052009-04-15 15:58:59 +00002223 break;
2224
2225 case pch::EXPR_SIZEOF_ALIGN_OF:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002226 S = new (Context) SizeOfAlignOfExpr(Empty);
Douglas Gregor12d74052009-04-15 15:58:59 +00002227 break;
2228
Douglas Gregor21ddd8c2009-04-15 22:19:53 +00002229 case pch::EXPR_ARRAY_SUBSCRIPT:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002230 S = new (Context) ArraySubscriptExpr(Empty);
Douglas Gregor21ddd8c2009-04-15 22:19:53 +00002231 break;
2232
Douglas Gregor7e2b1cd2009-04-15 17:43:59 +00002233 case pch::EXPR_CALL:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002234 S = new (Context) CallExpr(Context, Empty);
Douglas Gregor7e2b1cd2009-04-15 17:43:59 +00002235 break;
2236
2237 case pch::EXPR_MEMBER:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002238 S = new (Context) MemberExpr(Empty);
Douglas Gregor7e2b1cd2009-04-15 17:43:59 +00002239 break;
2240
Douglas Gregorc75d0cb2009-04-15 00:25:59 +00002241 case pch::EXPR_BINARY_OPERATOR:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002242 S = new (Context) BinaryOperator(Empty);
Douglas Gregorc75d0cb2009-04-15 00:25:59 +00002243 break;
2244
Douglas Gregorc599bbf2009-04-15 22:40:36 +00002245 case pch::EXPR_COMPOUND_ASSIGN_OPERATOR:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002246 S = new (Context) CompoundAssignOperator(Empty);
Douglas Gregorc599bbf2009-04-15 22:40:36 +00002247 break;
2248
2249 case pch::EXPR_CONDITIONAL_OPERATOR:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002250 S = new (Context) ConditionalOperator(Empty);
Douglas Gregorc599bbf2009-04-15 22:40:36 +00002251 break;
2252
Douglas Gregora151ba42009-04-14 23:32:43 +00002253 case pch::EXPR_IMPLICIT_CAST:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002254 S = new (Context) ImplicitCastExpr(Empty);
Douglas Gregora151ba42009-04-14 23:32:43 +00002255 break;
Douglas Gregorc75d0cb2009-04-15 00:25:59 +00002256
2257 case pch::EXPR_CSTYLE_CAST:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002258 S = new (Context) CStyleCastExpr(Empty);
Douglas Gregorc75d0cb2009-04-15 00:25:59 +00002259 break;
Douglas Gregorec0b8292009-04-15 23:02:49 +00002260
Douglas Gregorb70b48f2009-04-16 02:33:48 +00002261 case pch::EXPR_COMPOUND_LITERAL:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002262 S = new (Context) CompoundLiteralExpr(Empty);
Douglas Gregorb70b48f2009-04-16 02:33:48 +00002263 break;
2264
Douglas Gregorec0b8292009-04-15 23:02:49 +00002265 case pch::EXPR_EXT_VECTOR_ELEMENT:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002266 S = new (Context) ExtVectorElementExpr(Empty);
Douglas Gregorec0b8292009-04-15 23:02:49 +00002267 break;
2268
Douglas Gregor6710a3c2009-04-16 00:55:48 +00002269 case pch::EXPR_INIT_LIST:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002270 S = new (Context) InitListExpr(Empty);
Douglas Gregor6710a3c2009-04-16 00:55:48 +00002271 break;
2272
2273 case pch::EXPR_DESIGNATED_INIT:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002274 S = DesignatedInitExpr::CreateEmpty(Context,
Douglas Gregor6710a3c2009-04-16 00:55:48 +00002275 Record[PCHStmtReader::NumExprFields] - 1);
2276
2277 break;
2278
2279 case pch::EXPR_IMPLICIT_VALUE_INIT:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002280 S = new (Context) ImplicitValueInitExpr(Empty);
Douglas Gregor6710a3c2009-04-16 00:55:48 +00002281 break;
2282
Douglas Gregorec0b8292009-04-15 23:02:49 +00002283 case pch::EXPR_VA_ARG:
2284 // FIXME: untested; we need function bodies first
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002285 S = new (Context) VAArgExpr(Empty);
Douglas Gregorec0b8292009-04-15 23:02:49 +00002286 break;
Douglas Gregor209d4622009-04-15 23:33:31 +00002287
2288 case pch::EXPR_TYPES_COMPATIBLE:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002289 S = new (Context) TypesCompatibleExpr(Empty);
Douglas Gregor209d4622009-04-15 23:33:31 +00002290 break;
2291
2292 case pch::EXPR_CHOOSE:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002293 S = new (Context) ChooseExpr(Empty);
Douglas Gregor209d4622009-04-15 23:33:31 +00002294 break;
2295
2296 case pch::EXPR_GNU_NULL:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002297 S = new (Context) GNUNullExpr(Empty);
Douglas Gregor209d4622009-04-15 23:33:31 +00002298 break;
Douglas Gregor725e94b2009-04-16 00:01:45 +00002299
2300 case pch::EXPR_SHUFFLE_VECTOR:
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002301 S = new (Context) ShuffleVectorExpr(Empty);
Douglas Gregor725e94b2009-04-16 00:01:45 +00002302 break;
2303
2304 case pch::EXPR_BLOCK_DECL_REF:
2305 // FIXME: untested until we have statement and block support
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002306 S = new (Context) BlockDeclRefExpr(Empty);
Douglas Gregor725e94b2009-04-16 00:01:45 +00002307 break;
Douglas Gregora151ba42009-04-14 23:32:43 +00002308 }
2309
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002310 // We hit a STMT_STOP, so we're done with this expression.
Douglas Gregora151ba42009-04-14 23:32:43 +00002311 if (Finished)
2312 break;
2313
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002314 if (S) {
2315 unsigned NumSubStmts = Reader.Visit(S);
2316 while (NumSubStmts > 0) {
2317 StmtStack.pop_back();
2318 --NumSubStmts;
Douglas Gregora151ba42009-04-14 23:32:43 +00002319 }
2320 }
2321
2322 assert(Idx == Record.size() && "Invalid deserialization of expression");
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002323 StmtStack.push_back(S);
Douglas Gregorc10f86f2009-04-14 21:18:50 +00002324 }
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002325 assert(StmtStack.size() == 1 && "Extra expressions on stack!");
Douglas Gregor22d2dcd2009-04-17 16:34:57 +00002326 SwitchCaseStmts.clear();
Douglas Gregorc72f6c82009-04-16 22:23:12 +00002327 return StmtStack.back();
2328}
2329
2330Expr *PCHReader::ReadExpr() {
2331 return dyn_cast_or_null<Expr>(ReadStmt());
Douglas Gregorc10f86f2009-04-14 21:18:50 +00002332}
2333
Douglas Gregor179cfb12009-04-10 20:39:37 +00002334DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
Douglas Gregorb3a04c82009-04-10 23:10:45 +00002335 return Diag(SourceLocation(), DiagID);
2336}
2337
2338DiagnosticBuilder PCHReader::Diag(SourceLocation Loc, unsigned DiagID) {
2339 return PP.getDiagnostics().Report(FullSourceLoc(Loc,
Douglas Gregor179cfb12009-04-10 20:39:37 +00002340 Context.getSourceManager()),
2341 DiagID);
2342}
Douglas Gregor9c4782a2009-04-17 00:04:06 +00002343
2344/// \brief Record that the given ID maps to the given switch-case
2345/// statement.
2346void PCHReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
2347 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
2348 SwitchCaseStmts[ID] = SC;
2349}
2350
2351/// \brief Retrieve the switch-case statement with the given ID.
2352SwitchCase *PCHReader::getSwitchCaseWithID(unsigned ID) {
2353 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
2354 return SwitchCaseStmts[ID];
2355}