blob: 64929dcb1db99cc6f3dcec102dda1c7b8d6210f7 [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//===----------------------------------------------------------------------===//
Chris Lattner09547942009-04-27 05:14:47 +000013
Douglas Gregorc34897d2009-04-09 22:27:44 +000014#include "clang/Frontend/PCHReader.h"
Douglas Gregor179cfb12009-04-10 20:39:37 +000015#include "clang/Frontend/FrontendDiagnostic.h"
Douglas Gregorc713da92009-04-21 22:25:48 +000016#include "../Sema/Sema.h" // FIXME: move Sema headers elsewhere
Douglas Gregor631f6c62009-04-14 00:24:19 +000017#include "clang/AST/ASTConsumer.h"
Douglas Gregorc34897d2009-04-09 22:27:44 +000018#include "clang/AST/ASTContext.h"
Douglas Gregorc10f86f2009-04-14 21:18:50 +000019#include "clang/AST/Expr.h"
Douglas Gregorc34897d2009-04-09 22:27:44 +000020#include "clang/AST/Type.h"
Chris Lattnerdb1c81b2009-04-10 21:41:48 +000021#include "clang/Lex/MacroInfo.h"
Douglas Gregorab1cef72009-04-10 03:52:48 +000022#include "clang/Lex/Preprocessor.h"
Steve Naroffcda68f22009-04-24 20:03:17 +000023#include "clang/Lex/HeaderSearch.h"
Douglas Gregorc713da92009-04-21 22:25:48 +000024#include "clang/Basic/OnDiskHashTable.h"
Douglas Gregorab1cef72009-04-10 03:52:48 +000025#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>
Douglas Gregor32de6312009-04-28 18:58:38 +000033#include <iterator>
Douglas Gregorc34897d2009-04-09 22:27:44 +000034#include <cstdio>
Douglas Gregor6cc5d192009-04-27 18:38:38 +000035#include <sys/stat.h>
Douglas Gregorc34897d2009-04-09 22:27:44 +000036using namespace clang;
37
38//===----------------------------------------------------------------------===//
Douglas Gregorc713da92009-04-21 22:25:48 +000039// PCH reader implementation
40//===----------------------------------------------------------------------===//
41
Chris Lattner270d29a2009-04-27 21:45:14 +000042PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context)
Chris Lattner09547942009-04-27 05:14:47 +000043 : SemaObj(0), PP(PP), Context(Context), Consumer(0),
44 IdentifierTableData(0), IdentifierLookupTable(0),
45 IdentifierOffsets(0),
46 MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
47 TotalSelectorsInMethodPool(0), SelectorOffsets(0),
Douglas Gregor6cc5d192009-04-27 18:38:38 +000048 TotalNumSelectors(0), NumStatHits(0), NumStatMisses(0),
49 NumSLocEntriesRead(0), NumStatementsRead(0),
Douglas Gregor32e231c2009-04-27 06:38:32 +000050 NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
Chris Lattner09547942009-04-27 05:14:47 +000051 NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0) { }
52
53PCHReader::~PCHReader() {}
54
Chris Lattner3ef21962009-04-27 05:58:23 +000055Expr *PCHReader::ReadDeclExpr() {
56 return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
57}
58
59Expr *PCHReader::ReadTypeExpr() {
Chris Lattner3282c392009-04-27 05:41:06 +000060 return dyn_cast_or_null<Expr>(ReadStmt(Stream));
Chris Lattner09547942009-04-27 05:14:47 +000061}
62
63
Douglas Gregorc713da92009-04-21 22:25:48 +000064namespace {
Douglas Gregorc3221aa2009-04-24 21:10:55 +000065class VISIBILITY_HIDDEN PCHMethodPoolLookupTrait {
66 PCHReader &Reader;
67
68public:
69 typedef std::pair<ObjCMethodList, ObjCMethodList> data_type;
70
71 typedef Selector external_key_type;
72 typedef external_key_type internal_key_type;
73
74 explicit PCHMethodPoolLookupTrait(PCHReader &Reader) : Reader(Reader) { }
75
76 static bool EqualKey(const internal_key_type& a,
77 const internal_key_type& b) {
78 return a == b;
79 }
80
81 static unsigned ComputeHash(Selector Sel) {
82 unsigned N = Sel.getNumArgs();
83 if (N == 0)
84 ++N;
85 unsigned R = 5381;
86 for (unsigned I = 0; I != N; ++I)
87 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
88 R = clang::BernsteinHashPartial(II->getName(), II->getLength(), R);
89 return R;
90 }
91
92 // This hopefully will just get inlined and removed by the optimizer.
93 static const internal_key_type&
94 GetInternalKey(const external_key_type& x) { return x; }
95
96 static std::pair<unsigned, unsigned>
97 ReadKeyDataLength(const unsigned char*& d) {
98 using namespace clang::io;
99 unsigned KeyLen = ReadUnalignedLE16(d);
100 unsigned DataLen = ReadUnalignedLE16(d);
101 return std::make_pair(KeyLen, DataLen);
102 }
103
Douglas Gregor2d711832009-04-25 17:48:32 +0000104 internal_key_type ReadKey(const unsigned char* d, unsigned) {
Douglas Gregorc3221aa2009-04-24 21:10:55 +0000105 using namespace clang::io;
Chris Lattner270d29a2009-04-27 21:45:14 +0000106 SelectorTable &SelTable = Reader.getContext()->Selectors;
Douglas Gregorc3221aa2009-04-24 21:10:55 +0000107 unsigned N = ReadUnalignedLE16(d);
108 IdentifierInfo *FirstII
109 = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
110 if (N == 0)
111 return SelTable.getNullarySelector(FirstII);
112 else if (N == 1)
113 return SelTable.getUnarySelector(FirstII);
114
115 llvm::SmallVector<IdentifierInfo *, 16> Args;
116 Args.push_back(FirstII);
117 for (unsigned I = 1; I != N; ++I)
118 Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
119
120 return SelTable.getSelector(N, &Args[0]);
121 }
122
123 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
124 using namespace clang::io;
125 unsigned NumInstanceMethods = ReadUnalignedLE16(d);
126 unsigned NumFactoryMethods = ReadUnalignedLE16(d);
127
128 data_type Result;
129
130 // Load instance methods
131 ObjCMethodList *Prev = 0;
132 for (unsigned I = 0; I != NumInstanceMethods; ++I) {
133 ObjCMethodDecl *Method
134 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
135 if (!Result.first.Method) {
136 // This is the first method, which is the easy case.
137 Result.first.Method = Method;
138 Prev = &Result.first;
139 continue;
140 }
141
142 Prev->Next = new ObjCMethodList(Method, 0);
143 Prev = Prev->Next;
144 }
145
146 // Load factory methods
147 Prev = 0;
148 for (unsigned I = 0; I != NumFactoryMethods; ++I) {
149 ObjCMethodDecl *Method
150 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
151 if (!Result.second.Method) {
152 // This is the first method, which is the easy case.
153 Result.second.Method = Method;
154 Prev = &Result.second;
155 continue;
156 }
157
158 Prev->Next = new ObjCMethodList(Method, 0);
159 Prev = Prev->Next;
160 }
161
162 return Result;
163 }
164};
165
166} // end anonymous namespace
167
168/// \brief The on-disk hash table used for the global method pool.
169typedef OnDiskChainedHashTable<PCHMethodPoolLookupTrait>
170 PCHMethodPoolLookupTable;
171
172namespace {
Douglas Gregorc713da92009-04-21 22:25:48 +0000173class VISIBILITY_HIDDEN PCHIdentifierLookupTrait {
174 PCHReader &Reader;
175
176 // If we know the IdentifierInfo in advance, it is here and we will
177 // not build a new one. Used when deserializing information about an
178 // identifier that was constructed before the PCH file was read.
179 IdentifierInfo *KnownII;
180
181public:
182 typedef IdentifierInfo * data_type;
183
184 typedef const std::pair<const char*, unsigned> external_key_type;
185
186 typedef external_key_type internal_key_type;
187
188 explicit PCHIdentifierLookupTrait(PCHReader &Reader, IdentifierInfo *II = 0)
189 : Reader(Reader), KnownII(II) { }
190
191 static bool EqualKey(const internal_key_type& a,
192 const internal_key_type& b) {
193 return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
194 : false;
195 }
196
197 static unsigned ComputeHash(const internal_key_type& a) {
198 return BernsteinHash(a.first, a.second);
199 }
200
201 // This hopefully will just get inlined and removed by the optimizer.
202 static const internal_key_type&
203 GetInternalKey(const external_key_type& x) { return x; }
204
205 static std::pair<unsigned, unsigned>
206 ReadKeyDataLength(const unsigned char*& d) {
207 using namespace clang::io;
Douglas Gregor4bb24882009-04-25 20:26:24 +0000208 unsigned DataLen = ReadUnalignedLE16(d);
Douglas Gregor85c4a872009-04-25 21:04:17 +0000209 unsigned KeyLen = ReadUnalignedLE16(d);
Douglas Gregorc713da92009-04-21 22:25:48 +0000210 return std::make_pair(KeyLen, DataLen);
211 }
212
213 static std::pair<const char*, unsigned>
214 ReadKey(const unsigned char* d, unsigned n) {
215 assert(n >= 2 && d[n-1] == '\0');
216 return std::make_pair((const char*) d, n-1);
217 }
218
219 IdentifierInfo *ReadData(const internal_key_type& k,
220 const unsigned char* d,
221 unsigned DataLen) {
222 using namespace clang::io;
Douglas Gregor2c09dad2009-04-28 21:18:29 +0000223 pch::IdentID ID = ReadUnalignedLE32(d);
224 bool IsInteresting = ID & 0x01;
225
226 // Wipe out the "is interesting" bit.
227 ID = ID >> 1;
228
229 if (!IsInteresting) {
230 // For unintersting identifiers, just build the IdentifierInfo
231 // and associate it with the persistent ID.
232 IdentifierInfo *II = KnownII;
233 if (!II)
234 II = &Reader.getIdentifierTable().CreateIdentifierInfo(
235 k.first, k.first + k.second);
236 Reader.SetIdentifierInfo(ID, II);
237 return II;
238 }
239
Douglas Gregor2554cf22009-04-22 21:15:06 +0000240 uint32_t Bits = ReadUnalignedLE32(d);
Douglas Gregorda38c6c2009-04-22 18:49:13 +0000241 bool CPlusPlusOperatorKeyword = Bits & 0x01;
242 Bits >>= 1;
243 bool Poisoned = Bits & 0x01;
244 Bits >>= 1;
245 bool ExtensionToken = Bits & 0x01;
246 Bits >>= 1;
247 bool hasMacroDefinition = Bits & 0x01;
248 Bits >>= 1;
249 unsigned ObjCOrBuiltinID = Bits & 0x3FF;
250 Bits >>= 10;
251 unsigned TokenID = Bits & 0xFF;
252 Bits >>= 8;
Douglas Gregor2c09dad2009-04-28 21:18:29 +0000253
Douglas Gregorda38c6c2009-04-22 18:49:13 +0000254 assert(Bits == 0 && "Extra bits in the identifier?");
Douglas Gregorc713da92009-04-21 22:25:48 +0000255 DataLen -= 8;
256
257 // Build the IdentifierInfo itself and link the identifier ID with
258 // the new IdentifierInfo.
259 IdentifierInfo *II = KnownII;
260 if (!II)
Douglas Gregor4bb24882009-04-25 20:26:24 +0000261 II = &Reader.getIdentifierTable().CreateIdentifierInfo(
262 k.first, k.first + k.second);
Douglas Gregorc713da92009-04-21 22:25:48 +0000263 Reader.SetIdentifierInfo(ID, II);
264
Douglas Gregorda38c6c2009-04-22 18:49:13 +0000265 // Set or check the various bits in the IdentifierInfo structure.
266 // FIXME: Load token IDs lazily, too?
267 assert((unsigned)II->getTokenID() == TokenID &&
268 "Incorrect token ID loaded");
269 (void)TokenID;
270 II->setObjCOrBuiltinID(ObjCOrBuiltinID);
271 assert(II->isExtensionToken() == ExtensionToken &&
272 "Incorrect extension token flag");
273 (void)ExtensionToken;
274 II->setIsPoisoned(Poisoned);
275 assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
276 "Incorrect C++ operator keyword flag");
277 (void)CPlusPlusOperatorKeyword;
278
Douglas Gregore0ad2dd2009-04-21 23:56:24 +0000279 // If this identifier is a macro, deserialize the macro
280 // definition.
281 if (hasMacroDefinition) {
282 uint32_t Offset = ReadUnalignedLE64(d);
283 Reader.ReadMacroRecord(Offset);
284 DataLen -= 8;
285 }
Douglas Gregorc713da92009-04-21 22:25:48 +0000286
287 // Read all of the declarations visible at global scope with this
288 // name.
289 Sema *SemaObj = Reader.getSema();
Chris Lattnerea436b82009-04-27 22:17:41 +0000290 if (Reader.getContext() == 0) return II;
Chris Lattner772a7c12009-04-27 22:02:30 +0000291
Douglas Gregorc713da92009-04-21 22:25:48 +0000292 while (DataLen > 0) {
293 NamedDecl *D = cast<NamedDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Douglas Gregorc713da92009-04-21 22:25:48 +0000294 if (SemaObj) {
295 // Introduce this declaration into the translation-unit scope
296 // and add it to the declaration chain for this identifier, so
297 // that (unqualified) name lookup will find it.
298 SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(D));
299 SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
300 } else {
301 // Queue this declaration so that it will be added to the
302 // translation unit scope and identifier's declaration chain
303 // once a Sema object is known.
Douglas Gregor2554cf22009-04-22 21:15:06 +0000304 Reader.PreloadedDecls.push_back(D);
Douglas Gregorc713da92009-04-21 22:25:48 +0000305 }
306
307 DataLen -= 4;
308 }
309 return II;
310 }
311};
312
313} // end anonymous namespace
314
315/// \brief The on-disk hash table used to contain information about
316/// all of the identifiers in the program.
317typedef OnDiskChainedHashTable<PCHIdentifierLookupTrait>
318 PCHIdentifierLookupTable;
319
Douglas Gregorc34897d2009-04-09 22:27:44 +0000320// FIXME: use the diagnostics machinery
321static bool Error(const char *Str) {
322 std::fprintf(stderr, "%s\n", Str);
323 return true;
324}
325
Douglas Gregor32de6312009-04-28 18:58:38 +0000326/// \brief Split the given string into a vector of lines, eliminating
327/// any empty lines in the process.
328///
329/// \param Str the string to split.
330/// \param Len the length of Str.
331/// \param KeepEmptyLines true if empty lines should be included
332/// \returns a vector of lines, with the line endings removed
333std::vector<std::string> splitLines(const char *Str, unsigned Len,
334 bool KeepEmptyLines = false) {
335 std::vector<std::string> Lines;
336 for (unsigned LineStart = 0; LineStart < Len; ++LineStart) {
337 unsigned LineEnd = LineStart;
338 while (LineEnd < Len && Str[LineEnd] != '\n')
339 ++LineEnd;
340 if (LineStart != LineEnd || KeepEmptyLines)
341 Lines.push_back(std::string(&Str[LineStart], &Str[LineEnd]));
342 LineStart = LineEnd;
343 }
344 return Lines;
345}
346
347/// \brief Determine whether the string Haystack starts with the
348/// substring Needle.
349static bool startsWith(const std::string &Haystack, const char *Needle) {
350 for (unsigned I = 0, N = Haystack.size(); Needle[I] != 0; ++I) {
351 if (I == N)
352 return false;
353 if (Haystack[I] != Needle[I])
354 return false;
355 }
356
357 return true;
358}
359
360/// \brief Determine whether the string Haystack starts with the
361/// substring Needle.
362static inline bool startsWith(const std::string &Haystack,
363 const std::string &Needle) {
364 return startsWith(Haystack, Needle.c_str());
365}
366
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000367/// \brief Check the contents of the predefines buffer against the
368/// contents of the predefines buffer used to build the PCH file.
369///
370/// The contents of the two predefines buffers should be the same. If
371/// not, then some command-line option changed the preprocessor state
372/// and we must reject the PCH file.
373///
374/// \param PCHPredef The start of the predefines buffer in the PCH
375/// file.
376///
377/// \param PCHPredefLen The length of the predefines buffer in the PCH
378/// file.
379///
380/// \param PCHBufferID The FileID for the PCH predefines buffer.
381///
382/// \returns true if there was a mismatch (in which case the PCH file
383/// should be ignored), or false otherwise.
384bool PCHReader::CheckPredefinesBuffer(const char *PCHPredef,
385 unsigned PCHPredefLen,
386 FileID PCHBufferID) {
387 const char *Predef = PP.getPredefines().c_str();
388 unsigned PredefLen = PP.getPredefines().size();
389
Douglas Gregor32de6312009-04-28 18:58:38 +0000390 // If the two predefines buffers compare equal, we're done!
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000391 if (PredefLen == PCHPredefLen &&
392 strncmp(Predef, PCHPredef, PCHPredefLen) == 0)
393 return false;
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000394
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000395 SourceManager &SourceMgr = PP.getSourceManager();
Douglas Gregor32de6312009-04-28 18:58:38 +0000396
397 // The predefines buffers are different. Determine what the
398 // differences are, and whether they require us to reject the PCH
399 // file.
400 std::vector<std::string> CmdLineLines = splitLines(Predef, PredefLen);
401 std::vector<std::string> PCHLines = splitLines(PCHPredef, PCHPredefLen);
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000402
Douglas Gregor32de6312009-04-28 18:58:38 +0000403 // Sort both sets of predefined buffer lines, since
404 std::sort(CmdLineLines.begin(), CmdLineLines.end());
405 std::sort(PCHLines.begin(), PCHLines.end());
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000406
Douglas Gregor32de6312009-04-28 18:58:38 +0000407 // Determine which predefines that where used to build the PCH file
408 // are missing from the command line.
409 std::vector<std::string> MissingPredefines;
410 std::set_difference(PCHLines.begin(), PCHLines.end(),
411 CmdLineLines.begin(), CmdLineLines.end(),
412 std::back_inserter(MissingPredefines));
413
414 bool MissingDefines = false;
415 bool ConflictingDefines = false;
416 for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
417 const std::string &Missing = MissingPredefines[I];
418 if (!startsWith(Missing, "#define ") != 0) {
Douglas Gregor1c6d8cc2009-04-28 20:36:16 +0000419 Diag(diag::warn_pch_compiler_options_mismatch);
420 Diag(diag::note_ignoring_pch) << FileName;
Douglas Gregor32de6312009-04-28 18:58:38 +0000421 return true;
422 }
423
424 // This is a macro definition. Determine the name of the macro
425 // we're defining.
426 std::string::size_type StartOfMacroName = strlen("#define ");
427 std::string::size_type EndOfMacroName
428 = Missing.find_first_of("( \n\r", StartOfMacroName);
429 assert(EndOfMacroName != std::string::npos &&
430 "Couldn't find the end of the macro name");
431 std::string MacroName = Missing.substr(StartOfMacroName,
432 EndOfMacroName - StartOfMacroName);
433
434 // Determine whether this macro was given a different definition
435 // on the command line.
436 std::string MacroDefStart = "#define " + MacroName;
437 std::string::size_type MacroDefLen = MacroDefStart.size();
438 std::vector<std::string>::iterator ConflictPos
439 = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
440 MacroDefStart);
441 for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
442 if (!startsWith(*ConflictPos, MacroDefStart)) {
443 // Different macro; we're done.
444 ConflictPos = CmdLineLines.end();
445 break;
446 }
447
448 assert(ConflictPos->size() > MacroDefLen &&
449 "Invalid #define in predefines buffer?");
450 if ((*ConflictPos)[MacroDefLen] != ' ' &&
451 (*ConflictPos)[MacroDefLen] != '(')
452 continue; // Longer macro name; keep trying.
453
454 // We found a conflicting macro definition.
455 break;
456 }
457
458 if (ConflictPos != CmdLineLines.end()) {
459 Diag(diag::warn_cmdline_conflicting_macro_def)
460 << MacroName;
461
462 // Show the definition of this macro within the PCH file.
463 const char *MissingDef = strstr(PCHPredef, Missing.c_str());
464 unsigned Offset = MissingDef - PCHPredef;
465 SourceLocation PCHMissingLoc
466 = SourceMgr.getLocForStartOfFile(PCHBufferID)
467 .getFileLocWithOffset(Offset);
468 Diag(PCHMissingLoc, diag::note_pch_macro_defined_as)
469 << MacroName;
470
471 ConflictingDefines = true;
472 continue;
473 }
474
475 // If the macro doesn't conflict, then we'll just pick up the
476 // macro definition from the PCH file. Warn the user that they
477 // made a mistake.
478 if (ConflictingDefines)
479 continue; // Don't complain if there are already conflicting defs
480
481 if (!MissingDefines) {
482 Diag(diag::warn_cmdline_missing_macro_defs);
483 MissingDefines = true;
484 }
485
486 // Show the definition of this macro within the PCH file.
487 const char *MissingDef = strstr(PCHPredef, Missing.c_str());
488 unsigned Offset = MissingDef - PCHPredef;
489 SourceLocation PCHMissingLoc
490 = SourceMgr.getLocForStartOfFile(PCHBufferID)
491 .getFileLocWithOffset(Offset);
492 Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000493 }
494
Douglas Gregor32de6312009-04-28 18:58:38 +0000495 if (ConflictingDefines) {
496 Diag(diag::note_ignoring_pch) << FileName;
497 return true;
498 }
499
500 // Determine what predefines were introduced based on command-line
501 // parameters that were not present when building the PCH
502 // file. Extra #defines are okay, so long as the identifiers being
503 // defined were not used within the precompiled header.
504 std::vector<std::string> ExtraPredefines;
505 std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
506 PCHLines.begin(), PCHLines.end(),
507 std::back_inserter(ExtraPredefines));
508 for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
509 const std::string &Extra = ExtraPredefines[I];
510 if (!startsWith(Extra, "#define ") != 0) {
Douglas Gregor1c6d8cc2009-04-28 20:36:16 +0000511 Diag(diag::warn_pch_compiler_options_mismatch);
512 Diag(diag::note_ignoring_pch) << FileName;
Douglas Gregor32de6312009-04-28 18:58:38 +0000513 return true;
514 }
515
516 // This is an extra macro definition. Determine the name of the
517 // macro we're defining.
518 std::string::size_type StartOfMacroName = strlen("#define ");
519 std::string::size_type EndOfMacroName
520 = Extra.find_first_of("( \n\r", StartOfMacroName);
521 assert(EndOfMacroName != std::string::npos &&
522 "Couldn't find the end of the macro name");
523 std::string MacroName = Extra.substr(StartOfMacroName,
524 EndOfMacroName - StartOfMacroName);
525
Douglas Gregor91137812009-04-28 20:33:11 +0000526 // Check whether this name was used somewhere in the PCH file. If
527 // so, defining it as a macro could change behavior, so we reject
528 // the PCH file.
529 if (IdentifierInfo *II = get(MacroName.c_str(),
530 MacroName.c_str() + MacroName.size())) {
531 Diag(diag::warn_macro_name_used_in_pch)
532 << II;
533 Diag(diag::note_ignoring_pch)
534 << FileName;
535 return true;
536 }
Douglas Gregor32de6312009-04-28 18:58:38 +0000537
538 // Add this definition to the suggested predefines buffer.
539 SuggestedPredefines += Extra;
540 SuggestedPredefines += '\n';
541 }
542
543 // If we get here, it's because the predefines buffer had compatible
544 // contents. Accept the PCH file.
545 return false;
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000546}
547
Douglas Gregor6cc5d192009-04-27 18:38:38 +0000548//===----------------------------------------------------------------------===//
549// Source Manager Deserialization
550//===----------------------------------------------------------------------===//
551
Douglas Gregor635f97f2009-04-13 16:31:14 +0000552/// \brief Read the line table in the source manager block.
553/// \returns true if ther was an error.
554static bool ParseLineTable(SourceManager &SourceMgr,
555 llvm::SmallVectorImpl<uint64_t> &Record) {
556 unsigned Idx = 0;
557 LineTableInfo &LineTable = SourceMgr.getLineTable();
558
559 // Parse the file names
Douglas Gregor183ad602009-04-13 17:12:42 +0000560 std::map<int, int> FileIDs;
561 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregor635f97f2009-04-13 16:31:14 +0000562 // Extract the file name
563 unsigned FilenameLen = Record[Idx++];
564 std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
565 Idx += FilenameLen;
Douglas Gregor183ad602009-04-13 17:12:42 +0000566 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
567 Filename.size());
Douglas Gregor635f97f2009-04-13 16:31:14 +0000568 }
569
570 // Parse the line entries
571 std::vector<LineEntry> Entries;
572 while (Idx < Record.size()) {
Douglas Gregor183ad602009-04-13 17:12:42 +0000573 int FID = FileIDs[Record[Idx++]];
Douglas Gregor635f97f2009-04-13 16:31:14 +0000574
575 // Extract the line entries
576 unsigned NumEntries = Record[Idx++];
577 Entries.clear();
578 Entries.reserve(NumEntries);
579 for (unsigned I = 0; I != NumEntries; ++I) {
580 unsigned FileOffset = Record[Idx++];
581 unsigned LineNo = Record[Idx++];
582 int FilenameID = Record[Idx++];
583 SrcMgr::CharacteristicKind FileKind
584 = (SrcMgr::CharacteristicKind)Record[Idx++];
585 unsigned IncludeOffset = Record[Idx++];
586 Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
587 FileKind, IncludeOffset));
588 }
589 LineTable.AddEntry(FID, Entries);
590 }
591
592 return false;
593}
594
Douglas Gregor6cc5d192009-04-27 18:38:38 +0000595namespace {
596
597class VISIBILITY_HIDDEN PCHStatData {
598public:
599 const bool hasStat;
600 const ino_t ino;
601 const dev_t dev;
602 const mode_t mode;
603 const time_t mtime;
604 const off_t size;
605
606 PCHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
607 : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
608
609 PCHStatData()
610 : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
611};
612
613class VISIBILITY_HIDDEN PCHStatLookupTrait {
614 public:
615 typedef const char *external_key_type;
616 typedef const char *internal_key_type;
617
618 typedef PCHStatData data_type;
619
620 static unsigned ComputeHash(const char *path) {
621 return BernsteinHash(path);
622 }
623
624 static internal_key_type GetInternalKey(const char *path) { return path; }
625
626 static bool EqualKey(internal_key_type a, internal_key_type b) {
627 return strcmp(a, b) == 0;
628 }
629
630 static std::pair<unsigned, unsigned>
631 ReadKeyDataLength(const unsigned char*& d) {
632 unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
633 unsigned DataLen = (unsigned) *d++;
634 return std::make_pair(KeyLen + 1, DataLen);
635 }
636
637 static internal_key_type ReadKey(const unsigned char *d, unsigned) {
638 return (const char *)d;
639 }
640
641 static data_type ReadData(const internal_key_type, const unsigned char *d,
642 unsigned /*DataLen*/) {
643 using namespace clang::io;
644
645 if (*d++ == 1)
646 return data_type();
647
648 ino_t ino = (ino_t) ReadUnalignedLE32(d);
649 dev_t dev = (dev_t) ReadUnalignedLE32(d);
650 mode_t mode = (mode_t) ReadUnalignedLE16(d);
651 time_t mtime = (time_t) ReadUnalignedLE64(d);
652 off_t size = (off_t) ReadUnalignedLE64(d);
653 return data_type(ino, dev, mode, mtime, size);
654 }
655};
656
657/// \brief stat() cache for precompiled headers.
658///
659/// This cache is very similar to the stat cache used by pretokenized
660/// headers.
661class VISIBILITY_HIDDEN PCHStatCache : public StatSysCallCache {
662 typedef OnDiskChainedHashTable<PCHStatLookupTrait> CacheTy;
663 CacheTy *Cache;
664
665 unsigned &NumStatHits, &NumStatMisses;
666public:
667 PCHStatCache(const unsigned char *Buckets,
668 const unsigned char *Base,
669 unsigned &NumStatHits,
670 unsigned &NumStatMisses)
671 : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
672 Cache = CacheTy::Create(Buckets, Base);
673 }
674
675 ~PCHStatCache() { delete Cache; }
676
677 int stat(const char *path, struct stat *buf) {
678 // Do the lookup for the file's data in the PCH file.
679 CacheTy::iterator I = Cache->find(path);
680
681 // If we don't get a hit in the PCH file just forward to 'stat'.
682 if (I == Cache->end()) {
683 ++NumStatMisses;
684 return ::stat(path, buf);
685 }
686
687 ++NumStatHits;
688 PCHStatData Data = *I;
689
690 if (!Data.hasStat)
691 return 1;
692
693 buf->st_ino = Data.ino;
694 buf->st_dev = Data.dev;
695 buf->st_mtime = Data.mtime;
696 buf->st_mode = Data.mode;
697 buf->st_size = Data.size;
698 return 0;
699 }
700};
701} // end anonymous namespace
702
703
Douglas Gregorab1cef72009-04-10 03:52:48 +0000704/// \brief Read the source manager block
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000705PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
Douglas Gregorab1cef72009-04-10 03:52:48 +0000706 using namespace SrcMgr;
Douglas Gregor32e231c2009-04-27 06:38:32 +0000707
708 // Set the source-location entry cursor to the current position in
709 // the stream. This cursor will be used to read the contents of the
710 // source manager block initially, and then lazily read
711 // source-location entries as needed.
712 SLocEntryCursor = Stream;
713
714 // The stream itself is going to skip over the source manager block.
715 if (Stream.SkipBlock()) {
716 Error("Malformed block record");
717 return Failure;
718 }
719
720 // Enter the source manager block.
721 if (SLocEntryCursor.EnterSubBlock(pch::SOURCE_MANAGER_BLOCK_ID)) {
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000722 Error("Malformed source manager block record");
723 return Failure;
724 }
Douglas Gregorab1cef72009-04-10 03:52:48 +0000725
Chris Lattner270d29a2009-04-27 21:45:14 +0000726 SourceManager &SourceMgr = PP.getSourceManager();
Douglas Gregorab1cef72009-04-10 03:52:48 +0000727 RecordData Record;
Douglas Gregorf6e1fb22009-04-26 00:07:37 +0000728 unsigned NumHeaderInfos = 0;
Douglas Gregorab1cef72009-04-10 03:52:48 +0000729 while (true) {
Douglas Gregor32e231c2009-04-27 06:38:32 +0000730 unsigned Code = SLocEntryCursor.ReadCode();
Douglas Gregorab1cef72009-04-10 03:52:48 +0000731 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor32e231c2009-04-27 06:38:32 +0000732 if (SLocEntryCursor.ReadBlockEnd()) {
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000733 Error("Error at end of Source Manager block");
734 return Failure;
735 }
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000736 return Success;
Douglas Gregorab1cef72009-04-10 03:52:48 +0000737 }
738
739 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
740 // No known subblocks, always skip them.
Douglas Gregor32e231c2009-04-27 06:38:32 +0000741 SLocEntryCursor.ReadSubBlockID();
742 if (SLocEntryCursor.SkipBlock()) {
Douglas Gregorb3a04c82009-04-10 23:10:45 +0000743 Error("Malformed block record");
744 return Failure;
745 }
Douglas Gregorab1cef72009-04-10 03:52:48 +0000746 continue;
747 }
748
749 if (Code == llvm::bitc::DEFINE_ABBREV) {
Douglas Gregor32e231c2009-04-27 06:38:32 +0000750 SLocEntryCursor.ReadAbbrevRecord();
Douglas Gregorab1cef72009-04-10 03:52:48 +0000751 continue;
752 }
753
754 // Read a record.
755 const char *BlobStart;
756 unsigned BlobLen;
757 Record.clear();
Douglas Gregor32e231c2009-04-27 06:38:32 +0000758 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
Douglas Gregorab1cef72009-04-10 03:52:48 +0000759 default: // Default behavior: ignore.
760 break;
761
Chris Lattnere1be6022009-04-14 23:22:57 +0000762 case pch::SM_LINE_TABLE:
Douglas Gregor635f97f2009-04-13 16:31:14 +0000763 if (ParseLineTable(SourceMgr, Record))
764 return Failure;
Chris Lattnere1be6022009-04-14 23:22:57 +0000765 break;
Douglas Gregorf6e1fb22009-04-26 00:07:37 +0000766
767 case pch::SM_HEADER_FILE_INFO: {
768 HeaderFileInfo HFI;
769 HFI.isImport = Record[0];
770 HFI.DirInfo = Record[1];
771 HFI.NumIncludes = Record[2];
772 HFI.ControllingMacroID = Record[3];
773 PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
774 break;
775 }
Douglas Gregor32e231c2009-04-27 06:38:32 +0000776
777 case pch::SM_SLOC_FILE_ENTRY:
778 case pch::SM_SLOC_BUFFER_ENTRY:
779 case pch::SM_SLOC_INSTANTIATION_ENTRY:
780 // Once we hit one of the source location entries, we're done.
781 return Success;
Douglas Gregorab1cef72009-04-10 03:52:48 +0000782 }
783 }
784}
785
Douglas Gregor32e231c2009-04-27 06:38:32 +0000786/// \brief Read in the source location entry with the given ID.
787PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {
788 if (ID == 0)
789 return Success;
790
791 if (ID > TotalNumSLocEntries) {
792 Error("source location entry ID out-of-range for PCH file");
793 return Failure;
794 }
795
796 ++NumSLocEntriesRead;
797 SLocEntryCursor.JumpToBit(SLocOffsets[ID - 1]);
798 unsigned Code = SLocEntryCursor.ReadCode();
799 if (Code == llvm::bitc::END_BLOCK ||
800 Code == llvm::bitc::ENTER_SUBBLOCK ||
801 Code == llvm::bitc::DEFINE_ABBREV) {
802 Error("incorrectly-formatted source location entry in PCH file");
803 return Failure;
804 }
805
Chris Lattner270d29a2009-04-27 21:45:14 +0000806 SourceManager &SourceMgr = PP.getSourceManager();
Douglas Gregor32e231c2009-04-27 06:38:32 +0000807 RecordData Record;
808 const char *BlobStart;
809 unsigned BlobLen;
810 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
811 default:
812 Error("incorrectly-formatted source location entry in PCH file");
813 return Failure;
814
815 case pch::SM_SLOC_FILE_ENTRY: {
816 const FileEntry *File
817 = PP.getFileManager().getFile(BlobStart, BlobStart + BlobLen);
818 // FIXME: Error recovery if file cannot be found.
819 FileID FID = SourceMgr.createFileID(File,
820 SourceLocation::getFromRawEncoding(Record[1]),
821 (SrcMgr::CharacteristicKind)Record[2],
822 ID, Record[0]);
823 if (Record[3])
824 const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
825 .setHasLineDirectives();
826
827 break;
828 }
829
830 case pch::SM_SLOC_BUFFER_ENTRY: {
831 const char *Name = BlobStart;
832 unsigned Offset = Record[0];
833 unsigned Code = SLocEntryCursor.ReadCode();
834 Record.clear();
835 unsigned RecCode
836 = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
837 assert(RecCode == pch::SM_SLOC_BUFFER_BLOB && "Ill-formed PCH file");
838 (void)RecCode;
839 llvm::MemoryBuffer *Buffer
840 = llvm::MemoryBuffer::getMemBuffer(BlobStart,
841 BlobStart + BlobLen - 1,
842 Name);
843 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
844
Douglas Gregor91137812009-04-28 20:33:11 +0000845 if (strcmp(Name, "<built-in>") == 0) {
846 PCHPredefinesBufferID = BufferID;
847 PCHPredefines = BlobStart;
848 PCHPredefinesLen = BlobLen - 1;
849 }
Douglas Gregor32e231c2009-04-27 06:38:32 +0000850
851 break;
852 }
853
854 case pch::SM_SLOC_INSTANTIATION_ENTRY: {
855 SourceLocation SpellingLoc
856 = SourceLocation::getFromRawEncoding(Record[1]);
857 SourceMgr.createInstantiationLoc(SpellingLoc,
858 SourceLocation::getFromRawEncoding(Record[2]),
859 SourceLocation::getFromRawEncoding(Record[3]),
860 Record[4],
861 ID,
862 Record[0]);
863 break;
864 }
865 }
866
867 return Success;
868}
869
Chris Lattner4fc71eb2009-04-27 01:05:14 +0000870/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
871/// specified cursor. Read the abbreviations that are at the top of the block
872/// and then leave the cursor pointing into the block.
873bool PCHReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
874 unsigned BlockID) {
875 if (Cursor.EnterSubBlock(BlockID)) {
876 Error("Malformed block record");
877 return Failure;
878 }
879
Chris Lattner4fc71eb2009-04-27 01:05:14 +0000880 while (true) {
881 unsigned Code = Cursor.ReadCode();
882
883 // We expect all abbrevs to be at the start of the block.
884 if (Code != llvm::bitc::DEFINE_ABBREV)
885 return false;
886 Cursor.ReadAbbrevRecord();
887 }
888}
889
Douglas Gregore0ad2dd2009-04-21 23:56:24 +0000890void PCHReader::ReadMacroRecord(uint64_t Offset) {
891 // Keep track of where we are in the stream, then jump back there
892 // after reading this macro.
893 SavedStreamPosition SavedPosition(Stream);
894
895 Stream.JumpToBit(Offset);
896 RecordData Record;
897 llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
898 MacroInfo *Macro = 0;
Steve Naroffcda68f22009-04-24 20:03:17 +0000899
Douglas Gregore0ad2dd2009-04-21 23:56:24 +0000900 while (true) {
901 unsigned Code = Stream.ReadCode();
902 switch (Code) {
903 case llvm::bitc::END_BLOCK:
904 return;
905
906 case llvm::bitc::ENTER_SUBBLOCK:
907 // No known subblocks, always skip them.
908 Stream.ReadSubBlockID();
909 if (Stream.SkipBlock()) {
910 Error("Malformed block record");
911 return;
912 }
913 continue;
914
915 case llvm::bitc::DEFINE_ABBREV:
916 Stream.ReadAbbrevRecord();
917 continue;
918 default: break;
919 }
920
921 // Read a record.
922 Record.clear();
923 pch::PreprocessorRecordTypes RecType =
924 (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
925 switch (RecType) {
Douglas Gregore0ad2dd2009-04-21 23:56:24 +0000926 case pch::PP_MACRO_OBJECT_LIKE:
927 case pch::PP_MACRO_FUNCTION_LIKE: {
928 // If we already have a macro, that means that we've hit the end
929 // of the definition of the macro we were looking for. We're
930 // done.
931 if (Macro)
932 return;
933
934 IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
935 if (II == 0) {
936 Error("Macro must have a name");
937 return;
938 }
939 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
940 bool isUsed = Record[2];
941
942 MacroInfo *MI = PP.AllocateMacroInfo(Loc);
943 MI->setIsUsed(isUsed);
944
945 if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
946 // Decode function-like macro info.
947 bool isC99VarArgs = Record[3];
948 bool isGNUVarArgs = Record[4];
949 MacroArgs.clear();
950 unsigned NumArgs = Record[5];
951 for (unsigned i = 0; i != NumArgs; ++i)
952 MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
953
954 // Install function-like macro info.
955 MI->setIsFunctionLike();
956 if (isC99VarArgs) MI->setIsC99Varargs();
957 if (isGNUVarArgs) MI->setIsGNUVarargs();
958 MI->setArgumentList(&MacroArgs[0], MacroArgs.size(),
959 PP.getPreprocessorAllocator());
960 }
961
962 // Finally, install the macro.
963 PP.setMacroInfo(II, MI);
964
965 // Remember that we saw this macro last so that we add the tokens that
966 // form its body to it.
967 Macro = MI;
968 ++NumMacrosRead;
969 break;
970 }
971
972 case pch::PP_TOKEN: {
973 // If we see a TOKEN before a PP_MACRO_*, then the file is
974 // erroneous, just pretend we didn't see this.
975 if (Macro == 0) break;
976
977 Token Tok;
978 Tok.startToken();
979 Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
980 Tok.setLength(Record[1]);
981 if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
982 Tok.setIdentifierInfo(II);
983 Tok.setKind((tok::TokenKind)Record[3]);
984 Tok.setFlag((Token::TokenFlags)Record[4]);
985 Macro->AddTokenToBody(Tok);
986 break;
987 }
Steve Naroffcda68f22009-04-24 20:03:17 +0000988 }
Douglas Gregore0ad2dd2009-04-21 23:56:24 +0000989 }
990}
991
Douglas Gregorc713da92009-04-21 22:25:48 +0000992PCHReader::PCHReadResult
Douglas Gregorf6e1fb22009-04-26 00:07:37 +0000993PCHReader::ReadPCHBlock() {
Douglas Gregor179cfb12009-04-10 20:39:37 +0000994 if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
995 Error("Malformed block record");
996 return Failure;
997 }
Douglas Gregorc34897d2009-04-09 22:27:44 +0000998
999 // Read all of the records and blocks for the PCH file.
Douglas Gregorac8f2802009-04-10 17:25:41 +00001000 RecordData Record;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001001 while (!Stream.AtEndOfStream()) {
1002 unsigned Code = Stream.ReadCode();
1003 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor179cfb12009-04-10 20:39:37 +00001004 if (Stream.ReadBlockEnd()) {
1005 Error("Error at end of module block");
1006 return Failure;
1007 }
Chris Lattner29241862009-04-11 21:15:38 +00001008
Douglas Gregor179cfb12009-04-10 20:39:37 +00001009 return Success;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001010 }
1011
1012 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1013 switch (Stream.ReadSubBlockID()) {
Douglas Gregorc34897d2009-04-09 22:27:44 +00001014 case pch::TYPES_BLOCK_ID: // Skip types block (lazily loaded)
1015 default: // Skip unknown content.
Douglas Gregor179cfb12009-04-10 20:39:37 +00001016 if (Stream.SkipBlock()) {
1017 Error("Malformed block record");
1018 return Failure;
1019 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001020 break;
1021
Chris Lattner4fc71eb2009-04-27 01:05:14 +00001022 case pch::DECLS_BLOCK_ID:
1023 // We lazily load the decls block, but we want to set up the
1024 // DeclsCursor cursor to point into it. Clone our current bitcode
1025 // cursor to it, enter the block and read the abbrevs in that block.
1026 // With the main cursor, we just skip over it.
1027 DeclsCursor = Stream;
1028 if (Stream.SkipBlock() || // Skip with the main cursor.
1029 // Read the abbrevs.
1030 ReadBlockAbbrevs(DeclsCursor, pch::DECLS_BLOCK_ID)) {
1031 Error("Malformed block record");
1032 return Failure;
1033 }
1034 break;
1035
Chris Lattner29241862009-04-11 21:15:38 +00001036 case pch::PREPROCESSOR_BLOCK_ID:
Chris Lattner29241862009-04-11 21:15:38 +00001037 if (Stream.SkipBlock()) {
1038 Error("Malformed block record");
1039 return Failure;
1040 }
1041 break;
Steve Naroff9e84d782009-04-23 10:39:46 +00001042
Douglas Gregorab1cef72009-04-10 03:52:48 +00001043 case pch::SOURCE_MANAGER_BLOCK_ID:
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001044 switch (ReadSourceManagerBlock()) {
1045 case Success:
1046 break;
1047
1048 case Failure:
Douglas Gregor179cfb12009-04-10 20:39:37 +00001049 Error("Malformed source manager block");
1050 return Failure;
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001051
1052 case IgnorePCH:
1053 return IgnorePCH;
Douglas Gregor179cfb12009-04-10 20:39:37 +00001054 }
Douglas Gregorab1cef72009-04-10 03:52:48 +00001055 break;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001056 }
Douglas Gregorac8f2802009-04-10 17:25:41 +00001057 continue;
1058 }
1059
1060 if (Code == llvm::bitc::DEFINE_ABBREV) {
1061 Stream.ReadAbbrevRecord();
1062 continue;
1063 }
1064
1065 // Read and process a record.
1066 Record.clear();
Douglas Gregorb5887f32009-04-10 21:16:55 +00001067 const char *BlobStart = 0;
1068 unsigned BlobLen = 0;
1069 switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record,
1070 &BlobStart, &BlobLen)) {
Douglas Gregorac8f2802009-04-10 17:25:41 +00001071 default: // Default behavior: ignore.
1072 break;
1073
1074 case pch::TYPE_OFFSET:
Douglas Gregor24a224c2009-04-25 18:35:21 +00001075 if (!TypesLoaded.empty()) {
Douglas Gregor179cfb12009-04-10 20:39:37 +00001076 Error("Duplicate TYPE_OFFSET record in PCH file");
1077 return Failure;
1078 }
Chris Lattnerea332f32009-04-27 18:24:17 +00001079 TypeOffsets = (const uint32_t *)BlobStart;
Douglas Gregor24a224c2009-04-25 18:35:21 +00001080 TypesLoaded.resize(Record[0]);
Douglas Gregorac8f2802009-04-10 17:25:41 +00001081 break;
1082
1083 case pch::DECL_OFFSET:
Douglas Gregor24a224c2009-04-25 18:35:21 +00001084 if (!DeclsLoaded.empty()) {
Douglas Gregor179cfb12009-04-10 20:39:37 +00001085 Error("Duplicate DECL_OFFSET record in PCH file");
1086 return Failure;
1087 }
Chris Lattnerea332f32009-04-27 18:24:17 +00001088 DeclOffsets = (const uint32_t *)BlobStart;
Douglas Gregor24a224c2009-04-25 18:35:21 +00001089 DeclsLoaded.resize(Record[0]);
Douglas Gregorac8f2802009-04-10 17:25:41 +00001090 break;
Douglas Gregor179cfb12009-04-10 20:39:37 +00001091
1092 case pch::LANGUAGE_OPTIONS:
1093 if (ParseLanguageOptions(Record))
1094 return IgnorePCH;
1095 break;
Douglas Gregorb5887f32009-04-10 21:16:55 +00001096
Douglas Gregorb7064742009-04-27 22:23:34 +00001097 case pch::METADATA: {
1098 if (Record[0] != pch::VERSION_MAJOR) {
1099 Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old
1100 : diag::warn_pch_version_too_new);
1101 return IgnorePCH;
1102 }
1103
Douglas Gregorb5887f32009-04-10 21:16:55 +00001104 std::string TargetTriple(BlobStart, BlobLen);
Chris Lattner270d29a2009-04-27 21:45:14 +00001105 if (TargetTriple != PP.getTargetInfo().getTargetTriple()) {
Douglas Gregorb5887f32009-04-10 21:16:55 +00001106 Diag(diag::warn_pch_target_triple)
Chris Lattner270d29a2009-04-27 21:45:14 +00001107 << TargetTriple << PP.getTargetInfo().getTargetTriple();
Douglas Gregorb5887f32009-04-10 21:16:55 +00001108 Diag(diag::note_ignoring_pch) << FileName;
1109 return IgnorePCH;
1110 }
1111 break;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001112 }
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001113
1114 case pch::IDENTIFIER_TABLE:
Douglas Gregorc713da92009-04-21 22:25:48 +00001115 IdentifierTableData = BlobStart;
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001116 if (Record[0]) {
1117 IdentifierLookupTable
1118 = PCHIdentifierLookupTable::Create(
Douglas Gregorc713da92009-04-21 22:25:48 +00001119 (const unsigned char *)IdentifierTableData + Record[0],
1120 (const unsigned char *)IdentifierTableData,
1121 PCHIdentifierLookupTrait(*this));
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001122 PP.getIdentifierTable().setExternalIdentifierLookup(this);
1123 }
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001124 break;
1125
1126 case pch::IDENTIFIER_OFFSET:
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001127 if (!IdentifiersLoaded.empty()) {
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001128 Error("Duplicate IDENTIFIER_OFFSET record in PCH file");
1129 return Failure;
1130 }
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001131 IdentifierOffsets = (const uint32_t *)BlobStart;
1132 IdentifiersLoaded.resize(Record[0]);
Douglas Gregoreccb51d2009-04-25 23:30:02 +00001133 PP.getHeaderSearchInfo().SetExternalLookup(this);
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001134 break;
Douglas Gregor631f6c62009-04-14 00:24:19 +00001135
1136 case pch::EXTERNAL_DEFINITIONS:
1137 if (!ExternalDefinitions.empty()) {
1138 Error("Duplicate EXTERNAL_DEFINITIONS record in PCH file");
1139 return Failure;
1140 }
1141 ExternalDefinitions.swap(Record);
1142 break;
Douglas Gregor456e0952009-04-17 22:13:46 +00001143
Douglas Gregore01ad442009-04-18 05:55:16 +00001144 case pch::SPECIAL_TYPES:
1145 SpecialTypes.swap(Record);
1146 break;
1147
Douglas Gregor456e0952009-04-17 22:13:46 +00001148 case pch::STATISTICS:
1149 TotalNumStatements = Record[0];
Douglas Gregore0ad2dd2009-04-21 23:56:24 +00001150 TotalNumMacros = Record[1];
Douglas Gregoraf136d92009-04-22 22:34:57 +00001151 TotalLexicalDeclContexts = Record[2];
1152 TotalVisibleDeclContexts = Record[3];
Douglas Gregor456e0952009-04-17 22:13:46 +00001153 break;
Douglas Gregor32e231c2009-04-27 06:38:32 +00001154
Douglas Gregor77b2cd52009-04-22 22:02:47 +00001155 case pch::TENTATIVE_DEFINITIONS:
1156 if (!TentativeDefinitions.empty()) {
1157 Error("Duplicate TENTATIVE_DEFINITIONS record in PCH file");
1158 return Failure;
1159 }
1160 TentativeDefinitions.swap(Record);
1161 break;
Douglas Gregor062d9482009-04-22 22:18:58 +00001162
1163 case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
1164 if (!LocallyScopedExternalDecls.empty()) {
1165 Error("Duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
1166 return Failure;
1167 }
1168 LocallyScopedExternalDecls.swap(Record);
1169 break;
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001170
Douglas Gregor2d711832009-04-25 17:48:32 +00001171 case pch::SELECTOR_OFFSETS:
1172 SelectorOffsets = (const uint32_t *)BlobStart;
1173 TotalNumSelectors = Record[0];
1174 SelectorsLoaded.resize(TotalNumSelectors);
1175 break;
1176
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001177 case pch::METHOD_POOL:
Douglas Gregor2d711832009-04-25 17:48:32 +00001178 MethodPoolLookupTableData = (const unsigned char *)BlobStart;
1179 if (Record[0])
1180 MethodPoolLookupTable
1181 = PCHMethodPoolLookupTable::Create(
1182 MethodPoolLookupTableData + Record[0],
1183 MethodPoolLookupTableData,
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001184 PCHMethodPoolLookupTrait(*this));
Douglas Gregor2d711832009-04-25 17:48:32 +00001185 TotalSelectorsInMethodPool = Record[1];
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001186 break;
Douglas Gregorf6e1fb22009-04-26 00:07:37 +00001187
1188 case pch::PP_COUNTER_VALUE:
1189 if (!Record.empty())
1190 PP.setCounterValue(Record[0]);
1191 break;
Douglas Gregor32e231c2009-04-27 06:38:32 +00001192
1193 case pch::SOURCE_LOCATION_OFFSETS:
Chris Lattner93307da2009-04-27 19:01:47 +00001194 SLocOffsets = (const uint32_t *)BlobStart;
Douglas Gregor32e231c2009-04-27 06:38:32 +00001195 TotalNumSLocEntries = Record[0];
1196 PP.getSourceManager().PreallocateSLocEntries(this,
1197 TotalNumSLocEntries,
1198 Record[1]);
1199 break;
1200
1201 case pch::SOURCE_LOCATION_PRELOADS:
1202 for (unsigned I = 0, N = Record.size(); I != N; ++I) {
1203 PCHReadResult Result = ReadSLocEntryRecord(Record[I]);
1204 if (Result != Success)
1205 return Result;
1206 }
1207 break;
Douglas Gregor6cc5d192009-04-27 18:38:38 +00001208
1209 case pch::STAT_CACHE:
1210 PP.getFileManager().setStatCache(
1211 new PCHStatCache((const unsigned char *)BlobStart + Record[0],
1212 (const unsigned char *)BlobStart,
1213 NumStatHits, NumStatMisses));
1214 break;
Douglas Gregorb36b20d2009-04-27 20:06:05 +00001215
1216 case pch::EXT_VECTOR_DECLS:
1217 if (!ExtVectorDecls.empty()) {
1218 Error("Duplicate EXT_VECTOR_DECLS record in PCH file");
1219 return Failure;
1220 }
1221 ExtVectorDecls.swap(Record);
1222 break;
1223
1224 case pch::OBJC_CATEGORY_IMPLEMENTATIONS:
1225 if (!ObjCCategoryImpls.empty()) {
1226 Error("Duplicate OBJC_CATEGORY_IMPLEMENTATIONS record in PCH file");
1227 return Failure;
1228 }
1229 ObjCCategoryImpls.swap(Record);
1230 break;
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001231 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001232 }
Douglas Gregor179cfb12009-04-10 20:39:37 +00001233 Error("Premature end of bitstream");
1234 return Failure;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001235}
1236
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001237PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
Douglas Gregor179cfb12009-04-10 20:39:37 +00001238 // Set the PCH file name.
1239 this->FileName = FileName;
1240
Douglas Gregorc34897d2009-04-09 22:27:44 +00001241 // Open the PCH file.
1242 std::string ErrStr;
1243 Buffer.reset(llvm::MemoryBuffer::getFile(FileName.c_str(), &ErrStr));
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001244 if (!Buffer) {
1245 Error(ErrStr.c_str());
1246 return IgnorePCH;
1247 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001248
1249 // Initialize the stream
Chris Lattner587788a2009-04-26 20:59:20 +00001250 StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
1251 (const unsigned char *)Buffer->getBufferEnd());
1252 Stream.init(StreamFile);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001253
1254 // Sniff for the signature.
1255 if (Stream.Read(8) != 'C' ||
1256 Stream.Read(8) != 'P' ||
1257 Stream.Read(8) != 'C' ||
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001258 Stream.Read(8) != 'H') {
1259 Error("Not a PCH file");
1260 return IgnorePCH;
1261 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001262
Douglas Gregorc34897d2009-04-09 22:27:44 +00001263 while (!Stream.AtEndOfStream()) {
1264 unsigned Code = Stream.ReadCode();
1265
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001266 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
1267 Error("Invalid record at top-level");
1268 return Failure;
1269 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001270
1271 unsigned BlockID = Stream.ReadSubBlockID();
Douglas Gregorc713da92009-04-21 22:25:48 +00001272
Douglas Gregorc34897d2009-04-09 22:27:44 +00001273 // We only know the PCH subblock ID.
1274 switch (BlockID) {
1275 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001276 if (Stream.ReadBlockInfoBlock()) {
1277 Error("Malformed BlockInfoBlock");
1278 return Failure;
1279 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001280 break;
1281 case pch::PCH_BLOCK_ID:
Douglas Gregorf6e1fb22009-04-26 00:07:37 +00001282 switch (ReadPCHBlock()) {
Douglas Gregor179cfb12009-04-10 20:39:37 +00001283 case Success:
1284 break;
1285
1286 case Failure:
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001287 return Failure;
Douglas Gregor179cfb12009-04-10 20:39:37 +00001288
1289 case IgnorePCH:
Douglas Gregorb5887f32009-04-10 21:16:55 +00001290 // FIXME: We could consider reading through to the end of this
1291 // PCH block, skipping subblocks, to see if there are other
1292 // PCH blocks elsewhere.
Douglas Gregor57885192009-04-27 21:28:04 +00001293
1294 // Clear out any preallocated source location entries, so that
1295 // the source manager does not try to resolve them later.
1296 PP.getSourceManager().ClearPreallocatedSLocEntries();
1297
1298 // Remove the stat cache.
1299 PP.getFileManager().setStatCache(0);
1300
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001301 return IgnorePCH;
Douglas Gregor179cfb12009-04-10 20:39:37 +00001302 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001303 break;
1304 default:
Douglas Gregorb3a04c82009-04-10 23:10:45 +00001305 if (Stream.SkipBlock()) {
1306 Error("Malformed block record");
1307 return Failure;
1308 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001309 break;
1310 }
1311 }
1312
1313 // Load the translation unit declaration
Chris Lattner270d29a2009-04-27 21:45:14 +00001314 if (Context)
1315 ReadDeclRecord(DeclOffsets[0], 0);
Douglas Gregor91137812009-04-28 20:33:11 +00001316
1317 // Check the predefines buffer.
1318 if (CheckPredefinesBuffer(PCHPredefines, PCHPredefinesLen,
1319 PCHPredefinesBufferID))
1320 return IgnorePCH;
1321
Douglas Gregorc713da92009-04-21 22:25:48 +00001322 // Initialization of builtins and library builtins occurs before the
1323 // PCH file is read, so there may be some identifiers that were
1324 // loaded into the IdentifierTable before we intercepted the
1325 // creation of identifiers. Iterate through the list of known
1326 // identifiers and determine whether we have to establish
1327 // preprocessor definitions or top-level identifier declaration
1328 // chains for those identifiers.
1329 //
1330 // We copy the IdentifierInfo pointers to a small vector first,
1331 // since de-serializing declarations or macro definitions can add
1332 // new entries into the identifier table, invalidating the
1333 // iterators.
1334 llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
1335 for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),
1336 IdEnd = PP.getIdentifierTable().end();
1337 Id != IdEnd; ++Id)
1338 Identifiers.push_back(Id->second);
1339 PCHIdentifierLookupTable *IdTable
1340 = (PCHIdentifierLookupTable *)IdentifierLookupTable;
1341 for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
1342 IdentifierInfo *II = Identifiers[I];
1343 // Look in the on-disk hash table for an entry for
1344 PCHIdentifierLookupTrait Info(*this, II);
1345 std::pair<const char*, unsigned> Key(II->getName(), II->getLength());
1346 PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
1347 if (Pos == IdTable->end())
1348 continue;
1349
1350 // Dereferencing the iterator has the effect of populating the
1351 // IdentifierInfo node with the various declarations it needs.
1352 (void)*Pos;
1353 }
1354
Douglas Gregore01ad442009-04-18 05:55:16 +00001355 // Load the special types.
Chris Lattner270d29a2009-04-27 21:45:14 +00001356 if (Context) {
1357 Context->setBuiltinVaListType(
1358 GetType(SpecialTypes[pch::SPECIAL_TYPE_BUILTIN_VA_LIST]));
1359 if (unsigned Id = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID])
1360 Context->setObjCIdType(GetType(Id));
1361 if (unsigned Sel = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SELECTOR])
1362 Context->setObjCSelType(GetType(Sel));
1363 if (unsigned Proto = SpecialTypes[pch::SPECIAL_TYPE_OBJC_PROTOCOL])
1364 Context->setObjCProtoType(GetType(Proto));
1365 if (unsigned Class = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS])
1366 Context->setObjCClassType(GetType(Class));
1367 if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_CF_CONSTANT_STRING])
1368 Context->setCFConstantStringType(GetType(String));
1369 if (unsigned FastEnum
1370 = SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
1371 Context->setObjCFastEnumerationStateType(GetType(FastEnum));
1372 }
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001373
Douglas Gregorc713da92009-04-21 22:25:48 +00001374 return Success;
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001375}
1376
Douglas Gregor179cfb12009-04-10 20:39:37 +00001377/// \brief Parse the record that corresponds to a LangOptions data
1378/// structure.
1379///
1380/// This routine compares the language options used to generate the
1381/// PCH file against the language options set for the current
1382/// compilation. For each option, we classify differences between the
1383/// two compiler states as either "benign" or "important". Benign
1384/// differences don't matter, and we accept them without complaint
1385/// (and without modifying the language options). Differences between
1386/// the states for important options cause the PCH file to be
1387/// unusable, so we emit a warning and return true to indicate that
1388/// there was an error.
1389///
1390/// \returns true if the PCH file is unacceptable, false otherwise.
1391bool PCHReader::ParseLanguageOptions(
1392 const llvm::SmallVectorImpl<uint64_t> &Record) {
Chris Lattner270d29a2009-04-27 21:45:14 +00001393 const LangOptions &LangOpts = PP.getLangOptions();
Douglas Gregor179cfb12009-04-10 20:39:37 +00001394#define PARSE_LANGOPT_BENIGN(Option) ++Idx
1395#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
1396 if (Record[Idx] != LangOpts.Option) { \
1397 Diag(DiagID) << (unsigned)Record[Idx] << LangOpts.Option; \
1398 Diag(diag::note_ignoring_pch) << FileName; \
1399 return true; \
1400 } \
1401 ++Idx
1402
1403 unsigned Idx = 0;
1404 PARSE_LANGOPT_BENIGN(Trigraphs);
1405 PARSE_LANGOPT_BENIGN(BCPLComment);
1406 PARSE_LANGOPT_BENIGN(DollarIdents);
1407 PARSE_LANGOPT_BENIGN(AsmPreprocessor);
1408 PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
1409 PARSE_LANGOPT_BENIGN(ImplicitInt);
1410 PARSE_LANGOPT_BENIGN(Digraphs);
1411 PARSE_LANGOPT_BENIGN(HexFloats);
1412 PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
1413 PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
1414 PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
1415 PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
Douglas Gregor179cfb12009-04-10 20:39:37 +00001416 PARSE_LANGOPT_BENIGN(CXXOperatorName);
1417 PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
1418 PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
1419 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
1420 PARSE_LANGOPT_BENIGN(PascalStrings);
Douglas Gregor179cfb12009-04-10 20:39:37 +00001421 PARSE_LANGOPT_BENIGN(WritableStrings);
1422 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
1423 diag::warn_pch_lax_vector_conversions);
1424 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
1425 PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
1426 PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
1427 PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
1428 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
1429 diag::warn_pch_thread_safe_statics);
1430 PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
1431 PARSE_LANGOPT_BENIGN(EmitAllDecls);
1432 PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
1433 PARSE_LANGOPT_IMPORTANT(OverflowChecking, diag::warn_pch_overflow_checking);
1434 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
1435 diag::warn_pch_heinous_extensions);
1436 // FIXME: Most of the options below are benign if the macro wasn't
1437 // used. Unfortunately, this means that a PCH compiled without
1438 // optimization can't be used with optimization turned on, even
1439 // though the only thing that changes is whether __OPTIMIZE__ was
1440 // defined... but if __OPTIMIZE__ never showed up in the header, it
1441 // doesn't matter. We could consider making this some special kind
1442 // of check.
1443 PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
1444 PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
1445 PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
1446 PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
1447 PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
1448 PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
1449 if ((LangOpts.getGCMode() != 0) != (Record[Idx] != 0)) {
1450 Diag(diag::warn_pch_gc_mode)
1451 << (unsigned)Record[Idx] << LangOpts.getGCMode();
1452 Diag(diag::note_ignoring_pch) << FileName;
1453 return true;
1454 }
1455 ++Idx;
1456 PARSE_LANGOPT_BENIGN(getVisibilityMode());
1457 PARSE_LANGOPT_BENIGN(InstantiationDepth);
1458#undef PARSE_LANGOPT_IRRELEVANT
1459#undef PARSE_LANGOPT_BENIGN
1460
1461 return false;
1462}
1463
Douglas Gregorc34897d2009-04-09 22:27:44 +00001464/// \brief Read and return the type at the given offset.
1465///
1466/// This routine actually reads the record corresponding to the type
1467/// at the given offset in the bitstream. It is a helper routine for
1468/// GetType, which deals with reading type IDs.
1469QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001470 // Keep track of where we are in the stream, then jump back there
1471 // after reading this type.
1472 SavedStreamPosition SavedPosition(Stream);
1473
Douglas Gregorc34897d2009-04-09 22:27:44 +00001474 Stream.JumpToBit(Offset);
1475 RecordData Record;
1476 unsigned Code = Stream.ReadCode();
1477 switch ((pch::TypeCode)Stream.ReadRecord(Code, Record)) {
Douglas Gregorbdd4ba52009-04-15 22:00:08 +00001478 case pch::TYPE_EXT_QUAL: {
1479 assert(Record.size() == 3 &&
1480 "Incorrect encoding of extended qualifier type");
1481 QualType Base = GetType(Record[0]);
1482 QualType::GCAttrTypes GCAttr = (QualType::GCAttrTypes)Record[1];
1483 unsigned AddressSpace = Record[2];
1484
1485 QualType T = Base;
1486 if (GCAttr != QualType::GCNone)
Chris Lattner270d29a2009-04-27 21:45:14 +00001487 T = Context->getObjCGCQualType(T, GCAttr);
Douglas Gregorbdd4ba52009-04-15 22:00:08 +00001488 if (AddressSpace)
Chris Lattner270d29a2009-04-27 21:45:14 +00001489 T = Context->getAddrSpaceQualType(T, AddressSpace);
Douglas Gregorbdd4ba52009-04-15 22:00:08 +00001490 return T;
1491 }
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001492
Douglas Gregorc34897d2009-04-09 22:27:44 +00001493 case pch::TYPE_FIXED_WIDTH_INT: {
1494 assert(Record.size() == 2 && "Incorrect encoding of fixed-width int type");
Chris Lattner270d29a2009-04-27 21:45:14 +00001495 return Context->getFixedWidthIntType(Record[0], Record[1]);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001496 }
1497
1498 case pch::TYPE_COMPLEX: {
1499 assert(Record.size() == 1 && "Incorrect encoding of complex type");
1500 QualType ElemType = GetType(Record[0]);
Chris Lattner270d29a2009-04-27 21:45:14 +00001501 return Context->getComplexType(ElemType);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001502 }
1503
1504 case pch::TYPE_POINTER: {
1505 assert(Record.size() == 1 && "Incorrect encoding of pointer type");
1506 QualType PointeeType = GetType(Record[0]);
Chris Lattner270d29a2009-04-27 21:45:14 +00001507 return Context->getPointerType(PointeeType);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001508 }
1509
1510 case pch::TYPE_BLOCK_POINTER: {
1511 assert(Record.size() == 1 && "Incorrect encoding of block pointer type");
1512 QualType PointeeType = GetType(Record[0]);
Chris Lattner270d29a2009-04-27 21:45:14 +00001513 return Context->getBlockPointerType(PointeeType);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001514 }
1515
1516 case pch::TYPE_LVALUE_REFERENCE: {
1517 assert(Record.size() == 1 && "Incorrect encoding of lvalue reference type");
1518 QualType PointeeType = GetType(Record[0]);
Chris Lattner270d29a2009-04-27 21:45:14 +00001519 return Context->getLValueReferenceType(PointeeType);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001520 }
1521
1522 case pch::TYPE_RVALUE_REFERENCE: {
1523 assert(Record.size() == 1 && "Incorrect encoding of rvalue reference type");
1524 QualType PointeeType = GetType(Record[0]);
Chris Lattner270d29a2009-04-27 21:45:14 +00001525 return Context->getRValueReferenceType(PointeeType);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001526 }
1527
1528 case pch::TYPE_MEMBER_POINTER: {
1529 assert(Record.size() == 1 && "Incorrect encoding of member pointer type");
1530 QualType PointeeType = GetType(Record[0]);
1531 QualType ClassType = GetType(Record[1]);
Chris Lattner270d29a2009-04-27 21:45:14 +00001532 return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
Douglas Gregorc34897d2009-04-09 22:27:44 +00001533 }
1534
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001535 case pch::TYPE_CONSTANT_ARRAY: {
1536 QualType ElementType = GetType(Record[0]);
1537 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1538 unsigned IndexTypeQuals = Record[2];
1539 unsigned Idx = 3;
1540 llvm::APInt Size = ReadAPInt(Record, Idx);
Chris Lattner270d29a2009-04-27 21:45:14 +00001541 return Context->getConstantArrayType(ElementType, Size, ASM,IndexTypeQuals);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001542 }
1543
1544 case pch::TYPE_INCOMPLETE_ARRAY: {
1545 QualType ElementType = GetType(Record[0]);
1546 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1547 unsigned IndexTypeQuals = Record[2];
Chris Lattner270d29a2009-04-27 21:45:14 +00001548 return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001549 }
1550
1551 case pch::TYPE_VARIABLE_ARRAY: {
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001552 QualType ElementType = GetType(Record[0]);
1553 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1554 unsigned IndexTypeQuals = Record[2];
Chris Lattner270d29a2009-04-27 21:45:14 +00001555 return Context->getVariableArrayType(ElementType, ReadTypeExpr(),
1556 ASM, IndexTypeQuals);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001557 }
1558
1559 case pch::TYPE_VECTOR: {
1560 if (Record.size() != 2) {
1561 Error("Incorrect encoding of vector type in PCH file");
1562 return QualType();
1563 }
1564
1565 QualType ElementType = GetType(Record[0]);
1566 unsigned NumElements = Record[1];
Chris Lattner270d29a2009-04-27 21:45:14 +00001567 return Context->getVectorType(ElementType, NumElements);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001568 }
1569
1570 case pch::TYPE_EXT_VECTOR: {
1571 if (Record.size() != 2) {
1572 Error("Incorrect encoding of extended vector type in PCH file");
1573 return QualType();
1574 }
1575
1576 QualType ElementType = GetType(Record[0]);
1577 unsigned NumElements = Record[1];
Chris Lattner270d29a2009-04-27 21:45:14 +00001578 return Context->getExtVectorType(ElementType, NumElements);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001579 }
1580
1581 case pch::TYPE_FUNCTION_NO_PROTO: {
1582 if (Record.size() != 1) {
1583 Error("Incorrect encoding of no-proto function type");
1584 return QualType();
1585 }
1586 QualType ResultType = GetType(Record[0]);
Chris Lattner270d29a2009-04-27 21:45:14 +00001587 return Context->getFunctionNoProtoType(ResultType);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001588 }
1589
1590 case pch::TYPE_FUNCTION_PROTO: {
1591 QualType ResultType = GetType(Record[0]);
1592 unsigned Idx = 1;
1593 unsigned NumParams = Record[Idx++];
1594 llvm::SmallVector<QualType, 16> ParamTypes;
1595 for (unsigned I = 0; I != NumParams; ++I)
1596 ParamTypes.push_back(GetType(Record[Idx++]));
1597 bool isVariadic = Record[Idx++];
1598 unsigned Quals = Record[Idx++];
Chris Lattner270d29a2009-04-27 21:45:14 +00001599 return Context->getFunctionType(ResultType, &ParamTypes[0], NumParams,
1600 isVariadic, Quals);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001601 }
1602
1603 case pch::TYPE_TYPEDEF:
1604 assert(Record.size() == 1 && "Incorrect encoding of typedef type");
Chris Lattner270d29a2009-04-27 21:45:14 +00001605 return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001606
1607 case pch::TYPE_TYPEOF_EXPR:
Chris Lattner270d29a2009-04-27 21:45:14 +00001608 return Context->getTypeOfExprType(ReadTypeExpr());
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001609
1610 case pch::TYPE_TYPEOF: {
1611 if (Record.size() != 1) {
1612 Error("Incorrect encoding of typeof(type) in PCH file");
1613 return QualType();
1614 }
1615 QualType UnderlyingType = GetType(Record[0]);
Chris Lattner270d29a2009-04-27 21:45:14 +00001616 return Context->getTypeOfType(UnderlyingType);
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001617 }
1618
1619 case pch::TYPE_RECORD:
Douglas Gregor982365e2009-04-13 21:20:57 +00001620 assert(Record.size() == 1 && "Incorrect encoding of record type");
Chris Lattner270d29a2009-04-27 21:45:14 +00001621 return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001622
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001623 case pch::TYPE_ENUM:
1624 assert(Record.size() == 1 && "Incorrect encoding of enum type");
Chris Lattner270d29a2009-04-27 21:45:14 +00001625 return Context->getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00001626
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001627 case pch::TYPE_OBJC_INTERFACE:
Chris Lattner80f83c62009-04-22 05:57:30 +00001628 assert(Record.size() == 1 && "Incorrect encoding of objc interface type");
Chris Lattner270d29a2009-04-27 21:45:14 +00001629 return Context->getObjCInterfaceType(
Chris Lattner80f83c62009-04-22 05:57:30 +00001630 cast<ObjCInterfaceDecl>(GetDecl(Record[0])));
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001631
Chris Lattnerbab2c0f2009-04-22 06:45:28 +00001632 case pch::TYPE_OBJC_QUALIFIED_INTERFACE: {
1633 unsigned Idx = 0;
1634 ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
1635 unsigned NumProtos = Record[Idx++];
1636 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
1637 for (unsigned I = 0; I != NumProtos; ++I)
1638 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
Chris Lattner270d29a2009-04-27 21:45:14 +00001639 return Context->getObjCQualifiedInterfaceType(ItfD, &Protos[0], NumProtos);
Chris Lattnerbab2c0f2009-04-22 06:45:28 +00001640 }
Douglas Gregor88fd09d2009-04-13 20:46:52 +00001641
Chris Lattner9b9f2352009-04-22 06:40:03 +00001642 case pch::TYPE_OBJC_QUALIFIED_ID: {
1643 unsigned Idx = 0;
1644 unsigned NumProtos = Record[Idx++];
1645 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
1646 for (unsigned I = 0; I != NumProtos; ++I)
1647 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
Chris Lattner270d29a2009-04-27 21:45:14 +00001648 return Context->getObjCQualifiedIdType(&Protos[0], NumProtos);
Chris Lattner9b9f2352009-04-22 06:40:03 +00001649 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001650 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001651 // Suppress a GCC warning
1652 return QualType();
1653}
1654
Douglas Gregorc34897d2009-04-09 22:27:44 +00001655
Douglas Gregorac8f2802009-04-10 17:25:41 +00001656QualType PCHReader::GetType(pch::TypeID ID) {
Douglas Gregorc34897d2009-04-09 22:27:44 +00001657 unsigned Quals = ID & 0x07;
1658 unsigned Index = ID >> 3;
1659
1660 if (Index < pch::NUM_PREDEF_TYPE_IDS) {
1661 QualType T;
1662 switch ((pch::PredefinedTypeIDs)Index) {
1663 case pch::PREDEF_TYPE_NULL_ID: return QualType();
Chris Lattner270d29a2009-04-27 21:45:14 +00001664 case pch::PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
1665 case pch::PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001666
1667 case pch::PREDEF_TYPE_CHAR_U_ID:
1668 case pch::PREDEF_TYPE_CHAR_S_ID:
1669 // FIXME: Check that the signedness of CharTy is correct!
Chris Lattner270d29a2009-04-27 21:45:14 +00001670 T = Context->CharTy;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001671 break;
1672
Chris Lattner270d29a2009-04-27 21:45:14 +00001673 case pch::PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
1674 case pch::PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
1675 case pch::PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
1676 case pch::PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
1677 case pch::PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
1678 case pch::PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
1679 case pch::PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
1680 case pch::PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
1681 case pch::PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
1682 case pch::PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
1683 case pch::PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
1684 case pch::PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
1685 case pch::PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
1686 case pch::PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
1687 case pch::PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
1688 case pch::PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001689 }
1690
1691 assert(!T.isNull() && "Unknown predefined type");
1692 return T.getQualifiedType(Quals);
1693 }
1694
1695 Index -= pch::NUM_PREDEF_TYPE_IDS;
Douglas Gregore43f0972009-04-26 03:49:13 +00001696 assert(Index < TypesLoaded.size() && "Type index out-of-range");
Douglas Gregor24a224c2009-04-25 18:35:21 +00001697 if (!TypesLoaded[Index])
1698 TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]).getTypePtr();
Douglas Gregorc34897d2009-04-09 22:27:44 +00001699
Douglas Gregor24a224c2009-04-25 18:35:21 +00001700 return QualType(TypesLoaded[Index], Quals);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001701}
1702
Douglas Gregorac8f2802009-04-10 17:25:41 +00001703Decl *PCHReader::GetDecl(pch::DeclID ID) {
Douglas Gregorc34897d2009-04-09 22:27:44 +00001704 if (ID == 0)
1705 return 0;
1706
Douglas Gregor24a224c2009-04-25 18:35:21 +00001707 if (ID > DeclsLoaded.size()) {
1708 Error("Declaration ID out-of-range for PCH file");
1709 return 0;
1710 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001711
Douglas Gregor24a224c2009-04-25 18:35:21 +00001712 unsigned Index = ID - 1;
1713 if (!DeclsLoaded[Index])
1714 ReadDeclRecord(DeclOffsets[Index], Index);
1715
1716 return DeclsLoaded[Index];
Douglas Gregorc34897d2009-04-09 22:27:44 +00001717}
1718
Chris Lattner77055f62009-04-27 05:46:25 +00001719/// \brief Resolve the offset of a statement into a statement.
1720///
1721/// This operation will read a new statement from the external
1722/// source each time it is called, and is meant to be used via a
1723/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
1724Stmt *PCHReader::GetDeclStmt(uint64_t Offset) {
Chris Lattner3ef21962009-04-27 05:58:23 +00001725 // Since we know tha this statement is part of a decl, make sure to use the
1726 // decl cursor to read it.
1727 DeclsCursor.JumpToBit(Offset);
1728 return ReadStmt(DeclsCursor);
Douglas Gregor3b9a7c82009-04-18 00:07:54 +00001729}
1730
Douglas Gregorc34897d2009-04-09 22:27:44 +00001731bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
Douglas Gregorac8f2802009-04-10 17:25:41 +00001732 llvm::SmallVectorImpl<pch::DeclID> &Decls) {
Douglas Gregorc34897d2009-04-09 22:27:44 +00001733 assert(DC->hasExternalLexicalStorage() &&
1734 "DeclContext has no lexical decls in storage");
1735 uint64_t Offset = DeclContextOffsets[DC].first;
1736 assert(Offset && "DeclContext has no lexical decls in storage");
1737
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001738 // Keep track of where we are in the stream, then jump back there
1739 // after reading this context.
Chris Lattner85e3f642009-04-27 07:35:40 +00001740 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001741
Douglas Gregorc34897d2009-04-09 22:27:44 +00001742 // Load the record containing all of the declarations lexically in
1743 // this context.
Chris Lattner85e3f642009-04-27 07:35:40 +00001744 DeclsCursor.JumpToBit(Offset);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001745 RecordData Record;
Chris Lattner85e3f642009-04-27 07:35:40 +00001746 unsigned Code = DeclsCursor.ReadCode();
1747 unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
Douglas Gregor3c8ff3e2009-04-15 18:43:11 +00001748 (void)RecCode;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001749 assert(RecCode == pch::DECL_CONTEXT_LEXICAL && "Expected lexical block");
1750
1751 // Load all of the declaration IDs
1752 Decls.clear();
1753 Decls.insert(Decls.end(), Record.begin(), Record.end());
Douglas Gregoraf136d92009-04-22 22:34:57 +00001754 ++NumLexicalDeclContextsRead;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001755 return false;
1756}
1757
1758bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
Chris Lattner85e3f642009-04-27 07:35:40 +00001759 llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
Douglas Gregorc34897d2009-04-09 22:27:44 +00001760 assert(DC->hasExternalVisibleStorage() &&
1761 "DeclContext has no visible decls in storage");
1762 uint64_t Offset = DeclContextOffsets[DC].second;
1763 assert(Offset && "DeclContext has no visible decls in storage");
1764
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001765 // Keep track of where we are in the stream, then jump back there
1766 // after reading this context.
Chris Lattner85e3f642009-04-27 07:35:40 +00001767 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregorc10f86f2009-04-14 21:18:50 +00001768
Douglas Gregorc34897d2009-04-09 22:27:44 +00001769 // Load the record containing all of the declarations visible in
1770 // this context.
Chris Lattner85e3f642009-04-27 07:35:40 +00001771 DeclsCursor.JumpToBit(Offset);
Douglas Gregorc34897d2009-04-09 22:27:44 +00001772 RecordData Record;
Chris Lattner85e3f642009-04-27 07:35:40 +00001773 unsigned Code = DeclsCursor.ReadCode();
1774 unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
Douglas Gregor3c8ff3e2009-04-15 18:43:11 +00001775 (void)RecCode;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001776 assert(RecCode == pch::DECL_CONTEXT_VISIBLE && "Expected visible block");
1777 if (Record.size() == 0)
1778 return false;
1779
1780 Decls.clear();
1781
1782 unsigned Idx = 0;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001783 while (Idx < Record.size()) {
1784 Decls.push_back(VisibleDeclaration());
1785 Decls.back().Name = ReadDeclarationName(Record, Idx);
1786
Douglas Gregorc34897d2009-04-09 22:27:44 +00001787 unsigned Size = Record[Idx++];
Chris Lattner85e3f642009-04-27 07:35:40 +00001788 llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001789 LoadedDecls.reserve(Size);
1790 for (unsigned I = 0; I < Size; ++I)
1791 LoadedDecls.push_back(Record[Idx++]);
1792 }
1793
Douglas Gregoraf136d92009-04-22 22:34:57 +00001794 ++NumVisibleDeclContextsRead;
Douglas Gregorc34897d2009-04-09 22:27:44 +00001795 return false;
1796}
1797
Douglas Gregor631f6c62009-04-14 00:24:19 +00001798void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
Douglas Gregor405b6432009-04-22 19:09:20 +00001799 this->Consumer = Consumer;
1800
Douglas Gregor631f6c62009-04-14 00:24:19 +00001801 if (!Consumer)
1802 return;
1803
1804 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
1805 Decl *D = GetDecl(ExternalDefinitions[I]);
1806 DeclGroupRef DG(D);
1807 Consumer->HandleTopLevelDecl(DG);
1808 }
Douglas Gregorf93cfee2009-04-25 00:41:30 +00001809
1810 for (unsigned I = 0, N = InterestingDecls.size(); I != N; ++I) {
1811 DeclGroupRef DG(InterestingDecls[I]);
1812 Consumer->HandleTopLevelDecl(DG);
1813 }
Douglas Gregor631f6c62009-04-14 00:24:19 +00001814}
1815
Douglas Gregorc34897d2009-04-09 22:27:44 +00001816void PCHReader::PrintStats() {
1817 std::fprintf(stderr, "*** PCH Statistics:\n");
1818
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001819 unsigned NumTypesLoaded
1820 = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
1821 (Type *)0);
1822 unsigned NumDeclsLoaded
1823 = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
1824 (Decl *)0);
1825 unsigned NumIdentifiersLoaded
1826 = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
1827 IdentifiersLoaded.end(),
1828 (IdentifierInfo *)0);
1829 unsigned NumSelectorsLoaded
1830 = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
1831 SelectorsLoaded.end(),
1832 Selector());
Douglas Gregor9cf47422009-04-13 20:50:16 +00001833
Douglas Gregor6cc5d192009-04-27 18:38:38 +00001834 std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
1835 std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
Douglas Gregor32e231c2009-04-27 06:38:32 +00001836 if (TotalNumSLocEntries)
1837 std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
1838 NumSLocEntriesRead, TotalNumSLocEntries,
1839 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
Douglas Gregor24a224c2009-04-25 18:35:21 +00001840 if (!TypesLoaded.empty())
Douglas Gregor2d711832009-04-25 17:48:32 +00001841 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
Douglas Gregor24a224c2009-04-25 18:35:21 +00001842 NumTypesLoaded, (unsigned)TypesLoaded.size(),
1843 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
1844 if (!DeclsLoaded.empty())
Douglas Gregor2d711832009-04-25 17:48:32 +00001845 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
Douglas Gregor24a224c2009-04-25 18:35:21 +00001846 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
1847 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001848 if (!IdentifiersLoaded.empty())
Douglas Gregor2d711832009-04-25 17:48:32 +00001849 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001850 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
1851 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
Douglas Gregor2d711832009-04-25 17:48:32 +00001852 if (TotalNumSelectors)
1853 std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
1854 NumSelectorsLoaded, TotalNumSelectors,
1855 ((float)NumSelectorsLoaded/TotalNumSelectors * 100));
1856 if (TotalNumStatements)
1857 std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
1858 NumStatementsRead, TotalNumStatements,
1859 ((float)NumStatementsRead/TotalNumStatements * 100));
1860 if (TotalNumMacros)
1861 std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
1862 NumMacrosRead, TotalNumMacros,
1863 ((float)NumMacrosRead/TotalNumMacros * 100));
1864 if (TotalLexicalDeclContexts)
1865 std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
1866 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
1867 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
1868 * 100));
1869 if (TotalVisibleDeclContexts)
1870 std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
1871 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
1872 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
1873 * 100));
1874 if (TotalSelectorsInMethodPool) {
1875 std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
1876 NumMethodPoolSelectorsRead, TotalSelectorsInMethodPool,
1877 ((float)NumMethodPoolSelectorsRead/TotalSelectorsInMethodPool
1878 * 100));
1879 std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
1880 }
Douglas Gregorc34897d2009-04-09 22:27:44 +00001881 std::fprintf(stderr, "\n");
1882}
1883
Douglas Gregorc713da92009-04-21 22:25:48 +00001884void PCHReader::InitializeSema(Sema &S) {
1885 SemaObj = &S;
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001886 S.ExternalSource = this;
1887
Douglas Gregor2554cf22009-04-22 21:15:06 +00001888 // Makes sure any declarations that were deserialized "too early"
1889 // still get added to the identifier's declaration chains.
1890 for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
1891 SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(PreloadedDecls[I]));
1892 SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
Douglas Gregorc713da92009-04-21 22:25:48 +00001893 }
Douglas Gregor2554cf22009-04-22 21:15:06 +00001894 PreloadedDecls.clear();
Douglas Gregor77b2cd52009-04-22 22:02:47 +00001895
1896 // If there were any tentative definitions, deserialize them and add
1897 // them to Sema's table of tentative definitions.
1898 for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
1899 VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
1900 SemaObj->TentativeDefinitions[Var->getDeclName()] = Var;
1901 }
Douglas Gregor062d9482009-04-22 22:18:58 +00001902
1903 // If there were any locally-scoped external declarations,
1904 // deserialize them and add them to Sema's table of locally-scoped
1905 // external declarations.
1906 for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
1907 NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
1908 SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
1909 }
Douglas Gregorb36b20d2009-04-27 20:06:05 +00001910
1911 // If there were any ext_vector type declarations, deserialize them
1912 // and add them to Sema's vector of such declarations.
1913 for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
1914 SemaObj->ExtVectorDecls.push_back(
1915 cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
1916
1917 // If there were any Objective-C category implementations,
1918 // deserialize them and add them to Sema's vector of such
1919 // definitions.
1920 for (unsigned I = 0, N = ObjCCategoryImpls.size(); I != N; ++I)
1921 SemaObj->ObjCCategoryImpls.push_back(
1922 cast<ObjCCategoryImplDecl>(GetDecl(ObjCCategoryImpls[I])));
Douglas Gregorc713da92009-04-21 22:25:48 +00001923}
1924
1925IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
1926 // Try to find this name within our on-disk hash table
1927 PCHIdentifierLookupTable *IdTable
1928 = (PCHIdentifierLookupTable *)IdentifierLookupTable;
1929 std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
1930 PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
1931 if (Pos == IdTable->end())
1932 return 0;
1933
1934 // Dereferencing the iterator has the effect of building the
1935 // IdentifierInfo node and populating it with the various
1936 // declarations it needs.
1937 return *Pos;
1938}
1939
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001940std::pair<ObjCMethodList, ObjCMethodList>
1941PCHReader::ReadMethodPool(Selector Sel) {
1942 if (!MethodPoolLookupTable)
1943 return std::pair<ObjCMethodList, ObjCMethodList>();
1944
1945 // Try to find this selector within our on-disk hash table.
1946 PCHMethodPoolLookupTable *PoolTable
1947 = (PCHMethodPoolLookupTable*)MethodPoolLookupTable;
1948 PCHMethodPoolLookupTable::iterator Pos = PoolTable->find(Sel);
Douglas Gregor2d711832009-04-25 17:48:32 +00001949 if (Pos == PoolTable->end()) {
1950 ++NumMethodPoolMisses;
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001951 return std::pair<ObjCMethodList, ObjCMethodList>();;
Douglas Gregor2d711832009-04-25 17:48:32 +00001952 }
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001953
Douglas Gregor2d711832009-04-25 17:48:32 +00001954 ++NumMethodPoolSelectorsRead;
Douglas Gregorc3221aa2009-04-24 21:10:55 +00001955 return *Pos;
1956}
1957
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001958void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
Douglas Gregorc713da92009-04-21 22:25:48 +00001959 assert(ID && "Non-zero identifier ID required");
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001960 assert(ID <= IdentifiersLoaded.size() && "Identifier ID out of range");
1961 IdentifiersLoaded[ID - 1] = II;
Douglas Gregorc713da92009-04-21 22:25:48 +00001962}
1963
Chris Lattner29241862009-04-11 21:15:38 +00001964IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001965 if (ID == 0)
1966 return 0;
Chris Lattner29241862009-04-11 21:15:38 +00001967
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001968 if (!IdentifierTableData || IdentifiersLoaded.empty()) {
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001969 Error("No identifier table in PCH file");
1970 return 0;
1971 }
Chris Lattner29241862009-04-11 21:15:38 +00001972
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001973 if (!IdentifiersLoaded[ID - 1]) {
1974 uint32_t Offset = IdentifierOffsets[ID - 1];
Douglas Gregor4d7a6e42009-04-25 21:21:38 +00001975 const char *Str = IdentifierTableData + Offset;
Douglas Gregor85c4a872009-04-25 21:04:17 +00001976
Douglas Gregor68619772009-04-28 20:01:51 +00001977 // All of the strings in the PCH file are preceded by a 16-bit
1978 // length. Extract that 16-bit length to avoid having to execute
1979 // strlen().
1980 const char *StrLenPtr = Str - 2;
1981 unsigned StrLen = (((unsigned) StrLenPtr[0])
1982 | (((unsigned) StrLenPtr[1]) << 8)) - 1;
1983 IdentifiersLoaded[ID - 1]
1984 = &PP.getIdentifierTable().get(Str, Str + StrLen);
Douglas Gregor7a224cf2009-04-11 00:14:32 +00001985 }
Chris Lattner29241862009-04-11 21:15:38 +00001986
Douglas Gregorde44c9f2009-04-25 19:10:14 +00001987 return IdentifiersLoaded[ID - 1];
Douglas Gregorc34897d2009-04-09 22:27:44 +00001988}
1989
Douglas Gregor32e231c2009-04-27 06:38:32 +00001990void PCHReader::ReadSLocEntry(unsigned ID) {
1991 ReadSLocEntryRecord(ID);
1992}
1993
Steve Naroff9e84d782009-04-23 10:39:46 +00001994Selector PCHReader::DecodeSelector(unsigned ID) {
1995 if (ID == 0)
1996 return Selector();
1997
Douglas Gregor2d711832009-04-25 17:48:32 +00001998 if (!MethodPoolLookupTableData) {
Steve Naroff9e84d782009-04-23 10:39:46 +00001999 Error("No selector table in PCH file");
2000 return Selector();
2001 }
Douglas Gregor2d711832009-04-25 17:48:32 +00002002
2003 if (ID > TotalNumSelectors) {
Steve Naroff9e84d782009-04-23 10:39:46 +00002004 Error("Selector ID out of range");
2005 return Selector();
2006 }
Douglas Gregor2d711832009-04-25 17:48:32 +00002007
2008 unsigned Index = ID - 1;
2009 if (SelectorsLoaded[Index].getAsOpaquePtr() == 0) {
2010 // Load this selector from the selector table.
2011 // FIXME: endianness portability issues with SelectorOffsets table
2012 PCHMethodPoolLookupTrait Trait(*this);
2013 SelectorsLoaded[Index]
2014 = Trait.ReadKey(MethodPoolLookupTableData + SelectorOffsets[Index], 0);
2015 }
2016
2017 return SelectorsLoaded[Index];
Steve Naroff9e84d782009-04-23 10:39:46 +00002018}
2019
Douglas Gregorc34897d2009-04-09 22:27:44 +00002020DeclarationName
2021PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
2022 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
2023 switch (Kind) {
2024 case DeclarationName::Identifier:
2025 return DeclarationName(GetIdentifierInfo(Record, Idx));
2026
2027 case DeclarationName::ObjCZeroArgSelector:
2028 case DeclarationName::ObjCOneArgSelector:
2029 case DeclarationName::ObjCMultiArgSelector:
Steve Naroff104956f2009-04-23 15:15:40 +00002030 return DeclarationName(GetSelector(Record, Idx));
Douglas Gregorc34897d2009-04-09 22:27:44 +00002031
2032 case DeclarationName::CXXConstructorName:
Chris Lattner270d29a2009-04-27 21:45:14 +00002033 return Context->DeclarationNames.getCXXConstructorName(
Douglas Gregorc34897d2009-04-09 22:27:44 +00002034 GetType(Record[Idx++]));
2035
2036 case DeclarationName::CXXDestructorName:
Chris Lattner270d29a2009-04-27 21:45:14 +00002037 return Context->DeclarationNames.getCXXDestructorName(
Douglas Gregorc34897d2009-04-09 22:27:44 +00002038 GetType(Record[Idx++]));
2039
2040 case DeclarationName::CXXConversionFunctionName:
Chris Lattner270d29a2009-04-27 21:45:14 +00002041 return Context->DeclarationNames.getCXXConversionFunctionName(
Douglas Gregorc34897d2009-04-09 22:27:44 +00002042 GetType(Record[Idx++]));
2043
2044 case DeclarationName::CXXOperatorName:
Chris Lattner270d29a2009-04-27 21:45:14 +00002045 return Context->DeclarationNames.getCXXOperatorName(
Douglas Gregorc34897d2009-04-09 22:27:44 +00002046 (OverloadedOperatorKind)Record[Idx++]);
2047
2048 case DeclarationName::CXXUsingDirective:
2049 return DeclarationName::getUsingDirectiveName();
2050 }
2051
2052 // Required to silence GCC warning
2053 return DeclarationName();
2054}
Douglas Gregor179cfb12009-04-10 20:39:37 +00002055
Douglas Gregor47f1b2c2009-04-13 18:14:40 +00002056/// \brief Read an integral value
2057llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
2058 unsigned BitWidth = Record[Idx++];
2059 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
2060 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
2061 Idx += NumWords;
2062 return Result;
2063}
2064
2065/// \brief Read a signed integral value
2066llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
2067 bool isUnsigned = Record[Idx++];
2068 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
2069}
2070
Douglas Gregore2f37202009-04-14 21:55:33 +00002071/// \brief Read a floating-point value
2072llvm::APFloat PCHReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregore2f37202009-04-14 21:55:33 +00002073 return llvm::APFloat(ReadAPInt(Record, Idx));
2074}
2075
Douglas Gregor1c507882009-04-15 21:30:51 +00002076// \brief Read a string
2077std::string PCHReader::ReadString(const RecordData &Record, unsigned &Idx) {
2078 unsigned Len = Record[Idx++];
2079 std::string Result(&Record[Idx], &Record[Idx] + Len);
2080 Idx += Len;
2081 return Result;
2082}
2083
Douglas Gregor179cfb12009-04-10 20:39:37 +00002084DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
Douglas Gregorb3a04c82009-04-10 23:10:45 +00002085 return Diag(SourceLocation(), DiagID);
2086}
2087
2088DiagnosticBuilder PCHReader::Diag(SourceLocation Loc, unsigned DiagID) {
2089 return PP.getDiagnostics().Report(FullSourceLoc(Loc,
Chris Lattner270d29a2009-04-27 21:45:14 +00002090 PP.getSourceManager()),
Douglas Gregor179cfb12009-04-10 20:39:37 +00002091 DiagID);
2092}
Douglas Gregor9c4782a2009-04-17 00:04:06 +00002093
Douglas Gregorc713da92009-04-21 22:25:48 +00002094/// \brief Retrieve the identifier table associated with the
2095/// preprocessor.
2096IdentifierTable &PCHReader::getIdentifierTable() {
2097 return PP.getIdentifierTable();
2098}
2099
Douglas Gregor9c4782a2009-04-17 00:04:06 +00002100/// \brief Record that the given ID maps to the given switch-case
2101/// statement.
2102void PCHReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
2103 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
2104 SwitchCaseStmts[ID] = SC;
2105}
2106
2107/// \brief Retrieve the switch-case statement with the given ID.
2108SwitchCase *PCHReader::getSwitchCaseWithID(unsigned ID) {
2109 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
2110 return SwitchCaseStmts[ID];
2111}
Douglas Gregor6e411bf2009-04-17 18:18:49 +00002112
2113/// \brief Record that the given label statement has been
2114/// deserialized and has the given ID.
2115void PCHReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
2116 assert(LabelStmts.find(ID) == LabelStmts.end() &&
2117 "Deserialized label twice");
2118 LabelStmts[ID] = S;
2119
2120 // If we've already seen any goto statements that point to this
2121 // label, resolve them now.
2122 typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
2123 std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
2124 for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
2125 Goto->second->setLabel(S);
2126 UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
Douglas Gregor95a8fe32009-04-17 18:58:21 +00002127
2128 // If we've already seen any address-label statements that point to
2129 // this label, resolve them now.
2130 typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
2131 std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
2132 = UnresolvedAddrLabelExprs.equal_range(ID);
2133 for (AddrLabelIter AddrLabel = AddrLabels.first;
2134 AddrLabel != AddrLabels.second; ++AddrLabel)
2135 AddrLabel->second->setLabel(S);
2136 UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
Douglas Gregor6e411bf2009-04-17 18:18:49 +00002137}
2138
2139/// \brief Set the label of the given statement to the label
2140/// identified by ID.
2141///
2142/// Depending on the order in which the label and other statements
2143/// referencing that label occur, this operation may complete
2144/// immediately (updating the statement) or it may queue the
2145/// statement to be back-patched later.
2146void PCHReader::SetLabelOf(GotoStmt *S, unsigned ID) {
2147 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
2148 if (Label != LabelStmts.end()) {
2149 // We've already seen this label, so set the label of the goto and
2150 // we're done.
2151 S->setLabel(Label->second);
2152 } else {
2153 // We haven't seen this label yet, so add this goto to the set of
2154 // unresolved goto statements.
2155 UnresolvedGotoStmts.insert(std::make_pair(ID, S));
2156 }
2157}
Douglas Gregor95a8fe32009-04-17 18:58:21 +00002158
2159/// \brief Set the label of the given expression to the label
2160/// identified by ID.
2161///
2162/// Depending on the order in which the label and other statements
2163/// referencing that label occur, this operation may complete
2164/// immediately (updating the statement) or it may queue the
2165/// statement to be back-patched later.
2166void PCHReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
2167 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
2168 if (Label != LabelStmts.end()) {
2169 // We've already seen this label, so set the label of the
2170 // label-address expression and we're done.
2171 S->setLabel(Label->second);
2172 } else {
2173 // We haven't seen this label yet, so add this label-address
2174 // expression to the set of unresolved label-address expressions.
2175 UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
2176 }
2177}