blob: 7ca0300eed1ee1d64db278df7ff2ab26a99ebdf1 [file] [log] [blame]
Douglas Gregor2cf26342009-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 Lattner4c6f9522009-04-27 05:14:47 +000013
Douglas Gregor2cf26342009-04-09 22:27:44 +000014#include "clang/Frontend/PCHReader.h"
Douglas Gregor0a0428e2009-04-10 20:39:37 +000015#include "clang/Frontend/FrontendDiagnostic.h"
Douglas Gregor668c1a42009-04-21 22:25:48 +000016#include "../Sema/Sema.h" // FIXME: move Sema headers elsewhere
Douglas Gregorfdd01722009-04-14 00:24:19 +000017#include "clang/AST/ASTConsumer.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000018#include "clang/AST/ASTContext.h"
Douglas Gregor0b748912009-04-14 21:18:50 +000019#include "clang/AST/Expr.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000020#include "clang/AST/Type.h"
Chris Lattner42d42b52009-04-10 21:41:48 +000021#include "clang/Lex/MacroInfo.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000022#include "clang/Lex/Preprocessor.h"
Steve Naroff83d63c72009-04-24 20:03:17 +000023#include "clang/Lex/HeaderSearch.h"
Douglas Gregor668c1a42009-04-21 22:25:48 +000024#include "clang/Basic/OnDiskHashTable.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000025#include "clang/Basic/SourceManager.h"
Douglas Gregorbd945002009-04-13 16:31:14 +000026#include "clang/Basic/SourceManagerInternals.h"
Douglas Gregor14f79002009-04-10 03:52:48 +000027#include "clang/Basic/FileManager.h"
Douglas Gregor2bec0412009-04-10 21:16:55 +000028#include "clang/Basic/TargetInfo.h"
Douglas Gregor2cf26342009-04-09 22:27:44 +000029#include "llvm/Bitcode/BitstreamReader.h"
30#include "llvm/Support/Compiler.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include <algorithm>
33#include <cstdio>
Douglas Gregor4fed3f42009-04-27 18:38:38 +000034#include <sys/stat.h>
Douglas Gregor2cf26342009-04-09 22:27:44 +000035using namespace clang;
36
37//===----------------------------------------------------------------------===//
Douglas Gregor668c1a42009-04-21 22:25:48 +000038// PCH reader implementation
39//===----------------------------------------------------------------------===//
40
Chris Lattnerd1d64a02009-04-27 21:45:14 +000041PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context)
Chris Lattner4c6f9522009-04-27 05:14:47 +000042 : SemaObj(0), PP(PP), Context(Context), Consumer(0),
43 IdentifierTableData(0), IdentifierLookupTable(0),
44 IdentifierOffsets(0),
45 MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
46 TotalSelectorsInMethodPool(0), SelectorOffsets(0),
Douglas Gregor4fed3f42009-04-27 18:38:38 +000047 TotalNumSelectors(0), NumStatHits(0), NumStatMisses(0),
48 NumSLocEntriesRead(0), NumStatementsRead(0),
Douglas Gregor7f94b0b2009-04-27 06:38:32 +000049 NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
Chris Lattner4c6f9522009-04-27 05:14:47 +000050 NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0) { }
51
52PCHReader::~PCHReader() {}
53
Chris Lattnerda930612009-04-27 05:58:23 +000054Expr *PCHReader::ReadDeclExpr() {
55 return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
56}
57
58Expr *PCHReader::ReadTypeExpr() {
Chris Lattner52e97d12009-04-27 05:41:06 +000059 return dyn_cast_or_null<Expr>(ReadStmt(Stream));
Chris Lattner4c6f9522009-04-27 05:14:47 +000060}
61
62
Douglas Gregor668c1a42009-04-21 22:25:48 +000063namespace {
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +000064class VISIBILITY_HIDDEN PCHMethodPoolLookupTrait {
65 PCHReader &Reader;
66
67public:
68 typedef std::pair<ObjCMethodList, ObjCMethodList> data_type;
69
70 typedef Selector external_key_type;
71 typedef external_key_type internal_key_type;
72
73 explicit PCHMethodPoolLookupTrait(PCHReader &Reader) : Reader(Reader) { }
74
75 static bool EqualKey(const internal_key_type& a,
76 const internal_key_type& b) {
77 return a == b;
78 }
79
80 static unsigned ComputeHash(Selector Sel) {
81 unsigned N = Sel.getNumArgs();
82 if (N == 0)
83 ++N;
84 unsigned R = 5381;
85 for (unsigned I = 0; I != N; ++I)
86 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
87 R = clang::BernsteinHashPartial(II->getName(), II->getLength(), R);
88 return R;
89 }
90
91 // This hopefully will just get inlined and removed by the optimizer.
92 static const internal_key_type&
93 GetInternalKey(const external_key_type& x) { return x; }
94
95 static std::pair<unsigned, unsigned>
96 ReadKeyDataLength(const unsigned char*& d) {
97 using namespace clang::io;
98 unsigned KeyLen = ReadUnalignedLE16(d);
99 unsigned DataLen = ReadUnalignedLE16(d);
100 return std::make_pair(KeyLen, DataLen);
101 }
102
Douglas Gregor83941df2009-04-25 17:48:32 +0000103 internal_key_type ReadKey(const unsigned char* d, unsigned) {
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000104 using namespace clang::io;
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000105 SelectorTable &SelTable = Reader.getContext()->Selectors;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000106 unsigned N = ReadUnalignedLE16(d);
107 IdentifierInfo *FirstII
108 = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
109 if (N == 0)
110 return SelTable.getNullarySelector(FirstII);
111 else if (N == 1)
112 return SelTable.getUnarySelector(FirstII);
113
114 llvm::SmallVector<IdentifierInfo *, 16> Args;
115 Args.push_back(FirstII);
116 for (unsigned I = 1; I != N; ++I)
117 Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
118
119 return SelTable.getSelector(N, &Args[0]);
120 }
121
122 data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
123 using namespace clang::io;
124 unsigned NumInstanceMethods = ReadUnalignedLE16(d);
125 unsigned NumFactoryMethods = ReadUnalignedLE16(d);
126
127 data_type Result;
128
129 // Load instance methods
130 ObjCMethodList *Prev = 0;
131 for (unsigned I = 0; I != NumInstanceMethods; ++I) {
132 ObjCMethodDecl *Method
133 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
134 if (!Result.first.Method) {
135 // This is the first method, which is the easy case.
136 Result.first.Method = Method;
137 Prev = &Result.first;
138 continue;
139 }
140
141 Prev->Next = new ObjCMethodList(Method, 0);
142 Prev = Prev->Next;
143 }
144
145 // Load factory methods
146 Prev = 0;
147 for (unsigned I = 0; I != NumFactoryMethods; ++I) {
148 ObjCMethodDecl *Method
149 = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
150 if (!Result.second.Method) {
151 // This is the first method, which is the easy case.
152 Result.second.Method = Method;
153 Prev = &Result.second;
154 continue;
155 }
156
157 Prev->Next = new ObjCMethodList(Method, 0);
158 Prev = Prev->Next;
159 }
160
161 return Result;
162 }
163};
164
165} // end anonymous namespace
166
167/// \brief The on-disk hash table used for the global method pool.
168typedef OnDiskChainedHashTable<PCHMethodPoolLookupTrait>
169 PCHMethodPoolLookupTable;
170
171namespace {
Douglas Gregor668c1a42009-04-21 22:25:48 +0000172class VISIBILITY_HIDDEN PCHIdentifierLookupTrait {
173 PCHReader &Reader;
174
175 // If we know the IdentifierInfo in advance, it is here and we will
176 // not build a new one. Used when deserializing information about an
177 // identifier that was constructed before the PCH file was read.
178 IdentifierInfo *KnownII;
179
180public:
181 typedef IdentifierInfo * data_type;
182
183 typedef const std::pair<const char*, unsigned> external_key_type;
184
185 typedef external_key_type internal_key_type;
186
187 explicit PCHIdentifierLookupTrait(PCHReader &Reader, IdentifierInfo *II = 0)
188 : Reader(Reader), KnownII(II) { }
189
190 static bool EqualKey(const internal_key_type& a,
191 const internal_key_type& b) {
192 return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
193 : false;
194 }
195
196 static unsigned ComputeHash(const internal_key_type& a) {
197 return BernsteinHash(a.first, a.second);
198 }
199
200 // This hopefully will just get inlined and removed by the optimizer.
201 static const internal_key_type&
202 GetInternalKey(const external_key_type& x) { return x; }
203
204 static std::pair<unsigned, unsigned>
205 ReadKeyDataLength(const unsigned char*& d) {
206 using namespace clang::io;
Douglas Gregor5f8e3302009-04-25 20:26:24 +0000207 unsigned DataLen = ReadUnalignedLE16(d);
Douglas Gregord6595a42009-04-25 21:04:17 +0000208 unsigned KeyLen = ReadUnalignedLE16(d);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000209 return std::make_pair(KeyLen, DataLen);
210 }
211
212 static std::pair<const char*, unsigned>
213 ReadKey(const unsigned char* d, unsigned n) {
214 assert(n >= 2 && d[n-1] == '\0');
215 return std::make_pair((const char*) d, n-1);
216 }
217
218 IdentifierInfo *ReadData(const internal_key_type& k,
219 const unsigned char* d,
220 unsigned DataLen) {
221 using namespace clang::io;
Douglas Gregor6cfc1a82009-04-22 21:15:06 +0000222 uint32_t Bits = ReadUnalignedLE32(d);
Douglas Gregor2deaea32009-04-22 18:49:13 +0000223 bool CPlusPlusOperatorKeyword = Bits & 0x01;
224 Bits >>= 1;
225 bool Poisoned = Bits & 0x01;
226 Bits >>= 1;
227 bool ExtensionToken = Bits & 0x01;
228 Bits >>= 1;
229 bool hasMacroDefinition = Bits & 0x01;
230 Bits >>= 1;
231 unsigned ObjCOrBuiltinID = Bits & 0x3FF;
232 Bits >>= 10;
233 unsigned TokenID = Bits & 0xFF;
234 Bits >>= 8;
235
Douglas Gregor668c1a42009-04-21 22:25:48 +0000236 pch::IdentID ID = ReadUnalignedLE32(d);
Douglas Gregor2deaea32009-04-22 18:49:13 +0000237 assert(Bits == 0 && "Extra bits in the identifier?");
Douglas Gregor668c1a42009-04-21 22:25:48 +0000238 DataLen -= 8;
239
240 // Build the IdentifierInfo itself and link the identifier ID with
241 // the new IdentifierInfo.
242 IdentifierInfo *II = KnownII;
243 if (!II)
Douglas Gregor5f8e3302009-04-25 20:26:24 +0000244 II = &Reader.getIdentifierTable().CreateIdentifierInfo(
245 k.first, k.first + k.second);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000246 Reader.SetIdentifierInfo(ID, II);
247
Douglas Gregor2deaea32009-04-22 18:49:13 +0000248 // Set or check the various bits in the IdentifierInfo structure.
249 // FIXME: Load token IDs lazily, too?
250 assert((unsigned)II->getTokenID() == TokenID &&
251 "Incorrect token ID loaded");
252 (void)TokenID;
253 II->setObjCOrBuiltinID(ObjCOrBuiltinID);
254 assert(II->isExtensionToken() == ExtensionToken &&
255 "Incorrect extension token flag");
256 (void)ExtensionToken;
257 II->setIsPoisoned(Poisoned);
258 assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
259 "Incorrect C++ operator keyword flag");
260 (void)CPlusPlusOperatorKeyword;
261
Douglas Gregor37e26842009-04-21 23:56:24 +0000262 // If this identifier is a macro, deserialize the macro
263 // definition.
264 if (hasMacroDefinition) {
265 uint32_t Offset = ReadUnalignedLE64(d);
266 Reader.ReadMacroRecord(Offset);
267 DataLen -= 8;
268 }
Douglas Gregor668c1a42009-04-21 22:25:48 +0000269
270 // Read all of the declarations visible at global scope with this
271 // name.
272 Sema *SemaObj = Reader.getSema();
Chris Lattnercc7dea82009-04-27 22:02:30 +0000273 if (!SemaObj) return II;
274
Douglas Gregor668c1a42009-04-21 22:25:48 +0000275 while (DataLen > 0) {
276 NamedDecl *D = cast<NamedDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Douglas Gregor668c1a42009-04-21 22:25:48 +0000277 if (SemaObj) {
278 // Introduce this declaration into the translation-unit scope
279 // and add it to the declaration chain for this identifier, so
280 // that (unqualified) name lookup will find it.
281 SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(D));
282 SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
283 } else {
284 // Queue this declaration so that it will be added to the
285 // translation unit scope and identifier's declaration chain
286 // once a Sema object is known.
Douglas Gregor6cfc1a82009-04-22 21:15:06 +0000287 Reader.PreloadedDecls.push_back(D);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000288 }
289
290 DataLen -= 4;
291 }
292 return II;
293 }
294};
295
296} // end anonymous namespace
297
298/// \brief The on-disk hash table used to contain information about
299/// all of the identifiers in the program.
300typedef OnDiskChainedHashTable<PCHIdentifierLookupTrait>
301 PCHIdentifierLookupTable;
302
Douglas Gregor2cf26342009-04-09 22:27:44 +0000303// FIXME: use the diagnostics machinery
304static bool Error(const char *Str) {
305 std::fprintf(stderr, "%s\n", Str);
306 return true;
307}
308
Douglas Gregore1d918e2009-04-10 23:10:45 +0000309/// \brief Check the contents of the predefines buffer against the
310/// contents of the predefines buffer used to build the PCH file.
311///
312/// The contents of the two predefines buffers should be the same. If
313/// not, then some command-line option changed the preprocessor state
314/// and we must reject the PCH file.
315///
316/// \param PCHPredef The start of the predefines buffer in the PCH
317/// file.
318///
319/// \param PCHPredefLen The length of the predefines buffer in the PCH
320/// file.
321///
322/// \param PCHBufferID The FileID for the PCH predefines buffer.
323///
324/// \returns true if there was a mismatch (in which case the PCH file
325/// should be ignored), or false otherwise.
326bool PCHReader::CheckPredefinesBuffer(const char *PCHPredef,
327 unsigned PCHPredefLen,
328 FileID PCHBufferID) {
329 const char *Predef = PP.getPredefines().c_str();
330 unsigned PredefLen = PP.getPredefines().size();
331
332 // If the two predefines buffers compare equal, we're done!.
333 if (PredefLen == PCHPredefLen &&
334 strncmp(Predef, PCHPredef, PCHPredefLen) == 0)
335 return false;
336
337 // The predefines buffers are different. Produce a reasonable
338 // diagnostic showing where they are different.
339
340 // The source locations (potentially in the two different predefines
341 // buffers)
342 SourceLocation Loc1, Loc2;
343 SourceManager &SourceMgr = PP.getSourceManager();
344
345 // Create a source buffer for our predefines string, so
346 // that we can build a diagnostic that points into that
347 // source buffer.
348 FileID BufferID;
349 if (Predef && Predef[0]) {
350 llvm::MemoryBuffer *Buffer
351 = llvm::MemoryBuffer::getMemBuffer(Predef, Predef + PredefLen,
352 "<built-in>");
353 BufferID = SourceMgr.createFileIDForMemBuffer(Buffer);
354 }
355
356 unsigned MinLen = std::min(PredefLen, PCHPredefLen);
357 std::pair<const char *, const char *> Locations
358 = std::mismatch(Predef, Predef + MinLen, PCHPredef);
359
360 if (Locations.first != Predef + MinLen) {
361 // We found the location in the two buffers where there is a
362 // difference. Form source locations to point there (in both
363 // buffers).
364 unsigned Offset = Locations.first - Predef;
365 Loc1 = SourceMgr.getLocForStartOfFile(BufferID)
366 .getFileLocWithOffset(Offset);
367 Loc2 = SourceMgr.getLocForStartOfFile(PCHBufferID)
368 .getFileLocWithOffset(Offset);
369 } else if (PredefLen > PCHPredefLen) {
370 Loc1 = SourceMgr.getLocForStartOfFile(BufferID)
371 .getFileLocWithOffset(MinLen);
372 } else {
373 Loc1 = SourceMgr.getLocForStartOfFile(PCHBufferID)
374 .getFileLocWithOffset(MinLen);
375 }
376
377 Diag(Loc1, diag::warn_pch_preprocessor);
378 if (Loc2.isValid())
379 Diag(Loc2, diag::note_predef_in_pch);
380 Diag(diag::note_ignoring_pch) << FileName;
381 return true;
382}
383
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000384//===----------------------------------------------------------------------===//
385// Source Manager Deserialization
386//===----------------------------------------------------------------------===//
387
Douglas Gregorbd945002009-04-13 16:31:14 +0000388/// \brief Read the line table in the source manager block.
389/// \returns true if ther was an error.
390static bool ParseLineTable(SourceManager &SourceMgr,
391 llvm::SmallVectorImpl<uint64_t> &Record) {
392 unsigned Idx = 0;
393 LineTableInfo &LineTable = SourceMgr.getLineTable();
394
395 // Parse the file names
Douglas Gregorff0a9872009-04-13 17:12:42 +0000396 std::map<int, int> FileIDs;
397 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregorbd945002009-04-13 16:31:14 +0000398 // Extract the file name
399 unsigned FilenameLen = Record[Idx++];
400 std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
401 Idx += FilenameLen;
Douglas Gregorff0a9872009-04-13 17:12:42 +0000402 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
403 Filename.size());
Douglas Gregorbd945002009-04-13 16:31:14 +0000404 }
405
406 // Parse the line entries
407 std::vector<LineEntry> Entries;
408 while (Idx < Record.size()) {
Douglas Gregorff0a9872009-04-13 17:12:42 +0000409 int FID = FileIDs[Record[Idx++]];
Douglas Gregorbd945002009-04-13 16:31:14 +0000410
411 // Extract the line entries
412 unsigned NumEntries = Record[Idx++];
413 Entries.clear();
414 Entries.reserve(NumEntries);
415 for (unsigned I = 0; I != NumEntries; ++I) {
416 unsigned FileOffset = Record[Idx++];
417 unsigned LineNo = Record[Idx++];
418 int FilenameID = Record[Idx++];
419 SrcMgr::CharacteristicKind FileKind
420 = (SrcMgr::CharacteristicKind)Record[Idx++];
421 unsigned IncludeOffset = Record[Idx++];
422 Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
423 FileKind, IncludeOffset));
424 }
425 LineTable.AddEntry(FID, Entries);
426 }
427
428 return false;
429}
430
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000431namespace {
432
433class VISIBILITY_HIDDEN PCHStatData {
434public:
435 const bool hasStat;
436 const ino_t ino;
437 const dev_t dev;
438 const mode_t mode;
439 const time_t mtime;
440 const off_t size;
441
442 PCHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
443 : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
444
445 PCHStatData()
446 : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
447};
448
449class VISIBILITY_HIDDEN PCHStatLookupTrait {
450 public:
451 typedef const char *external_key_type;
452 typedef const char *internal_key_type;
453
454 typedef PCHStatData data_type;
455
456 static unsigned ComputeHash(const char *path) {
457 return BernsteinHash(path);
458 }
459
460 static internal_key_type GetInternalKey(const char *path) { return path; }
461
462 static bool EqualKey(internal_key_type a, internal_key_type b) {
463 return strcmp(a, b) == 0;
464 }
465
466 static std::pair<unsigned, unsigned>
467 ReadKeyDataLength(const unsigned char*& d) {
468 unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
469 unsigned DataLen = (unsigned) *d++;
470 return std::make_pair(KeyLen + 1, DataLen);
471 }
472
473 static internal_key_type ReadKey(const unsigned char *d, unsigned) {
474 return (const char *)d;
475 }
476
477 static data_type ReadData(const internal_key_type, const unsigned char *d,
478 unsigned /*DataLen*/) {
479 using namespace clang::io;
480
481 if (*d++ == 1)
482 return data_type();
483
484 ino_t ino = (ino_t) ReadUnalignedLE32(d);
485 dev_t dev = (dev_t) ReadUnalignedLE32(d);
486 mode_t mode = (mode_t) ReadUnalignedLE16(d);
487 time_t mtime = (time_t) ReadUnalignedLE64(d);
488 off_t size = (off_t) ReadUnalignedLE64(d);
489 return data_type(ino, dev, mode, mtime, size);
490 }
491};
492
493/// \brief stat() cache for precompiled headers.
494///
495/// This cache is very similar to the stat cache used by pretokenized
496/// headers.
497class VISIBILITY_HIDDEN PCHStatCache : public StatSysCallCache {
498 typedef OnDiskChainedHashTable<PCHStatLookupTrait> CacheTy;
499 CacheTy *Cache;
500
501 unsigned &NumStatHits, &NumStatMisses;
502public:
503 PCHStatCache(const unsigned char *Buckets,
504 const unsigned char *Base,
505 unsigned &NumStatHits,
506 unsigned &NumStatMisses)
507 : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
508 Cache = CacheTy::Create(Buckets, Base);
509 }
510
511 ~PCHStatCache() { delete Cache; }
512
513 int stat(const char *path, struct stat *buf) {
514 // Do the lookup for the file's data in the PCH file.
515 CacheTy::iterator I = Cache->find(path);
516
517 // If we don't get a hit in the PCH file just forward to 'stat'.
518 if (I == Cache->end()) {
519 ++NumStatMisses;
520 return ::stat(path, buf);
521 }
522
523 ++NumStatHits;
524 PCHStatData Data = *I;
525
526 if (!Data.hasStat)
527 return 1;
528
529 buf->st_ino = Data.ino;
530 buf->st_dev = Data.dev;
531 buf->st_mtime = Data.mtime;
532 buf->st_mode = Data.mode;
533 buf->st_size = Data.size;
534 return 0;
535 }
536};
537} // end anonymous namespace
538
539
Douglas Gregor14f79002009-04-10 03:52:48 +0000540/// \brief Read the source manager block
Douglas Gregore1d918e2009-04-10 23:10:45 +0000541PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
Douglas Gregor14f79002009-04-10 03:52:48 +0000542 using namespace SrcMgr;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000543
544 // Set the source-location entry cursor to the current position in
545 // the stream. This cursor will be used to read the contents of the
546 // source manager block initially, and then lazily read
547 // source-location entries as needed.
548 SLocEntryCursor = Stream;
549
550 // The stream itself is going to skip over the source manager block.
551 if (Stream.SkipBlock()) {
552 Error("Malformed block record");
553 return Failure;
554 }
555
556 // Enter the source manager block.
557 if (SLocEntryCursor.EnterSubBlock(pch::SOURCE_MANAGER_BLOCK_ID)) {
Douglas Gregore1d918e2009-04-10 23:10:45 +0000558 Error("Malformed source manager block record");
559 return Failure;
560 }
Douglas Gregor14f79002009-04-10 03:52:48 +0000561
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000562 SourceManager &SourceMgr = PP.getSourceManager();
Douglas Gregor14f79002009-04-10 03:52:48 +0000563 RecordData Record;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +0000564 unsigned NumHeaderInfos = 0;
Douglas Gregor14f79002009-04-10 03:52:48 +0000565 while (true) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000566 unsigned Code = SLocEntryCursor.ReadCode();
Douglas Gregor14f79002009-04-10 03:52:48 +0000567 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000568 if (SLocEntryCursor.ReadBlockEnd()) {
Douglas Gregore1d918e2009-04-10 23:10:45 +0000569 Error("Error at end of Source Manager block");
570 return Failure;
571 }
Douglas Gregore1d918e2009-04-10 23:10:45 +0000572 return Success;
Douglas Gregor14f79002009-04-10 03:52:48 +0000573 }
574
575 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
576 // No known subblocks, always skip them.
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000577 SLocEntryCursor.ReadSubBlockID();
578 if (SLocEntryCursor.SkipBlock()) {
Douglas Gregore1d918e2009-04-10 23:10:45 +0000579 Error("Malformed block record");
580 return Failure;
581 }
Douglas Gregor14f79002009-04-10 03:52:48 +0000582 continue;
583 }
584
585 if (Code == llvm::bitc::DEFINE_ABBREV) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000586 SLocEntryCursor.ReadAbbrevRecord();
Douglas Gregor14f79002009-04-10 03:52:48 +0000587 continue;
588 }
589
590 // Read a record.
591 const char *BlobStart;
592 unsigned BlobLen;
593 Record.clear();
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000594 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
Douglas Gregor14f79002009-04-10 03:52:48 +0000595 default: // Default behavior: ignore.
596 break;
597
Chris Lattner2c78b872009-04-14 23:22:57 +0000598 case pch::SM_LINE_TABLE:
Douglas Gregorbd945002009-04-13 16:31:14 +0000599 if (ParseLineTable(SourceMgr, Record))
600 return Failure;
Chris Lattner2c78b872009-04-14 23:22:57 +0000601 break;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +0000602
603 case pch::SM_HEADER_FILE_INFO: {
604 HeaderFileInfo HFI;
605 HFI.isImport = Record[0];
606 HFI.DirInfo = Record[1];
607 HFI.NumIncludes = Record[2];
608 HFI.ControllingMacroID = Record[3];
609 PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
610 break;
611 }
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000612
613 case pch::SM_SLOC_FILE_ENTRY:
614 case pch::SM_SLOC_BUFFER_ENTRY:
615 case pch::SM_SLOC_INSTANTIATION_ENTRY:
616 // Once we hit one of the source location entries, we're done.
617 return Success;
Douglas Gregor14f79002009-04-10 03:52:48 +0000618 }
619 }
620}
621
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000622/// \brief Read in the source location entry with the given ID.
623PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {
624 if (ID == 0)
625 return Success;
626
627 if (ID > TotalNumSLocEntries) {
628 Error("source location entry ID out-of-range for PCH file");
629 return Failure;
630 }
631
632 ++NumSLocEntriesRead;
633 SLocEntryCursor.JumpToBit(SLocOffsets[ID - 1]);
634 unsigned Code = SLocEntryCursor.ReadCode();
635 if (Code == llvm::bitc::END_BLOCK ||
636 Code == llvm::bitc::ENTER_SUBBLOCK ||
637 Code == llvm::bitc::DEFINE_ABBREV) {
638 Error("incorrectly-formatted source location entry in PCH file");
639 return Failure;
640 }
641
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000642 SourceManager &SourceMgr = PP.getSourceManager();
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000643 RecordData Record;
644 const char *BlobStart;
645 unsigned BlobLen;
646 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
647 default:
648 Error("incorrectly-formatted source location entry in PCH file");
649 return Failure;
650
651 case pch::SM_SLOC_FILE_ENTRY: {
652 const FileEntry *File
653 = PP.getFileManager().getFile(BlobStart, BlobStart + BlobLen);
654 // FIXME: Error recovery if file cannot be found.
655 FileID FID = SourceMgr.createFileID(File,
656 SourceLocation::getFromRawEncoding(Record[1]),
657 (SrcMgr::CharacteristicKind)Record[2],
658 ID, Record[0]);
659 if (Record[3])
660 const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
661 .setHasLineDirectives();
662
663 break;
664 }
665
666 case pch::SM_SLOC_BUFFER_ENTRY: {
667 const char *Name = BlobStart;
668 unsigned Offset = Record[0];
669 unsigned Code = SLocEntryCursor.ReadCode();
670 Record.clear();
671 unsigned RecCode
672 = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
673 assert(RecCode == pch::SM_SLOC_BUFFER_BLOB && "Ill-formed PCH file");
674 (void)RecCode;
675 llvm::MemoryBuffer *Buffer
676 = llvm::MemoryBuffer::getMemBuffer(BlobStart,
677 BlobStart + BlobLen - 1,
678 Name);
679 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
680
681 if (strcmp(Name, "<built-in>") == 0
682 && CheckPredefinesBuffer(BlobStart, BlobLen - 1, BufferID))
683 return IgnorePCH;
684
685 break;
686 }
687
688 case pch::SM_SLOC_INSTANTIATION_ENTRY: {
689 SourceLocation SpellingLoc
690 = SourceLocation::getFromRawEncoding(Record[1]);
691 SourceMgr.createInstantiationLoc(SpellingLoc,
692 SourceLocation::getFromRawEncoding(Record[2]),
693 SourceLocation::getFromRawEncoding(Record[3]),
694 Record[4],
695 ID,
696 Record[0]);
697 break;
698 }
699 }
700
701 return Success;
702}
703
Chris Lattner6367f6d2009-04-27 01:05:14 +0000704/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
705/// specified cursor. Read the abbreviations that are at the top of the block
706/// and then leave the cursor pointing into the block.
707bool PCHReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
708 unsigned BlockID) {
709 if (Cursor.EnterSubBlock(BlockID)) {
710 Error("Malformed block record");
711 return Failure;
712 }
713
Chris Lattner6367f6d2009-04-27 01:05:14 +0000714 while (true) {
715 unsigned Code = Cursor.ReadCode();
716
717 // We expect all abbrevs to be at the start of the block.
718 if (Code != llvm::bitc::DEFINE_ABBREV)
719 return false;
720 Cursor.ReadAbbrevRecord();
721 }
722}
723
Douglas Gregor37e26842009-04-21 23:56:24 +0000724void PCHReader::ReadMacroRecord(uint64_t Offset) {
725 // Keep track of where we are in the stream, then jump back there
726 // after reading this macro.
727 SavedStreamPosition SavedPosition(Stream);
728
729 Stream.JumpToBit(Offset);
730 RecordData Record;
731 llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
732 MacroInfo *Macro = 0;
Steve Naroff83d63c72009-04-24 20:03:17 +0000733
Douglas Gregor37e26842009-04-21 23:56:24 +0000734 while (true) {
735 unsigned Code = Stream.ReadCode();
736 switch (Code) {
737 case llvm::bitc::END_BLOCK:
738 return;
739
740 case llvm::bitc::ENTER_SUBBLOCK:
741 // No known subblocks, always skip them.
742 Stream.ReadSubBlockID();
743 if (Stream.SkipBlock()) {
744 Error("Malformed block record");
745 return;
746 }
747 continue;
748
749 case llvm::bitc::DEFINE_ABBREV:
750 Stream.ReadAbbrevRecord();
751 continue;
752 default: break;
753 }
754
755 // Read a record.
756 Record.clear();
757 pch::PreprocessorRecordTypes RecType =
758 (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
759 switch (RecType) {
Douglas Gregor37e26842009-04-21 23:56:24 +0000760 case pch::PP_MACRO_OBJECT_LIKE:
761 case pch::PP_MACRO_FUNCTION_LIKE: {
762 // If we already have a macro, that means that we've hit the end
763 // of the definition of the macro we were looking for. We're
764 // done.
765 if (Macro)
766 return;
767
768 IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
769 if (II == 0) {
770 Error("Macro must have a name");
771 return;
772 }
773 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
774 bool isUsed = Record[2];
775
776 MacroInfo *MI = PP.AllocateMacroInfo(Loc);
777 MI->setIsUsed(isUsed);
778
779 if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
780 // Decode function-like macro info.
781 bool isC99VarArgs = Record[3];
782 bool isGNUVarArgs = Record[4];
783 MacroArgs.clear();
784 unsigned NumArgs = Record[5];
785 for (unsigned i = 0; i != NumArgs; ++i)
786 MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
787
788 // Install function-like macro info.
789 MI->setIsFunctionLike();
790 if (isC99VarArgs) MI->setIsC99Varargs();
791 if (isGNUVarArgs) MI->setIsGNUVarargs();
792 MI->setArgumentList(&MacroArgs[0], MacroArgs.size(),
793 PP.getPreprocessorAllocator());
794 }
795
796 // Finally, install the macro.
797 PP.setMacroInfo(II, MI);
798
799 // Remember that we saw this macro last so that we add the tokens that
800 // form its body to it.
801 Macro = MI;
802 ++NumMacrosRead;
803 break;
804 }
805
806 case pch::PP_TOKEN: {
807 // If we see a TOKEN before a PP_MACRO_*, then the file is
808 // erroneous, just pretend we didn't see this.
809 if (Macro == 0) break;
810
811 Token Tok;
812 Tok.startToken();
813 Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
814 Tok.setLength(Record[1]);
815 if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
816 Tok.setIdentifierInfo(II);
817 Tok.setKind((tok::TokenKind)Record[3]);
818 Tok.setFlag((Token::TokenFlags)Record[4]);
819 Macro->AddTokenToBody(Tok);
820 break;
821 }
Steve Naroff83d63c72009-04-24 20:03:17 +0000822 }
Douglas Gregor37e26842009-04-21 23:56:24 +0000823 }
824}
825
Douglas Gregor668c1a42009-04-21 22:25:48 +0000826PCHReader::PCHReadResult
Douglas Gregor2eafc1b2009-04-26 00:07:37 +0000827PCHReader::ReadPCHBlock() {
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000828 if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
829 Error("Malformed block record");
830 return Failure;
831 }
Douglas Gregor2cf26342009-04-09 22:27:44 +0000832
833 // Read all of the records and blocks for the PCH file.
Douglas Gregor8038d512009-04-10 17:25:41 +0000834 RecordData Record;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000835 while (!Stream.AtEndOfStream()) {
836 unsigned Code = Stream.ReadCode();
837 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000838 if (Stream.ReadBlockEnd()) {
839 Error("Error at end of module block");
840 return Failure;
841 }
Chris Lattner7356a312009-04-11 21:15:38 +0000842
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000843 return Success;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000844 }
845
846 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
847 switch (Stream.ReadSubBlockID()) {
Douglas Gregor2cf26342009-04-09 22:27:44 +0000848 case pch::TYPES_BLOCK_ID: // Skip types block (lazily loaded)
849 default: // Skip unknown content.
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000850 if (Stream.SkipBlock()) {
851 Error("Malformed block record");
852 return Failure;
853 }
Douglas Gregor2cf26342009-04-09 22:27:44 +0000854 break;
855
Chris Lattner6367f6d2009-04-27 01:05:14 +0000856 case pch::DECLS_BLOCK_ID:
857 // We lazily load the decls block, but we want to set up the
858 // DeclsCursor cursor to point into it. Clone our current bitcode
859 // cursor to it, enter the block and read the abbrevs in that block.
860 // With the main cursor, we just skip over it.
861 DeclsCursor = Stream;
862 if (Stream.SkipBlock() || // Skip with the main cursor.
863 // Read the abbrevs.
864 ReadBlockAbbrevs(DeclsCursor, pch::DECLS_BLOCK_ID)) {
865 Error("Malformed block record");
866 return Failure;
867 }
868 break;
869
Chris Lattner7356a312009-04-11 21:15:38 +0000870 case pch::PREPROCESSOR_BLOCK_ID:
Chris Lattner7356a312009-04-11 21:15:38 +0000871 if (Stream.SkipBlock()) {
872 Error("Malformed block record");
873 return Failure;
874 }
875 break;
Steve Naroff90cd1bb2009-04-23 10:39:46 +0000876
Douglas Gregor14f79002009-04-10 03:52:48 +0000877 case pch::SOURCE_MANAGER_BLOCK_ID:
Douglas Gregore1d918e2009-04-10 23:10:45 +0000878 switch (ReadSourceManagerBlock()) {
879 case Success:
880 break;
881
882 case Failure:
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000883 Error("Malformed source manager block");
884 return Failure;
Douglas Gregore1d918e2009-04-10 23:10:45 +0000885
886 case IgnorePCH:
887 return IgnorePCH;
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000888 }
Douglas Gregor14f79002009-04-10 03:52:48 +0000889 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000890 }
Douglas Gregor8038d512009-04-10 17:25:41 +0000891 continue;
892 }
893
894 if (Code == llvm::bitc::DEFINE_ABBREV) {
895 Stream.ReadAbbrevRecord();
896 continue;
897 }
898
899 // Read and process a record.
900 Record.clear();
Douglas Gregor2bec0412009-04-10 21:16:55 +0000901 const char *BlobStart = 0;
902 unsigned BlobLen = 0;
903 switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record,
904 &BlobStart, &BlobLen)) {
Douglas Gregor8038d512009-04-10 17:25:41 +0000905 default: // Default behavior: ignore.
906 break;
907
908 case pch::TYPE_OFFSET:
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +0000909 if (!TypesLoaded.empty()) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000910 Error("Duplicate TYPE_OFFSET record in PCH file");
911 return Failure;
912 }
Chris Lattnerc732f5a2009-04-27 18:24:17 +0000913 TypeOffsets = (const uint32_t *)BlobStart;
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +0000914 TypesLoaded.resize(Record[0]);
Douglas Gregor8038d512009-04-10 17:25:41 +0000915 break;
916
917 case pch::DECL_OFFSET:
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +0000918 if (!DeclsLoaded.empty()) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000919 Error("Duplicate DECL_OFFSET record in PCH file");
920 return Failure;
921 }
Chris Lattnerc732f5a2009-04-27 18:24:17 +0000922 DeclOffsets = (const uint32_t *)BlobStart;
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +0000923 DeclsLoaded.resize(Record[0]);
Douglas Gregor8038d512009-04-10 17:25:41 +0000924 break;
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000925
926 case pch::LANGUAGE_OPTIONS:
927 if (ParseLanguageOptions(Record))
928 return IgnorePCH;
929 break;
Douglas Gregor2bec0412009-04-10 21:16:55 +0000930
Douglas Gregorafaf3082009-04-11 00:14:32 +0000931 case pch::TARGET_TRIPLE: {
Douglas Gregor2bec0412009-04-10 21:16:55 +0000932 std::string TargetTriple(BlobStart, BlobLen);
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000933 if (TargetTriple != PP.getTargetInfo().getTargetTriple()) {
Douglas Gregor2bec0412009-04-10 21:16:55 +0000934 Diag(diag::warn_pch_target_triple)
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000935 << TargetTriple << PP.getTargetInfo().getTargetTriple();
Douglas Gregor2bec0412009-04-10 21:16:55 +0000936 Diag(diag::note_ignoring_pch) << FileName;
937 return IgnorePCH;
938 }
939 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000940 }
Douglas Gregorafaf3082009-04-11 00:14:32 +0000941
942 case pch::IDENTIFIER_TABLE:
Douglas Gregor668c1a42009-04-21 22:25:48 +0000943 IdentifierTableData = BlobStart;
Douglas Gregor2b3a5a82009-04-25 19:10:14 +0000944 if (Record[0]) {
945 IdentifierLookupTable
946 = PCHIdentifierLookupTable::Create(
Douglas Gregor668c1a42009-04-21 22:25:48 +0000947 (const unsigned char *)IdentifierTableData + Record[0],
948 (const unsigned char *)IdentifierTableData,
949 PCHIdentifierLookupTrait(*this));
Douglas Gregor2b3a5a82009-04-25 19:10:14 +0000950 PP.getIdentifierTable().setExternalIdentifierLookup(this);
951 }
Douglas Gregorafaf3082009-04-11 00:14:32 +0000952 break;
953
954 case pch::IDENTIFIER_OFFSET:
Douglas Gregor2b3a5a82009-04-25 19:10:14 +0000955 if (!IdentifiersLoaded.empty()) {
Douglas Gregorafaf3082009-04-11 00:14:32 +0000956 Error("Duplicate IDENTIFIER_OFFSET record in PCH file");
957 return Failure;
958 }
Douglas Gregor2b3a5a82009-04-25 19:10:14 +0000959 IdentifierOffsets = (const uint32_t *)BlobStart;
960 IdentifiersLoaded.resize(Record[0]);
Douglas Gregor8c5a7602009-04-25 23:30:02 +0000961 PP.getHeaderSearchInfo().SetExternalLookup(this);
Douglas Gregorafaf3082009-04-11 00:14:32 +0000962 break;
Douglas Gregorfdd01722009-04-14 00:24:19 +0000963
964 case pch::EXTERNAL_DEFINITIONS:
965 if (!ExternalDefinitions.empty()) {
966 Error("Duplicate EXTERNAL_DEFINITIONS record in PCH file");
967 return Failure;
968 }
969 ExternalDefinitions.swap(Record);
970 break;
Douglas Gregor3e1af842009-04-17 22:13:46 +0000971
Douglas Gregorad1de002009-04-18 05:55:16 +0000972 case pch::SPECIAL_TYPES:
973 SpecialTypes.swap(Record);
974 break;
975
Douglas Gregor3e1af842009-04-17 22:13:46 +0000976 case pch::STATISTICS:
977 TotalNumStatements = Record[0];
Douglas Gregor37e26842009-04-21 23:56:24 +0000978 TotalNumMacros = Record[1];
Douglas Gregor25123082009-04-22 22:34:57 +0000979 TotalLexicalDeclContexts = Record[2];
980 TotalVisibleDeclContexts = Record[3];
Douglas Gregor3e1af842009-04-17 22:13:46 +0000981 break;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000982
Douglas Gregor4c0e86b2009-04-22 22:02:47 +0000983 case pch::TENTATIVE_DEFINITIONS:
984 if (!TentativeDefinitions.empty()) {
985 Error("Duplicate TENTATIVE_DEFINITIONS record in PCH file");
986 return Failure;
987 }
988 TentativeDefinitions.swap(Record);
989 break;
Douglas Gregor14c22f22009-04-22 22:18:58 +0000990
991 case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
992 if (!LocallyScopedExternalDecls.empty()) {
993 Error("Duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
994 return Failure;
995 }
996 LocallyScopedExternalDecls.swap(Record);
997 break;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000998
Douglas Gregor83941df2009-04-25 17:48:32 +0000999 case pch::SELECTOR_OFFSETS:
1000 SelectorOffsets = (const uint32_t *)BlobStart;
1001 TotalNumSelectors = Record[0];
1002 SelectorsLoaded.resize(TotalNumSelectors);
1003 break;
1004
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001005 case pch::METHOD_POOL:
Douglas Gregor83941df2009-04-25 17:48:32 +00001006 MethodPoolLookupTableData = (const unsigned char *)BlobStart;
1007 if (Record[0])
1008 MethodPoolLookupTable
1009 = PCHMethodPoolLookupTable::Create(
1010 MethodPoolLookupTableData + Record[0],
1011 MethodPoolLookupTableData,
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001012 PCHMethodPoolLookupTrait(*this));
Douglas Gregor83941df2009-04-25 17:48:32 +00001013 TotalSelectorsInMethodPool = Record[1];
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001014 break;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001015
1016 case pch::PP_COUNTER_VALUE:
1017 if (!Record.empty())
1018 PP.setCounterValue(Record[0]);
1019 break;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001020
1021 case pch::SOURCE_LOCATION_OFFSETS:
Chris Lattner090d9b52009-04-27 19:01:47 +00001022 SLocOffsets = (const uint32_t *)BlobStart;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001023 TotalNumSLocEntries = Record[0];
1024 PP.getSourceManager().PreallocateSLocEntries(this,
1025 TotalNumSLocEntries,
1026 Record[1]);
1027 break;
1028
1029 case pch::SOURCE_LOCATION_PRELOADS:
1030 for (unsigned I = 0, N = Record.size(); I != N; ++I) {
1031 PCHReadResult Result = ReadSLocEntryRecord(Record[I]);
1032 if (Result != Success)
1033 return Result;
1034 }
1035 break;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001036
1037 case pch::STAT_CACHE:
1038 PP.getFileManager().setStatCache(
1039 new PCHStatCache((const unsigned char *)BlobStart + Record[0],
1040 (const unsigned char *)BlobStart,
1041 NumStatHits, NumStatMisses));
1042 break;
Douglas Gregorb81c1702009-04-27 20:06:05 +00001043
1044 case pch::EXT_VECTOR_DECLS:
1045 if (!ExtVectorDecls.empty()) {
1046 Error("Duplicate EXT_VECTOR_DECLS record in PCH file");
1047 return Failure;
1048 }
1049 ExtVectorDecls.swap(Record);
1050 break;
1051
1052 case pch::OBJC_CATEGORY_IMPLEMENTATIONS:
1053 if (!ObjCCategoryImpls.empty()) {
1054 Error("Duplicate OBJC_CATEGORY_IMPLEMENTATIONS record in PCH file");
1055 return Failure;
1056 }
1057 ObjCCategoryImpls.swap(Record);
1058 break;
Douglas Gregorafaf3082009-04-11 00:14:32 +00001059 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001060 }
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001061 Error("Premature end of bitstream");
1062 return Failure;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001063}
1064
Douglas Gregore1d918e2009-04-10 23:10:45 +00001065PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001066 // Set the PCH file name.
1067 this->FileName = FileName;
1068
Douglas Gregor2cf26342009-04-09 22:27:44 +00001069 // Open the PCH file.
1070 std::string ErrStr;
1071 Buffer.reset(llvm::MemoryBuffer::getFile(FileName.c_str(), &ErrStr));
Douglas Gregore1d918e2009-04-10 23:10:45 +00001072 if (!Buffer) {
1073 Error(ErrStr.c_str());
1074 return IgnorePCH;
1075 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001076
1077 // Initialize the stream
Chris Lattnerb9fa9172009-04-26 20:59:20 +00001078 StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
1079 (const unsigned char *)Buffer->getBufferEnd());
1080 Stream.init(StreamFile);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001081
1082 // Sniff for the signature.
1083 if (Stream.Read(8) != 'C' ||
1084 Stream.Read(8) != 'P' ||
1085 Stream.Read(8) != 'C' ||
Douglas Gregore1d918e2009-04-10 23:10:45 +00001086 Stream.Read(8) != 'H') {
1087 Error("Not a PCH file");
1088 return IgnorePCH;
1089 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001090
Douglas Gregor2cf26342009-04-09 22:27:44 +00001091 while (!Stream.AtEndOfStream()) {
1092 unsigned Code = Stream.ReadCode();
1093
Douglas Gregore1d918e2009-04-10 23:10:45 +00001094 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
1095 Error("Invalid record at top-level");
1096 return Failure;
1097 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001098
1099 unsigned BlockID = Stream.ReadSubBlockID();
Douglas Gregor668c1a42009-04-21 22:25:48 +00001100
Douglas Gregor2cf26342009-04-09 22:27:44 +00001101 // We only know the PCH subblock ID.
1102 switch (BlockID) {
1103 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregore1d918e2009-04-10 23:10:45 +00001104 if (Stream.ReadBlockInfoBlock()) {
1105 Error("Malformed BlockInfoBlock");
1106 return Failure;
1107 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001108 break;
1109 case pch::PCH_BLOCK_ID:
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001110 switch (ReadPCHBlock()) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001111 case Success:
1112 break;
1113
1114 case Failure:
Douglas Gregore1d918e2009-04-10 23:10:45 +00001115 return Failure;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001116
1117 case IgnorePCH:
Douglas Gregor2bec0412009-04-10 21:16:55 +00001118 // FIXME: We could consider reading through to the end of this
1119 // PCH block, skipping subblocks, to see if there are other
1120 // PCH blocks elsewhere.
Douglas Gregor2bf1eb02009-04-27 21:28:04 +00001121
1122 // Clear out any preallocated source location entries, so that
1123 // the source manager does not try to resolve them later.
1124 PP.getSourceManager().ClearPreallocatedSLocEntries();
1125
1126 // Remove the stat cache.
1127 PP.getFileManager().setStatCache(0);
1128
Douglas Gregore1d918e2009-04-10 23:10:45 +00001129 return IgnorePCH;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001130 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001131 break;
1132 default:
Douglas Gregore1d918e2009-04-10 23:10:45 +00001133 if (Stream.SkipBlock()) {
1134 Error("Malformed block record");
1135 return Failure;
1136 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001137 break;
1138 }
1139 }
1140
1141 // Load the translation unit declaration
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001142 if (Context)
1143 ReadDeclRecord(DeclOffsets[0], 0);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001144
Douglas Gregor668c1a42009-04-21 22:25:48 +00001145 // Initialization of builtins and library builtins occurs before the
1146 // PCH file is read, so there may be some identifiers that were
1147 // loaded into the IdentifierTable before we intercepted the
1148 // creation of identifiers. Iterate through the list of known
1149 // identifiers and determine whether we have to establish
1150 // preprocessor definitions or top-level identifier declaration
1151 // chains for those identifiers.
1152 //
1153 // We copy the IdentifierInfo pointers to a small vector first,
1154 // since de-serializing declarations or macro definitions can add
1155 // new entries into the identifier table, invalidating the
1156 // iterators.
1157 llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
1158 for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),
1159 IdEnd = PP.getIdentifierTable().end();
1160 Id != IdEnd; ++Id)
1161 Identifiers.push_back(Id->second);
1162 PCHIdentifierLookupTable *IdTable
1163 = (PCHIdentifierLookupTable *)IdentifierLookupTable;
1164 for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
1165 IdentifierInfo *II = Identifiers[I];
1166 // Look in the on-disk hash table for an entry for
1167 PCHIdentifierLookupTrait Info(*this, II);
1168 std::pair<const char*, unsigned> Key(II->getName(), II->getLength());
1169 PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
1170 if (Pos == IdTable->end())
1171 continue;
1172
1173 // Dereferencing the iterator has the effect of populating the
1174 // IdentifierInfo node with the various declarations it needs.
1175 (void)*Pos;
1176 }
1177
Douglas Gregorad1de002009-04-18 05:55:16 +00001178 // Load the special types.
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001179 if (Context) {
1180 Context->setBuiltinVaListType(
1181 GetType(SpecialTypes[pch::SPECIAL_TYPE_BUILTIN_VA_LIST]));
1182 if (unsigned Id = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID])
1183 Context->setObjCIdType(GetType(Id));
1184 if (unsigned Sel = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SELECTOR])
1185 Context->setObjCSelType(GetType(Sel));
1186 if (unsigned Proto = SpecialTypes[pch::SPECIAL_TYPE_OBJC_PROTOCOL])
1187 Context->setObjCProtoType(GetType(Proto));
1188 if (unsigned Class = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS])
1189 Context->setObjCClassType(GetType(Class));
1190 if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_CF_CONSTANT_STRING])
1191 Context->setCFConstantStringType(GetType(String));
1192 if (unsigned FastEnum
1193 = SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
1194 Context->setObjCFastEnumerationStateType(GetType(FastEnum));
1195 }
Douglas Gregor0b748912009-04-14 21:18:50 +00001196
Douglas Gregor668c1a42009-04-21 22:25:48 +00001197 return Success;
Douglas Gregor0b748912009-04-14 21:18:50 +00001198}
1199
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001200/// \brief Parse the record that corresponds to a LangOptions data
1201/// structure.
1202///
1203/// This routine compares the language options used to generate the
1204/// PCH file against the language options set for the current
1205/// compilation. For each option, we classify differences between the
1206/// two compiler states as either "benign" or "important". Benign
1207/// differences don't matter, and we accept them without complaint
1208/// (and without modifying the language options). Differences between
1209/// the states for important options cause the PCH file to be
1210/// unusable, so we emit a warning and return true to indicate that
1211/// there was an error.
1212///
1213/// \returns true if the PCH file is unacceptable, false otherwise.
1214bool PCHReader::ParseLanguageOptions(
1215 const llvm::SmallVectorImpl<uint64_t> &Record) {
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001216 const LangOptions &LangOpts = PP.getLangOptions();
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001217#define PARSE_LANGOPT_BENIGN(Option) ++Idx
1218#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
1219 if (Record[Idx] != LangOpts.Option) { \
1220 Diag(DiagID) << (unsigned)Record[Idx] << LangOpts.Option; \
1221 Diag(diag::note_ignoring_pch) << FileName; \
1222 return true; \
1223 } \
1224 ++Idx
1225
1226 unsigned Idx = 0;
1227 PARSE_LANGOPT_BENIGN(Trigraphs);
1228 PARSE_LANGOPT_BENIGN(BCPLComment);
1229 PARSE_LANGOPT_BENIGN(DollarIdents);
1230 PARSE_LANGOPT_BENIGN(AsmPreprocessor);
1231 PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
1232 PARSE_LANGOPT_BENIGN(ImplicitInt);
1233 PARSE_LANGOPT_BENIGN(Digraphs);
1234 PARSE_LANGOPT_BENIGN(HexFloats);
1235 PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
1236 PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
1237 PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
1238 PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
1239 PARSE_LANGOPT_IMPORTANT(NoExtensions, diag::warn_pch_extensions);
1240 PARSE_LANGOPT_BENIGN(CXXOperatorName);
1241 PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
1242 PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
1243 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
1244 PARSE_LANGOPT_BENIGN(PascalStrings);
1245 PARSE_LANGOPT_BENIGN(Boolean);
1246 PARSE_LANGOPT_BENIGN(WritableStrings);
1247 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
1248 diag::warn_pch_lax_vector_conversions);
1249 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
1250 PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
1251 PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
1252 PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
1253 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
1254 diag::warn_pch_thread_safe_statics);
1255 PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
1256 PARSE_LANGOPT_BENIGN(EmitAllDecls);
1257 PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
1258 PARSE_LANGOPT_IMPORTANT(OverflowChecking, diag::warn_pch_overflow_checking);
1259 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
1260 diag::warn_pch_heinous_extensions);
1261 // FIXME: Most of the options below are benign if the macro wasn't
1262 // used. Unfortunately, this means that a PCH compiled without
1263 // optimization can't be used with optimization turned on, even
1264 // though the only thing that changes is whether __OPTIMIZE__ was
1265 // defined... but if __OPTIMIZE__ never showed up in the header, it
1266 // doesn't matter. We could consider making this some special kind
1267 // of check.
1268 PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
1269 PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
1270 PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
1271 PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
1272 PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
1273 PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
1274 if ((LangOpts.getGCMode() != 0) != (Record[Idx] != 0)) {
1275 Diag(diag::warn_pch_gc_mode)
1276 << (unsigned)Record[Idx] << LangOpts.getGCMode();
1277 Diag(diag::note_ignoring_pch) << FileName;
1278 return true;
1279 }
1280 ++Idx;
1281 PARSE_LANGOPT_BENIGN(getVisibilityMode());
1282 PARSE_LANGOPT_BENIGN(InstantiationDepth);
1283#undef PARSE_LANGOPT_IRRELEVANT
1284#undef PARSE_LANGOPT_BENIGN
1285
1286 return false;
1287}
1288
Douglas Gregor2cf26342009-04-09 22:27:44 +00001289/// \brief Read and return the type at the given offset.
1290///
1291/// This routine actually reads the record corresponding to the type
1292/// at the given offset in the bitstream. It is a helper routine for
1293/// GetType, which deals with reading type IDs.
1294QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
Douglas Gregor0b748912009-04-14 21:18:50 +00001295 // Keep track of where we are in the stream, then jump back there
1296 // after reading this type.
1297 SavedStreamPosition SavedPosition(Stream);
1298
Douglas Gregor2cf26342009-04-09 22:27:44 +00001299 Stream.JumpToBit(Offset);
1300 RecordData Record;
1301 unsigned Code = Stream.ReadCode();
1302 switch ((pch::TypeCode)Stream.ReadRecord(Code, Record)) {
Douglas Gregor6d473962009-04-15 22:00:08 +00001303 case pch::TYPE_EXT_QUAL: {
1304 assert(Record.size() == 3 &&
1305 "Incorrect encoding of extended qualifier type");
1306 QualType Base = GetType(Record[0]);
1307 QualType::GCAttrTypes GCAttr = (QualType::GCAttrTypes)Record[1];
1308 unsigned AddressSpace = Record[2];
1309
1310 QualType T = Base;
1311 if (GCAttr != QualType::GCNone)
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001312 T = Context->getObjCGCQualType(T, GCAttr);
Douglas Gregor6d473962009-04-15 22:00:08 +00001313 if (AddressSpace)
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001314 T = Context->getAddrSpaceQualType(T, AddressSpace);
Douglas Gregor6d473962009-04-15 22:00:08 +00001315 return T;
1316 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001317
Douglas Gregor2cf26342009-04-09 22:27:44 +00001318 case pch::TYPE_FIXED_WIDTH_INT: {
1319 assert(Record.size() == 2 && "Incorrect encoding of fixed-width int type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001320 return Context->getFixedWidthIntType(Record[0], Record[1]);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001321 }
1322
1323 case pch::TYPE_COMPLEX: {
1324 assert(Record.size() == 1 && "Incorrect encoding of complex type");
1325 QualType ElemType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001326 return Context->getComplexType(ElemType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001327 }
1328
1329 case pch::TYPE_POINTER: {
1330 assert(Record.size() == 1 && "Incorrect encoding of pointer type");
1331 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001332 return Context->getPointerType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001333 }
1334
1335 case pch::TYPE_BLOCK_POINTER: {
1336 assert(Record.size() == 1 && "Incorrect encoding of block pointer type");
1337 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001338 return Context->getBlockPointerType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001339 }
1340
1341 case pch::TYPE_LVALUE_REFERENCE: {
1342 assert(Record.size() == 1 && "Incorrect encoding of lvalue reference type");
1343 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001344 return Context->getLValueReferenceType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001345 }
1346
1347 case pch::TYPE_RVALUE_REFERENCE: {
1348 assert(Record.size() == 1 && "Incorrect encoding of rvalue reference type");
1349 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001350 return Context->getRValueReferenceType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001351 }
1352
1353 case pch::TYPE_MEMBER_POINTER: {
1354 assert(Record.size() == 1 && "Incorrect encoding of member pointer type");
1355 QualType PointeeType = GetType(Record[0]);
1356 QualType ClassType = GetType(Record[1]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001357 return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
Douglas Gregor2cf26342009-04-09 22:27:44 +00001358 }
1359
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001360 case pch::TYPE_CONSTANT_ARRAY: {
1361 QualType ElementType = GetType(Record[0]);
1362 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1363 unsigned IndexTypeQuals = Record[2];
1364 unsigned Idx = 3;
1365 llvm::APInt Size = ReadAPInt(Record, Idx);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001366 return Context->getConstantArrayType(ElementType, Size, ASM,IndexTypeQuals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001367 }
1368
1369 case pch::TYPE_INCOMPLETE_ARRAY: {
1370 QualType ElementType = GetType(Record[0]);
1371 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1372 unsigned IndexTypeQuals = Record[2];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001373 return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001374 }
1375
1376 case pch::TYPE_VARIABLE_ARRAY: {
Douglas Gregor0b748912009-04-14 21:18:50 +00001377 QualType ElementType = GetType(Record[0]);
1378 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1379 unsigned IndexTypeQuals = Record[2];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001380 return Context->getVariableArrayType(ElementType, ReadTypeExpr(),
1381 ASM, IndexTypeQuals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001382 }
1383
1384 case pch::TYPE_VECTOR: {
1385 if (Record.size() != 2) {
1386 Error("Incorrect encoding of vector type in PCH file");
1387 return QualType();
1388 }
1389
1390 QualType ElementType = GetType(Record[0]);
1391 unsigned NumElements = Record[1];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001392 return Context->getVectorType(ElementType, NumElements);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001393 }
1394
1395 case pch::TYPE_EXT_VECTOR: {
1396 if (Record.size() != 2) {
1397 Error("Incorrect encoding of extended vector type in PCH file");
1398 return QualType();
1399 }
1400
1401 QualType ElementType = GetType(Record[0]);
1402 unsigned NumElements = Record[1];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001403 return Context->getExtVectorType(ElementType, NumElements);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001404 }
1405
1406 case pch::TYPE_FUNCTION_NO_PROTO: {
1407 if (Record.size() != 1) {
1408 Error("Incorrect encoding of no-proto function type");
1409 return QualType();
1410 }
1411 QualType ResultType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001412 return Context->getFunctionNoProtoType(ResultType);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001413 }
1414
1415 case pch::TYPE_FUNCTION_PROTO: {
1416 QualType ResultType = GetType(Record[0]);
1417 unsigned Idx = 1;
1418 unsigned NumParams = Record[Idx++];
1419 llvm::SmallVector<QualType, 16> ParamTypes;
1420 for (unsigned I = 0; I != NumParams; ++I)
1421 ParamTypes.push_back(GetType(Record[Idx++]));
1422 bool isVariadic = Record[Idx++];
1423 unsigned Quals = Record[Idx++];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001424 return Context->getFunctionType(ResultType, &ParamTypes[0], NumParams,
1425 isVariadic, Quals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001426 }
1427
1428 case pch::TYPE_TYPEDEF:
1429 assert(Record.size() == 1 && "Incorrect encoding of typedef type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001430 return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001431
1432 case pch::TYPE_TYPEOF_EXPR:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001433 return Context->getTypeOfExprType(ReadTypeExpr());
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001434
1435 case pch::TYPE_TYPEOF: {
1436 if (Record.size() != 1) {
1437 Error("Incorrect encoding of typeof(type) in PCH file");
1438 return QualType();
1439 }
1440 QualType UnderlyingType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001441 return Context->getTypeOfType(UnderlyingType);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001442 }
1443
1444 case pch::TYPE_RECORD:
Douglas Gregor8c700062009-04-13 21:20:57 +00001445 assert(Record.size() == 1 && "Incorrect encoding of record type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001446 return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001447
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00001448 case pch::TYPE_ENUM:
1449 assert(Record.size() == 1 && "Incorrect encoding of enum type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001450 return Context->getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00001451
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001452 case pch::TYPE_OBJC_INTERFACE:
Chris Lattner4dcf151a2009-04-22 05:57:30 +00001453 assert(Record.size() == 1 && "Incorrect encoding of objc interface type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001454 return Context->getObjCInterfaceType(
Chris Lattner4dcf151a2009-04-22 05:57:30 +00001455 cast<ObjCInterfaceDecl>(GetDecl(Record[0])));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001456
Chris Lattnerc6fa4452009-04-22 06:45:28 +00001457 case pch::TYPE_OBJC_QUALIFIED_INTERFACE: {
1458 unsigned Idx = 0;
1459 ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
1460 unsigned NumProtos = Record[Idx++];
1461 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
1462 for (unsigned I = 0; I != NumProtos; ++I)
1463 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001464 return Context->getObjCQualifiedInterfaceType(ItfD, &Protos[0], NumProtos);
Chris Lattnerc6fa4452009-04-22 06:45:28 +00001465 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001466
Chris Lattnerd7a3fcd2009-04-22 06:40:03 +00001467 case pch::TYPE_OBJC_QUALIFIED_ID: {
1468 unsigned Idx = 0;
1469 unsigned NumProtos = Record[Idx++];
1470 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
1471 for (unsigned I = 0; I != NumProtos; ++I)
1472 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001473 return Context->getObjCQualifiedIdType(&Protos[0], NumProtos);
Chris Lattnerd7a3fcd2009-04-22 06:40:03 +00001474 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001475 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001476 // Suppress a GCC warning
1477 return QualType();
1478}
1479
Douglas Gregor2cf26342009-04-09 22:27:44 +00001480
Douglas Gregor8038d512009-04-10 17:25:41 +00001481QualType PCHReader::GetType(pch::TypeID ID) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00001482 unsigned Quals = ID & 0x07;
1483 unsigned Index = ID >> 3;
1484
1485 if (Index < pch::NUM_PREDEF_TYPE_IDS) {
1486 QualType T;
1487 switch ((pch::PredefinedTypeIDs)Index) {
1488 case pch::PREDEF_TYPE_NULL_ID: return QualType();
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001489 case pch::PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
1490 case pch::PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001491
1492 case pch::PREDEF_TYPE_CHAR_U_ID:
1493 case pch::PREDEF_TYPE_CHAR_S_ID:
1494 // FIXME: Check that the signedness of CharTy is correct!
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001495 T = Context->CharTy;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001496 break;
1497
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001498 case pch::PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
1499 case pch::PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
1500 case pch::PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
1501 case pch::PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
1502 case pch::PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
1503 case pch::PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
1504 case pch::PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
1505 case pch::PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
1506 case pch::PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
1507 case pch::PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
1508 case pch::PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
1509 case pch::PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
1510 case pch::PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
1511 case pch::PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
1512 case pch::PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
1513 case pch::PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001514 }
1515
1516 assert(!T.isNull() && "Unknown predefined type");
1517 return T.getQualifiedType(Quals);
1518 }
1519
1520 Index -= pch::NUM_PREDEF_TYPE_IDS;
Douglas Gregor366809a2009-04-26 03:49:13 +00001521 assert(Index < TypesLoaded.size() && "Type index out-of-range");
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001522 if (!TypesLoaded[Index])
1523 TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]).getTypePtr();
Douglas Gregor2cf26342009-04-09 22:27:44 +00001524
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001525 return QualType(TypesLoaded[Index], Quals);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001526}
1527
Douglas Gregor8038d512009-04-10 17:25:41 +00001528Decl *PCHReader::GetDecl(pch::DeclID ID) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00001529 if (ID == 0)
1530 return 0;
1531
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001532 if (ID > DeclsLoaded.size()) {
1533 Error("Declaration ID out-of-range for PCH file");
1534 return 0;
1535 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001536
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001537 unsigned Index = ID - 1;
1538 if (!DeclsLoaded[Index])
1539 ReadDeclRecord(DeclOffsets[Index], Index);
1540
1541 return DeclsLoaded[Index];
Douglas Gregor2cf26342009-04-09 22:27:44 +00001542}
1543
Chris Lattner887e2b32009-04-27 05:46:25 +00001544/// \brief Resolve the offset of a statement into a statement.
1545///
1546/// This operation will read a new statement from the external
1547/// source each time it is called, and is meant to be used via a
1548/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
1549Stmt *PCHReader::GetDeclStmt(uint64_t Offset) {
Chris Lattnerda930612009-04-27 05:58:23 +00001550 // Since we know tha this statement is part of a decl, make sure to use the
1551 // decl cursor to read it.
1552 DeclsCursor.JumpToBit(Offset);
1553 return ReadStmt(DeclsCursor);
Douglas Gregor250fc9c2009-04-18 00:07:54 +00001554}
1555
Douglas Gregor2cf26342009-04-09 22:27:44 +00001556bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
Douglas Gregor8038d512009-04-10 17:25:41 +00001557 llvm::SmallVectorImpl<pch::DeclID> &Decls) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00001558 assert(DC->hasExternalLexicalStorage() &&
1559 "DeclContext has no lexical decls in storage");
1560 uint64_t Offset = DeclContextOffsets[DC].first;
1561 assert(Offset && "DeclContext has no lexical decls in storage");
1562
Douglas Gregor0b748912009-04-14 21:18:50 +00001563 // Keep track of where we are in the stream, then jump back there
1564 // after reading this context.
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001565 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregor0b748912009-04-14 21:18:50 +00001566
Douglas Gregor2cf26342009-04-09 22:27:44 +00001567 // Load the record containing all of the declarations lexically in
1568 // this context.
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001569 DeclsCursor.JumpToBit(Offset);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001570 RecordData Record;
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001571 unsigned Code = DeclsCursor.ReadCode();
1572 unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
Douglas Gregor6a2bfb22009-04-15 18:43:11 +00001573 (void)RecCode;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001574 assert(RecCode == pch::DECL_CONTEXT_LEXICAL && "Expected lexical block");
1575
1576 // Load all of the declaration IDs
1577 Decls.clear();
1578 Decls.insert(Decls.end(), Record.begin(), Record.end());
Douglas Gregor25123082009-04-22 22:34:57 +00001579 ++NumLexicalDeclContextsRead;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001580 return false;
1581}
1582
1583bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001584 llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00001585 assert(DC->hasExternalVisibleStorage() &&
1586 "DeclContext has no visible decls in storage");
1587 uint64_t Offset = DeclContextOffsets[DC].second;
1588 assert(Offset && "DeclContext has no visible decls in storage");
1589
Douglas Gregor0b748912009-04-14 21:18:50 +00001590 // Keep track of where we are in the stream, then jump back there
1591 // after reading this context.
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001592 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregor0b748912009-04-14 21:18:50 +00001593
Douglas Gregor2cf26342009-04-09 22:27:44 +00001594 // Load the record containing all of the declarations visible in
1595 // this context.
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001596 DeclsCursor.JumpToBit(Offset);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001597 RecordData Record;
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001598 unsigned Code = DeclsCursor.ReadCode();
1599 unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
Douglas Gregor6a2bfb22009-04-15 18:43:11 +00001600 (void)RecCode;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001601 assert(RecCode == pch::DECL_CONTEXT_VISIBLE && "Expected visible block");
1602 if (Record.size() == 0)
1603 return false;
1604
1605 Decls.clear();
1606
1607 unsigned Idx = 0;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001608 while (Idx < Record.size()) {
1609 Decls.push_back(VisibleDeclaration());
1610 Decls.back().Name = ReadDeclarationName(Record, Idx);
1611
Douglas Gregor2cf26342009-04-09 22:27:44 +00001612 unsigned Size = Record[Idx++];
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001613 llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001614 LoadedDecls.reserve(Size);
1615 for (unsigned I = 0; I < Size; ++I)
1616 LoadedDecls.push_back(Record[Idx++]);
1617 }
1618
Douglas Gregor25123082009-04-22 22:34:57 +00001619 ++NumVisibleDeclContextsRead;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001620 return false;
1621}
1622
Douglas Gregorfdd01722009-04-14 00:24:19 +00001623void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
Douglas Gregor0af2ca42009-04-22 19:09:20 +00001624 this->Consumer = Consumer;
1625
Douglas Gregorfdd01722009-04-14 00:24:19 +00001626 if (!Consumer)
1627 return;
1628
1629 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
1630 Decl *D = GetDecl(ExternalDefinitions[I]);
1631 DeclGroupRef DG(D);
1632 Consumer->HandleTopLevelDecl(DG);
1633 }
Douglas Gregorc62a2fe2009-04-25 00:41:30 +00001634
1635 for (unsigned I = 0, N = InterestingDecls.size(); I != N; ++I) {
1636 DeclGroupRef DG(InterestingDecls[I]);
1637 Consumer->HandleTopLevelDecl(DG);
1638 }
Douglas Gregorfdd01722009-04-14 00:24:19 +00001639}
1640
Douglas Gregor2cf26342009-04-09 22:27:44 +00001641void PCHReader::PrintStats() {
1642 std::fprintf(stderr, "*** PCH Statistics:\n");
1643
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001644 unsigned NumTypesLoaded
1645 = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
1646 (Type *)0);
1647 unsigned NumDeclsLoaded
1648 = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
1649 (Decl *)0);
1650 unsigned NumIdentifiersLoaded
1651 = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
1652 IdentifiersLoaded.end(),
1653 (IdentifierInfo *)0);
1654 unsigned NumSelectorsLoaded
1655 = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
1656 SelectorsLoaded.end(),
1657 Selector());
Douglas Gregor2d41cc12009-04-13 20:50:16 +00001658
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001659 std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
1660 std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001661 if (TotalNumSLocEntries)
1662 std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
1663 NumSLocEntriesRead, TotalNumSLocEntries,
1664 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001665 if (!TypesLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00001666 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001667 NumTypesLoaded, (unsigned)TypesLoaded.size(),
1668 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
1669 if (!DeclsLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00001670 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001671 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
1672 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001673 if (!IdentifiersLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00001674 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001675 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
1676 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
Douglas Gregor83941df2009-04-25 17:48:32 +00001677 if (TotalNumSelectors)
1678 std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
1679 NumSelectorsLoaded, TotalNumSelectors,
1680 ((float)NumSelectorsLoaded/TotalNumSelectors * 100));
1681 if (TotalNumStatements)
1682 std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
1683 NumStatementsRead, TotalNumStatements,
1684 ((float)NumStatementsRead/TotalNumStatements * 100));
1685 if (TotalNumMacros)
1686 std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
1687 NumMacrosRead, TotalNumMacros,
1688 ((float)NumMacrosRead/TotalNumMacros * 100));
1689 if (TotalLexicalDeclContexts)
1690 std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
1691 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
1692 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
1693 * 100));
1694 if (TotalVisibleDeclContexts)
1695 std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
1696 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
1697 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
1698 * 100));
1699 if (TotalSelectorsInMethodPool) {
1700 std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
1701 NumMethodPoolSelectorsRead, TotalSelectorsInMethodPool,
1702 ((float)NumMethodPoolSelectorsRead/TotalSelectorsInMethodPool
1703 * 100));
1704 std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
1705 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001706 std::fprintf(stderr, "\n");
1707}
1708
Douglas Gregor668c1a42009-04-21 22:25:48 +00001709void PCHReader::InitializeSema(Sema &S) {
1710 SemaObj = &S;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001711 S.ExternalSource = this;
1712
Douglas Gregor6cfc1a82009-04-22 21:15:06 +00001713 // Makes sure any declarations that were deserialized "too early"
1714 // still get added to the identifier's declaration chains.
1715 for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
1716 SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(PreloadedDecls[I]));
1717 SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
Douglas Gregor668c1a42009-04-21 22:25:48 +00001718 }
Douglas Gregor6cfc1a82009-04-22 21:15:06 +00001719 PreloadedDecls.clear();
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00001720
1721 // If there were any tentative definitions, deserialize them and add
1722 // them to Sema's table of tentative definitions.
1723 for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
1724 VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
1725 SemaObj->TentativeDefinitions[Var->getDeclName()] = Var;
1726 }
Douglas Gregor14c22f22009-04-22 22:18:58 +00001727
1728 // If there were any locally-scoped external declarations,
1729 // deserialize them and add them to Sema's table of locally-scoped
1730 // external declarations.
1731 for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
1732 NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
1733 SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
1734 }
Douglas Gregorb81c1702009-04-27 20:06:05 +00001735
1736 // If there were any ext_vector type declarations, deserialize them
1737 // and add them to Sema's vector of such declarations.
1738 for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
1739 SemaObj->ExtVectorDecls.push_back(
1740 cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
1741
1742 // If there were any Objective-C category implementations,
1743 // deserialize them and add them to Sema's vector of such
1744 // definitions.
1745 for (unsigned I = 0, N = ObjCCategoryImpls.size(); I != N; ++I)
1746 SemaObj->ObjCCategoryImpls.push_back(
1747 cast<ObjCCategoryImplDecl>(GetDecl(ObjCCategoryImpls[I])));
Douglas Gregor668c1a42009-04-21 22:25:48 +00001748}
1749
1750IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
1751 // Try to find this name within our on-disk hash table
1752 PCHIdentifierLookupTable *IdTable
1753 = (PCHIdentifierLookupTable *)IdentifierLookupTable;
1754 std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
1755 PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
1756 if (Pos == IdTable->end())
1757 return 0;
1758
1759 // Dereferencing the iterator has the effect of building the
1760 // IdentifierInfo node and populating it with the various
1761 // declarations it needs.
1762 return *Pos;
1763}
1764
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001765std::pair<ObjCMethodList, ObjCMethodList>
1766PCHReader::ReadMethodPool(Selector Sel) {
1767 if (!MethodPoolLookupTable)
1768 return std::pair<ObjCMethodList, ObjCMethodList>();
1769
1770 // Try to find this selector within our on-disk hash table.
1771 PCHMethodPoolLookupTable *PoolTable
1772 = (PCHMethodPoolLookupTable*)MethodPoolLookupTable;
1773 PCHMethodPoolLookupTable::iterator Pos = PoolTable->find(Sel);
Douglas Gregor83941df2009-04-25 17:48:32 +00001774 if (Pos == PoolTable->end()) {
1775 ++NumMethodPoolMisses;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001776 return std::pair<ObjCMethodList, ObjCMethodList>();;
Douglas Gregor83941df2009-04-25 17:48:32 +00001777 }
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001778
Douglas Gregor83941df2009-04-25 17:48:32 +00001779 ++NumMethodPoolSelectorsRead;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001780 return *Pos;
1781}
1782
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001783void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
Douglas Gregor668c1a42009-04-21 22:25:48 +00001784 assert(ID && "Non-zero identifier ID required");
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001785 assert(ID <= IdentifiersLoaded.size() && "Identifier ID out of range");
1786 IdentifiersLoaded[ID - 1] = II;
Douglas Gregor668c1a42009-04-21 22:25:48 +00001787}
1788
Chris Lattner7356a312009-04-11 21:15:38 +00001789IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregorafaf3082009-04-11 00:14:32 +00001790 if (ID == 0)
1791 return 0;
Chris Lattner7356a312009-04-11 21:15:38 +00001792
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001793 if (!IdentifierTableData || IdentifiersLoaded.empty()) {
Douglas Gregorafaf3082009-04-11 00:14:32 +00001794 Error("No identifier table in PCH file");
1795 return 0;
1796 }
Chris Lattner7356a312009-04-11 21:15:38 +00001797
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001798 if (!IdentifiersLoaded[ID - 1]) {
1799 uint32_t Offset = IdentifierOffsets[ID - 1];
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001800 const char *Str = IdentifierTableData + Offset;
Douglas Gregord6595a42009-04-25 21:04:17 +00001801
1802 // If there is an identifier lookup table, but the offset of this
1803 // string is after the identifier table itself, then we know that
1804 // this string is not in the on-disk hash table. Therefore,
1805 // disable lookup into the hash table when looking for this
1806 // identifier.
1807 PCHIdentifierLookupTable *IdTable
1808 = (PCHIdentifierLookupTable *)IdentifierLookupTable;
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001809 if (!IdTable ||
1810 Offset >= uint32_t(IdTable->getBuckets() - IdTable->getBase())) {
1811 // Turn off lookup into the on-disk hash table. We know that
1812 // this identifier is not there.
1813 if (IdTable)
1814 PP.getIdentifierTable().setExternalIdentifierLookup(0);
Douglas Gregord6595a42009-04-25 21:04:17 +00001815
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001816 // All of the strings in the PCH file are preceded by a 16-bit
1817 // length. Extract that 16-bit length to avoid having to execute
1818 // strlen().
1819 const char *StrLenPtr = Str - 2;
1820 unsigned StrLen = (((unsigned) StrLenPtr[0])
1821 | (((unsigned) StrLenPtr[1]) << 8)) - 1;
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001822 IdentifiersLoaded[ID - 1]=&PP.getIdentifierTable().get(Str, Str + StrLen);
Douglas Gregord6595a42009-04-25 21:04:17 +00001823
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001824 // Turn on lookup into the on-disk hash table, if we have an
1825 // on-disk hash table.
1826 if (IdTable)
1827 PP.getIdentifierTable().setExternalIdentifierLookup(this);
1828 } else {
1829 // The identifier is a key in our on-disk hash table. Since we
1830 // know where the hash table entry starts, just read in this
1831 // (key, value) pair.
1832 PCHIdentifierLookupTrait Trait(const_cast<PCHReader &>(*this));
1833 const unsigned char *Pos = (const unsigned char *)Str - 4;
1834 std::pair<unsigned, unsigned> KeyDataLengths
1835 = Trait.ReadKeyDataLength(Pos);
Douglas Gregord6595a42009-04-25 21:04:17 +00001836
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001837 PCHIdentifierLookupTrait::internal_key_type InternalKey
1838 = Trait.ReadKey(Pos, KeyDataLengths.first);
1839 Pos = (const unsigned char *)Str + KeyDataLengths.first;
1840 IdentifiersLoaded[ID - 1] = Trait.ReadData(InternalKey, Pos,
1841 KeyDataLengths.second);
1842 }
Douglas Gregorafaf3082009-04-11 00:14:32 +00001843 }
Chris Lattner7356a312009-04-11 21:15:38 +00001844
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001845 return IdentifiersLoaded[ID - 1];
Douglas Gregor2cf26342009-04-09 22:27:44 +00001846}
1847
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001848void PCHReader::ReadSLocEntry(unsigned ID) {
1849 ReadSLocEntryRecord(ID);
1850}
1851
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001852Selector PCHReader::DecodeSelector(unsigned ID) {
1853 if (ID == 0)
1854 return Selector();
1855
Douglas Gregor83941df2009-04-25 17:48:32 +00001856 if (!MethodPoolLookupTableData) {
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001857 Error("No selector table in PCH file");
1858 return Selector();
1859 }
Douglas Gregor83941df2009-04-25 17:48:32 +00001860
1861 if (ID > TotalNumSelectors) {
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001862 Error("Selector ID out of range");
1863 return Selector();
1864 }
Douglas Gregor83941df2009-04-25 17:48:32 +00001865
1866 unsigned Index = ID - 1;
1867 if (SelectorsLoaded[Index].getAsOpaquePtr() == 0) {
1868 // Load this selector from the selector table.
1869 // FIXME: endianness portability issues with SelectorOffsets table
1870 PCHMethodPoolLookupTrait Trait(*this);
1871 SelectorsLoaded[Index]
1872 = Trait.ReadKey(MethodPoolLookupTableData + SelectorOffsets[Index], 0);
1873 }
1874
1875 return SelectorsLoaded[Index];
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001876}
1877
Douglas Gregor2cf26342009-04-09 22:27:44 +00001878DeclarationName
1879PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
1880 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
1881 switch (Kind) {
1882 case DeclarationName::Identifier:
1883 return DeclarationName(GetIdentifierInfo(Record, Idx));
1884
1885 case DeclarationName::ObjCZeroArgSelector:
1886 case DeclarationName::ObjCOneArgSelector:
1887 case DeclarationName::ObjCMultiArgSelector:
Steve Naroffa7503a72009-04-23 15:15:40 +00001888 return DeclarationName(GetSelector(Record, Idx));
Douglas Gregor2cf26342009-04-09 22:27:44 +00001889
1890 case DeclarationName::CXXConstructorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001891 return Context->DeclarationNames.getCXXConstructorName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00001892 GetType(Record[Idx++]));
1893
1894 case DeclarationName::CXXDestructorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001895 return Context->DeclarationNames.getCXXDestructorName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00001896 GetType(Record[Idx++]));
1897
1898 case DeclarationName::CXXConversionFunctionName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001899 return Context->DeclarationNames.getCXXConversionFunctionName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00001900 GetType(Record[Idx++]));
1901
1902 case DeclarationName::CXXOperatorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001903 return Context->DeclarationNames.getCXXOperatorName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00001904 (OverloadedOperatorKind)Record[Idx++]);
1905
1906 case DeclarationName::CXXUsingDirective:
1907 return DeclarationName::getUsingDirectiveName();
1908 }
1909
1910 // Required to silence GCC warning
1911 return DeclarationName();
1912}
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001913
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00001914/// \brief Read an integral value
1915llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
1916 unsigned BitWidth = Record[Idx++];
1917 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
1918 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
1919 Idx += NumWords;
1920 return Result;
1921}
1922
1923/// \brief Read a signed integral value
1924llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
1925 bool isUnsigned = Record[Idx++];
1926 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
1927}
1928
Douglas Gregor17fc2232009-04-14 21:55:33 +00001929/// \brief Read a floating-point value
1930llvm::APFloat PCHReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregor17fc2232009-04-14 21:55:33 +00001931 return llvm::APFloat(ReadAPInt(Record, Idx));
1932}
1933
Douglas Gregor68a2eb02009-04-15 21:30:51 +00001934// \brief Read a string
1935std::string PCHReader::ReadString(const RecordData &Record, unsigned &Idx) {
1936 unsigned Len = Record[Idx++];
1937 std::string Result(&Record[Idx], &Record[Idx] + Len);
1938 Idx += Len;
1939 return Result;
1940}
1941
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001942DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
Douglas Gregore1d918e2009-04-10 23:10:45 +00001943 return Diag(SourceLocation(), DiagID);
1944}
1945
1946DiagnosticBuilder PCHReader::Diag(SourceLocation Loc, unsigned DiagID) {
1947 return PP.getDiagnostics().Report(FullSourceLoc(Loc,
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001948 PP.getSourceManager()),
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001949 DiagID);
1950}
Douglas Gregor025452f2009-04-17 00:04:06 +00001951
Douglas Gregor668c1a42009-04-21 22:25:48 +00001952/// \brief Retrieve the identifier table associated with the
1953/// preprocessor.
1954IdentifierTable &PCHReader::getIdentifierTable() {
1955 return PP.getIdentifierTable();
1956}
1957
Douglas Gregor025452f2009-04-17 00:04:06 +00001958/// \brief Record that the given ID maps to the given switch-case
1959/// statement.
1960void PCHReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
1961 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
1962 SwitchCaseStmts[ID] = SC;
1963}
1964
1965/// \brief Retrieve the switch-case statement with the given ID.
1966SwitchCase *PCHReader::getSwitchCaseWithID(unsigned ID) {
1967 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
1968 return SwitchCaseStmts[ID];
1969}
Douglas Gregor1de05fe2009-04-17 18:18:49 +00001970
1971/// \brief Record that the given label statement has been
1972/// deserialized and has the given ID.
1973void PCHReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
1974 assert(LabelStmts.find(ID) == LabelStmts.end() &&
1975 "Deserialized label twice");
1976 LabelStmts[ID] = S;
1977
1978 // If we've already seen any goto statements that point to this
1979 // label, resolve them now.
1980 typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
1981 std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
1982 for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
1983 Goto->second->setLabel(S);
1984 UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00001985
1986 // If we've already seen any address-label statements that point to
1987 // this label, resolve them now.
1988 typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
1989 std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
1990 = UnresolvedAddrLabelExprs.equal_range(ID);
1991 for (AddrLabelIter AddrLabel = AddrLabels.first;
1992 AddrLabel != AddrLabels.second; ++AddrLabel)
1993 AddrLabel->second->setLabel(S);
1994 UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
Douglas Gregor1de05fe2009-04-17 18:18:49 +00001995}
1996
1997/// \brief Set the label of the given statement to the label
1998/// identified by ID.
1999///
2000/// Depending on the order in which the label and other statements
2001/// referencing that label occur, this operation may complete
2002/// immediately (updating the statement) or it may queue the
2003/// statement to be back-patched later.
2004void PCHReader::SetLabelOf(GotoStmt *S, unsigned ID) {
2005 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
2006 if (Label != LabelStmts.end()) {
2007 // We've already seen this label, so set the label of the goto and
2008 // we're done.
2009 S->setLabel(Label->second);
2010 } else {
2011 // We haven't seen this label yet, so add this goto to the set of
2012 // unresolved goto statements.
2013 UnresolvedGotoStmts.insert(std::make_pair(ID, S));
2014 }
2015}
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00002016
2017/// \brief Set the label of the given expression to the label
2018/// identified by ID.
2019///
2020/// Depending on the order in which the label and other statements
2021/// referencing that label occur, this operation may complete
2022/// immediately (updating the statement) or it may queue the
2023/// statement to be back-patched later.
2024void PCHReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
2025 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
2026 if (Label != LabelStmts.end()) {
2027 // We've already seen this label, so set the label of the
2028 // label-address expression and we're done.
2029 S->setLabel(Label->second);
2030 } else {
2031 // We haven't seen this label yet, so add this label-address
2032 // expression to the set of unresolved label-address expressions.
2033 UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
2034 }
2035}