blob: 7483f7854c60c0ddade3f08ef6f1e1334feec865 [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();
273 while (DataLen > 0) {
274 NamedDecl *D = cast<NamedDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
Douglas Gregor668c1a42009-04-21 22:25:48 +0000275 if (SemaObj) {
276 // Introduce this declaration into the translation-unit scope
277 // and add it to the declaration chain for this identifier, so
278 // that (unqualified) name lookup will find it.
279 SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(D));
280 SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
281 } else {
282 // Queue this declaration so that it will be added to the
283 // translation unit scope and identifier's declaration chain
284 // once a Sema object is known.
Douglas Gregor6cfc1a82009-04-22 21:15:06 +0000285 Reader.PreloadedDecls.push_back(D);
Douglas Gregor668c1a42009-04-21 22:25:48 +0000286 }
287
288 DataLen -= 4;
289 }
290 return II;
291 }
292};
293
294} // end anonymous namespace
295
296/// \brief The on-disk hash table used to contain information about
297/// all of the identifiers in the program.
298typedef OnDiskChainedHashTable<PCHIdentifierLookupTrait>
299 PCHIdentifierLookupTable;
300
Douglas Gregor2cf26342009-04-09 22:27:44 +0000301// FIXME: use the diagnostics machinery
302static bool Error(const char *Str) {
303 std::fprintf(stderr, "%s\n", Str);
304 return true;
305}
306
Douglas Gregore1d918e2009-04-10 23:10:45 +0000307/// \brief Check the contents of the predefines buffer against the
308/// contents of the predefines buffer used to build the PCH file.
309///
310/// The contents of the two predefines buffers should be the same. If
311/// not, then some command-line option changed the preprocessor state
312/// and we must reject the PCH file.
313///
314/// \param PCHPredef The start of the predefines buffer in the PCH
315/// file.
316///
317/// \param PCHPredefLen The length of the predefines buffer in the PCH
318/// file.
319///
320/// \param PCHBufferID The FileID for the PCH predefines buffer.
321///
322/// \returns true if there was a mismatch (in which case the PCH file
323/// should be ignored), or false otherwise.
324bool PCHReader::CheckPredefinesBuffer(const char *PCHPredef,
325 unsigned PCHPredefLen,
326 FileID PCHBufferID) {
327 const char *Predef = PP.getPredefines().c_str();
328 unsigned PredefLen = PP.getPredefines().size();
329
330 // If the two predefines buffers compare equal, we're done!.
331 if (PredefLen == PCHPredefLen &&
332 strncmp(Predef, PCHPredef, PCHPredefLen) == 0)
333 return false;
334
335 // The predefines buffers are different. Produce a reasonable
336 // diagnostic showing where they are different.
337
338 // The source locations (potentially in the two different predefines
339 // buffers)
340 SourceLocation Loc1, Loc2;
341 SourceManager &SourceMgr = PP.getSourceManager();
342
343 // Create a source buffer for our predefines string, so
344 // that we can build a diagnostic that points into that
345 // source buffer.
346 FileID BufferID;
347 if (Predef && Predef[0]) {
348 llvm::MemoryBuffer *Buffer
349 = llvm::MemoryBuffer::getMemBuffer(Predef, Predef + PredefLen,
350 "<built-in>");
351 BufferID = SourceMgr.createFileIDForMemBuffer(Buffer);
352 }
353
354 unsigned MinLen = std::min(PredefLen, PCHPredefLen);
355 std::pair<const char *, const char *> Locations
356 = std::mismatch(Predef, Predef + MinLen, PCHPredef);
357
358 if (Locations.first != Predef + MinLen) {
359 // We found the location in the two buffers where there is a
360 // difference. Form source locations to point there (in both
361 // buffers).
362 unsigned Offset = Locations.first - Predef;
363 Loc1 = SourceMgr.getLocForStartOfFile(BufferID)
364 .getFileLocWithOffset(Offset);
365 Loc2 = SourceMgr.getLocForStartOfFile(PCHBufferID)
366 .getFileLocWithOffset(Offset);
367 } else if (PredefLen > PCHPredefLen) {
368 Loc1 = SourceMgr.getLocForStartOfFile(BufferID)
369 .getFileLocWithOffset(MinLen);
370 } else {
371 Loc1 = SourceMgr.getLocForStartOfFile(PCHBufferID)
372 .getFileLocWithOffset(MinLen);
373 }
374
375 Diag(Loc1, diag::warn_pch_preprocessor);
376 if (Loc2.isValid())
377 Diag(Loc2, diag::note_predef_in_pch);
378 Diag(diag::note_ignoring_pch) << FileName;
379 return true;
380}
381
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000382//===----------------------------------------------------------------------===//
383// Source Manager Deserialization
384//===----------------------------------------------------------------------===//
385
Douglas Gregorbd945002009-04-13 16:31:14 +0000386/// \brief Read the line table in the source manager block.
387/// \returns true if ther was an error.
388static bool ParseLineTable(SourceManager &SourceMgr,
389 llvm::SmallVectorImpl<uint64_t> &Record) {
390 unsigned Idx = 0;
391 LineTableInfo &LineTable = SourceMgr.getLineTable();
392
393 // Parse the file names
Douglas Gregorff0a9872009-04-13 17:12:42 +0000394 std::map<int, int> FileIDs;
395 for (int I = 0, N = Record[Idx++]; I != N; ++I) {
Douglas Gregorbd945002009-04-13 16:31:14 +0000396 // Extract the file name
397 unsigned FilenameLen = Record[Idx++];
398 std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
399 Idx += FilenameLen;
Douglas Gregorff0a9872009-04-13 17:12:42 +0000400 FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
401 Filename.size());
Douglas Gregorbd945002009-04-13 16:31:14 +0000402 }
403
404 // Parse the line entries
405 std::vector<LineEntry> Entries;
406 while (Idx < Record.size()) {
Douglas Gregorff0a9872009-04-13 17:12:42 +0000407 int FID = FileIDs[Record[Idx++]];
Douglas Gregorbd945002009-04-13 16:31:14 +0000408
409 // Extract the line entries
410 unsigned NumEntries = Record[Idx++];
411 Entries.clear();
412 Entries.reserve(NumEntries);
413 for (unsigned I = 0; I != NumEntries; ++I) {
414 unsigned FileOffset = Record[Idx++];
415 unsigned LineNo = Record[Idx++];
416 int FilenameID = Record[Idx++];
417 SrcMgr::CharacteristicKind FileKind
418 = (SrcMgr::CharacteristicKind)Record[Idx++];
419 unsigned IncludeOffset = Record[Idx++];
420 Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
421 FileKind, IncludeOffset));
422 }
423 LineTable.AddEntry(FID, Entries);
424 }
425
426 return false;
427}
428
Douglas Gregor4fed3f42009-04-27 18:38:38 +0000429namespace {
430
431class VISIBILITY_HIDDEN PCHStatData {
432public:
433 const bool hasStat;
434 const ino_t ino;
435 const dev_t dev;
436 const mode_t mode;
437 const time_t mtime;
438 const off_t size;
439
440 PCHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
441 : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
442
443 PCHStatData()
444 : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
445};
446
447class VISIBILITY_HIDDEN PCHStatLookupTrait {
448 public:
449 typedef const char *external_key_type;
450 typedef const char *internal_key_type;
451
452 typedef PCHStatData data_type;
453
454 static unsigned ComputeHash(const char *path) {
455 return BernsteinHash(path);
456 }
457
458 static internal_key_type GetInternalKey(const char *path) { return path; }
459
460 static bool EqualKey(internal_key_type a, internal_key_type b) {
461 return strcmp(a, b) == 0;
462 }
463
464 static std::pair<unsigned, unsigned>
465 ReadKeyDataLength(const unsigned char*& d) {
466 unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
467 unsigned DataLen = (unsigned) *d++;
468 return std::make_pair(KeyLen + 1, DataLen);
469 }
470
471 static internal_key_type ReadKey(const unsigned char *d, unsigned) {
472 return (const char *)d;
473 }
474
475 static data_type ReadData(const internal_key_type, const unsigned char *d,
476 unsigned /*DataLen*/) {
477 using namespace clang::io;
478
479 if (*d++ == 1)
480 return data_type();
481
482 ino_t ino = (ino_t) ReadUnalignedLE32(d);
483 dev_t dev = (dev_t) ReadUnalignedLE32(d);
484 mode_t mode = (mode_t) ReadUnalignedLE16(d);
485 time_t mtime = (time_t) ReadUnalignedLE64(d);
486 off_t size = (off_t) ReadUnalignedLE64(d);
487 return data_type(ino, dev, mode, mtime, size);
488 }
489};
490
491/// \brief stat() cache for precompiled headers.
492///
493/// This cache is very similar to the stat cache used by pretokenized
494/// headers.
495class VISIBILITY_HIDDEN PCHStatCache : public StatSysCallCache {
496 typedef OnDiskChainedHashTable<PCHStatLookupTrait> CacheTy;
497 CacheTy *Cache;
498
499 unsigned &NumStatHits, &NumStatMisses;
500public:
501 PCHStatCache(const unsigned char *Buckets,
502 const unsigned char *Base,
503 unsigned &NumStatHits,
504 unsigned &NumStatMisses)
505 : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
506 Cache = CacheTy::Create(Buckets, Base);
507 }
508
509 ~PCHStatCache() { delete Cache; }
510
511 int stat(const char *path, struct stat *buf) {
512 // Do the lookup for the file's data in the PCH file.
513 CacheTy::iterator I = Cache->find(path);
514
515 // If we don't get a hit in the PCH file just forward to 'stat'.
516 if (I == Cache->end()) {
517 ++NumStatMisses;
518 return ::stat(path, buf);
519 }
520
521 ++NumStatHits;
522 PCHStatData Data = *I;
523
524 if (!Data.hasStat)
525 return 1;
526
527 buf->st_ino = Data.ino;
528 buf->st_dev = Data.dev;
529 buf->st_mtime = Data.mtime;
530 buf->st_mode = Data.mode;
531 buf->st_size = Data.size;
532 return 0;
533 }
534};
535} // end anonymous namespace
536
537
Douglas Gregor14f79002009-04-10 03:52:48 +0000538/// \brief Read the source manager block
Douglas Gregore1d918e2009-04-10 23:10:45 +0000539PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
Douglas Gregor14f79002009-04-10 03:52:48 +0000540 using namespace SrcMgr;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000541
542 // Set the source-location entry cursor to the current position in
543 // the stream. This cursor will be used to read the contents of the
544 // source manager block initially, and then lazily read
545 // source-location entries as needed.
546 SLocEntryCursor = Stream;
547
548 // The stream itself is going to skip over the source manager block.
549 if (Stream.SkipBlock()) {
550 Error("Malformed block record");
551 return Failure;
552 }
553
554 // Enter the source manager block.
555 if (SLocEntryCursor.EnterSubBlock(pch::SOURCE_MANAGER_BLOCK_ID)) {
Douglas Gregore1d918e2009-04-10 23:10:45 +0000556 Error("Malformed source manager block record");
557 return Failure;
558 }
Douglas Gregor14f79002009-04-10 03:52:48 +0000559
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000560 SourceManager &SourceMgr = PP.getSourceManager();
Douglas Gregor14f79002009-04-10 03:52:48 +0000561 RecordData Record;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +0000562 unsigned NumHeaderInfos = 0;
Douglas Gregor14f79002009-04-10 03:52:48 +0000563 while (true) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000564 unsigned Code = SLocEntryCursor.ReadCode();
Douglas Gregor14f79002009-04-10 03:52:48 +0000565 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000566 if (SLocEntryCursor.ReadBlockEnd()) {
Douglas Gregore1d918e2009-04-10 23:10:45 +0000567 Error("Error at end of Source Manager block");
568 return Failure;
569 }
Douglas Gregore1d918e2009-04-10 23:10:45 +0000570 return Success;
Douglas Gregor14f79002009-04-10 03:52:48 +0000571 }
572
573 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
574 // No known subblocks, always skip them.
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000575 SLocEntryCursor.ReadSubBlockID();
576 if (SLocEntryCursor.SkipBlock()) {
Douglas Gregore1d918e2009-04-10 23:10:45 +0000577 Error("Malformed block record");
578 return Failure;
579 }
Douglas Gregor14f79002009-04-10 03:52:48 +0000580 continue;
581 }
582
583 if (Code == llvm::bitc::DEFINE_ABBREV) {
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000584 SLocEntryCursor.ReadAbbrevRecord();
Douglas Gregor14f79002009-04-10 03:52:48 +0000585 continue;
586 }
587
588 // Read a record.
589 const char *BlobStart;
590 unsigned BlobLen;
591 Record.clear();
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000592 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
Douglas Gregor14f79002009-04-10 03:52:48 +0000593 default: // Default behavior: ignore.
594 break;
595
Chris Lattner2c78b872009-04-14 23:22:57 +0000596 case pch::SM_LINE_TABLE:
Douglas Gregorbd945002009-04-13 16:31:14 +0000597 if (ParseLineTable(SourceMgr, Record))
598 return Failure;
Chris Lattner2c78b872009-04-14 23:22:57 +0000599 break;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +0000600
601 case pch::SM_HEADER_FILE_INFO: {
602 HeaderFileInfo HFI;
603 HFI.isImport = Record[0];
604 HFI.DirInfo = Record[1];
605 HFI.NumIncludes = Record[2];
606 HFI.ControllingMacroID = Record[3];
607 PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
608 break;
609 }
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000610
611 case pch::SM_SLOC_FILE_ENTRY:
612 case pch::SM_SLOC_BUFFER_ENTRY:
613 case pch::SM_SLOC_INSTANTIATION_ENTRY:
614 // Once we hit one of the source location entries, we're done.
615 return Success;
Douglas Gregor14f79002009-04-10 03:52:48 +0000616 }
617 }
618}
619
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000620/// \brief Read in the source location entry with the given ID.
621PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {
622 if (ID == 0)
623 return Success;
624
625 if (ID > TotalNumSLocEntries) {
626 Error("source location entry ID out-of-range for PCH file");
627 return Failure;
628 }
629
630 ++NumSLocEntriesRead;
631 SLocEntryCursor.JumpToBit(SLocOffsets[ID - 1]);
632 unsigned Code = SLocEntryCursor.ReadCode();
633 if (Code == llvm::bitc::END_BLOCK ||
634 Code == llvm::bitc::ENTER_SUBBLOCK ||
635 Code == llvm::bitc::DEFINE_ABBREV) {
636 Error("incorrectly-formatted source location entry in PCH file");
637 return Failure;
638 }
639
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000640 SourceManager &SourceMgr = PP.getSourceManager();
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000641 RecordData Record;
642 const char *BlobStart;
643 unsigned BlobLen;
644 switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
645 default:
646 Error("incorrectly-formatted source location entry in PCH file");
647 return Failure;
648
649 case pch::SM_SLOC_FILE_ENTRY: {
650 const FileEntry *File
651 = PP.getFileManager().getFile(BlobStart, BlobStart + BlobLen);
652 // FIXME: Error recovery if file cannot be found.
653 FileID FID = SourceMgr.createFileID(File,
654 SourceLocation::getFromRawEncoding(Record[1]),
655 (SrcMgr::CharacteristicKind)Record[2],
656 ID, Record[0]);
657 if (Record[3])
658 const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
659 .setHasLineDirectives();
660
661 break;
662 }
663
664 case pch::SM_SLOC_BUFFER_ENTRY: {
665 const char *Name = BlobStart;
666 unsigned Offset = Record[0];
667 unsigned Code = SLocEntryCursor.ReadCode();
668 Record.clear();
669 unsigned RecCode
670 = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
671 assert(RecCode == pch::SM_SLOC_BUFFER_BLOB && "Ill-formed PCH file");
672 (void)RecCode;
673 llvm::MemoryBuffer *Buffer
674 = llvm::MemoryBuffer::getMemBuffer(BlobStart,
675 BlobStart + BlobLen - 1,
676 Name);
677 FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
678
679 if (strcmp(Name, "<built-in>") == 0
680 && CheckPredefinesBuffer(BlobStart, BlobLen - 1, BufferID))
681 return IgnorePCH;
682
683 break;
684 }
685
686 case pch::SM_SLOC_INSTANTIATION_ENTRY: {
687 SourceLocation SpellingLoc
688 = SourceLocation::getFromRawEncoding(Record[1]);
689 SourceMgr.createInstantiationLoc(SpellingLoc,
690 SourceLocation::getFromRawEncoding(Record[2]),
691 SourceLocation::getFromRawEncoding(Record[3]),
692 Record[4],
693 ID,
694 Record[0]);
695 break;
696 }
697 }
698
699 return Success;
700}
701
Chris Lattner6367f6d2009-04-27 01:05:14 +0000702/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
703/// specified cursor. Read the abbreviations that are at the top of the block
704/// and then leave the cursor pointing into the block.
705bool PCHReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
706 unsigned BlockID) {
707 if (Cursor.EnterSubBlock(BlockID)) {
708 Error("Malformed block record");
709 return Failure;
710 }
711
Chris Lattner6367f6d2009-04-27 01:05:14 +0000712 while (true) {
713 unsigned Code = Cursor.ReadCode();
714
715 // We expect all abbrevs to be at the start of the block.
716 if (Code != llvm::bitc::DEFINE_ABBREV)
717 return false;
718 Cursor.ReadAbbrevRecord();
719 }
720}
721
Douglas Gregor37e26842009-04-21 23:56:24 +0000722void PCHReader::ReadMacroRecord(uint64_t Offset) {
723 // Keep track of where we are in the stream, then jump back there
724 // after reading this macro.
725 SavedStreamPosition SavedPosition(Stream);
726
727 Stream.JumpToBit(Offset);
728 RecordData Record;
729 llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
730 MacroInfo *Macro = 0;
Steve Naroff83d63c72009-04-24 20:03:17 +0000731
Douglas Gregor37e26842009-04-21 23:56:24 +0000732 while (true) {
733 unsigned Code = Stream.ReadCode();
734 switch (Code) {
735 case llvm::bitc::END_BLOCK:
736 return;
737
738 case llvm::bitc::ENTER_SUBBLOCK:
739 // No known subblocks, always skip them.
740 Stream.ReadSubBlockID();
741 if (Stream.SkipBlock()) {
742 Error("Malformed block record");
743 return;
744 }
745 continue;
746
747 case llvm::bitc::DEFINE_ABBREV:
748 Stream.ReadAbbrevRecord();
749 continue;
750 default: break;
751 }
752
753 // Read a record.
754 Record.clear();
755 pch::PreprocessorRecordTypes RecType =
756 (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
757 switch (RecType) {
Douglas Gregor37e26842009-04-21 23:56:24 +0000758 case pch::PP_MACRO_OBJECT_LIKE:
759 case pch::PP_MACRO_FUNCTION_LIKE: {
760 // If we already have a macro, that means that we've hit the end
761 // of the definition of the macro we were looking for. We're
762 // done.
763 if (Macro)
764 return;
765
766 IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
767 if (II == 0) {
768 Error("Macro must have a name");
769 return;
770 }
771 SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
772 bool isUsed = Record[2];
773
774 MacroInfo *MI = PP.AllocateMacroInfo(Loc);
775 MI->setIsUsed(isUsed);
776
777 if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
778 // Decode function-like macro info.
779 bool isC99VarArgs = Record[3];
780 bool isGNUVarArgs = Record[4];
781 MacroArgs.clear();
782 unsigned NumArgs = Record[5];
783 for (unsigned i = 0; i != NumArgs; ++i)
784 MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
785
786 // Install function-like macro info.
787 MI->setIsFunctionLike();
788 if (isC99VarArgs) MI->setIsC99Varargs();
789 if (isGNUVarArgs) MI->setIsGNUVarargs();
790 MI->setArgumentList(&MacroArgs[0], MacroArgs.size(),
791 PP.getPreprocessorAllocator());
792 }
793
794 // Finally, install the macro.
795 PP.setMacroInfo(II, MI);
796
797 // Remember that we saw this macro last so that we add the tokens that
798 // form its body to it.
799 Macro = MI;
800 ++NumMacrosRead;
801 break;
802 }
803
804 case pch::PP_TOKEN: {
805 // If we see a TOKEN before a PP_MACRO_*, then the file is
806 // erroneous, just pretend we didn't see this.
807 if (Macro == 0) break;
808
809 Token Tok;
810 Tok.startToken();
811 Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
812 Tok.setLength(Record[1]);
813 if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
814 Tok.setIdentifierInfo(II);
815 Tok.setKind((tok::TokenKind)Record[3]);
816 Tok.setFlag((Token::TokenFlags)Record[4]);
817 Macro->AddTokenToBody(Tok);
818 break;
819 }
Steve Naroff83d63c72009-04-24 20:03:17 +0000820 }
Douglas Gregor37e26842009-04-21 23:56:24 +0000821 }
822}
823
Douglas Gregor668c1a42009-04-21 22:25:48 +0000824PCHReader::PCHReadResult
Douglas Gregor2eafc1b2009-04-26 00:07:37 +0000825PCHReader::ReadPCHBlock() {
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000826 if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
827 Error("Malformed block record");
828 return Failure;
829 }
Douglas Gregor2cf26342009-04-09 22:27:44 +0000830
831 // Read all of the records and blocks for the PCH file.
Douglas Gregor8038d512009-04-10 17:25:41 +0000832 RecordData Record;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000833 while (!Stream.AtEndOfStream()) {
834 unsigned Code = Stream.ReadCode();
835 if (Code == llvm::bitc::END_BLOCK) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000836 if (Stream.ReadBlockEnd()) {
837 Error("Error at end of module block");
838 return Failure;
839 }
Chris Lattner7356a312009-04-11 21:15:38 +0000840
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000841 return Success;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000842 }
843
844 if (Code == llvm::bitc::ENTER_SUBBLOCK) {
845 switch (Stream.ReadSubBlockID()) {
Douglas Gregor2cf26342009-04-09 22:27:44 +0000846 case pch::TYPES_BLOCK_ID: // Skip types block (lazily loaded)
847 default: // Skip unknown content.
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000848 if (Stream.SkipBlock()) {
849 Error("Malformed block record");
850 return Failure;
851 }
Douglas Gregor2cf26342009-04-09 22:27:44 +0000852 break;
853
Chris Lattner6367f6d2009-04-27 01:05:14 +0000854 case pch::DECLS_BLOCK_ID:
855 // We lazily load the decls block, but we want to set up the
856 // DeclsCursor cursor to point into it. Clone our current bitcode
857 // cursor to it, enter the block and read the abbrevs in that block.
858 // With the main cursor, we just skip over it.
859 DeclsCursor = Stream;
860 if (Stream.SkipBlock() || // Skip with the main cursor.
861 // Read the abbrevs.
862 ReadBlockAbbrevs(DeclsCursor, pch::DECLS_BLOCK_ID)) {
863 Error("Malformed block record");
864 return Failure;
865 }
866 break;
867
Chris Lattner7356a312009-04-11 21:15:38 +0000868 case pch::PREPROCESSOR_BLOCK_ID:
Chris Lattner7356a312009-04-11 21:15:38 +0000869 if (Stream.SkipBlock()) {
870 Error("Malformed block record");
871 return Failure;
872 }
873 break;
Steve Naroff90cd1bb2009-04-23 10:39:46 +0000874
Douglas Gregor14f79002009-04-10 03:52:48 +0000875 case pch::SOURCE_MANAGER_BLOCK_ID:
Douglas Gregore1d918e2009-04-10 23:10:45 +0000876 switch (ReadSourceManagerBlock()) {
877 case Success:
878 break;
879
880 case Failure:
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000881 Error("Malformed source manager block");
882 return Failure;
Douglas Gregore1d918e2009-04-10 23:10:45 +0000883
884 case IgnorePCH:
885 return IgnorePCH;
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000886 }
Douglas Gregor14f79002009-04-10 03:52:48 +0000887 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000888 }
Douglas Gregor8038d512009-04-10 17:25:41 +0000889 continue;
890 }
891
892 if (Code == llvm::bitc::DEFINE_ABBREV) {
893 Stream.ReadAbbrevRecord();
894 continue;
895 }
896
897 // Read and process a record.
898 Record.clear();
Douglas Gregor2bec0412009-04-10 21:16:55 +0000899 const char *BlobStart = 0;
900 unsigned BlobLen = 0;
901 switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record,
902 &BlobStart, &BlobLen)) {
Douglas Gregor8038d512009-04-10 17:25:41 +0000903 default: // Default behavior: ignore.
904 break;
905
906 case pch::TYPE_OFFSET:
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +0000907 if (!TypesLoaded.empty()) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000908 Error("Duplicate TYPE_OFFSET record in PCH file");
909 return Failure;
910 }
Chris Lattnerc732f5a2009-04-27 18:24:17 +0000911 TypeOffsets = (const uint32_t *)BlobStart;
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +0000912 TypesLoaded.resize(Record[0]);
Douglas Gregor8038d512009-04-10 17:25:41 +0000913 break;
914
915 case pch::DECL_OFFSET:
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +0000916 if (!DeclsLoaded.empty()) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000917 Error("Duplicate DECL_OFFSET record in PCH file");
918 return Failure;
919 }
Chris Lattnerc732f5a2009-04-27 18:24:17 +0000920 DeclOffsets = (const uint32_t *)BlobStart;
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +0000921 DeclsLoaded.resize(Record[0]);
Douglas Gregor8038d512009-04-10 17:25:41 +0000922 break;
Douglas Gregor0a0428e2009-04-10 20:39:37 +0000923
924 case pch::LANGUAGE_OPTIONS:
925 if (ParseLanguageOptions(Record))
926 return IgnorePCH;
927 break;
Douglas Gregor2bec0412009-04-10 21:16:55 +0000928
Douglas Gregorafaf3082009-04-11 00:14:32 +0000929 case pch::TARGET_TRIPLE: {
Douglas Gregor2bec0412009-04-10 21:16:55 +0000930 std::string TargetTriple(BlobStart, BlobLen);
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000931 if (TargetTriple != PP.getTargetInfo().getTargetTriple()) {
Douglas Gregor2bec0412009-04-10 21:16:55 +0000932 Diag(diag::warn_pch_target_triple)
Chris Lattnerd1d64a02009-04-27 21:45:14 +0000933 << TargetTriple << PP.getTargetInfo().getTargetTriple();
Douglas Gregor2bec0412009-04-10 21:16:55 +0000934 Diag(diag::note_ignoring_pch) << FileName;
935 return IgnorePCH;
936 }
937 break;
Douglas Gregor2cf26342009-04-09 22:27:44 +0000938 }
Douglas Gregorafaf3082009-04-11 00:14:32 +0000939
940 case pch::IDENTIFIER_TABLE:
Douglas Gregor668c1a42009-04-21 22:25:48 +0000941 IdentifierTableData = BlobStart;
Douglas Gregor2b3a5a82009-04-25 19:10:14 +0000942 if (Record[0]) {
943 IdentifierLookupTable
944 = PCHIdentifierLookupTable::Create(
Douglas Gregor668c1a42009-04-21 22:25:48 +0000945 (const unsigned char *)IdentifierTableData + Record[0],
946 (const unsigned char *)IdentifierTableData,
947 PCHIdentifierLookupTrait(*this));
Douglas Gregor2b3a5a82009-04-25 19:10:14 +0000948 PP.getIdentifierTable().setExternalIdentifierLookup(this);
949 }
Douglas Gregorafaf3082009-04-11 00:14:32 +0000950 break;
951
952 case pch::IDENTIFIER_OFFSET:
Douglas Gregor2b3a5a82009-04-25 19:10:14 +0000953 if (!IdentifiersLoaded.empty()) {
Douglas Gregorafaf3082009-04-11 00:14:32 +0000954 Error("Duplicate IDENTIFIER_OFFSET record in PCH file");
955 return Failure;
956 }
Douglas Gregor2b3a5a82009-04-25 19:10:14 +0000957 IdentifierOffsets = (const uint32_t *)BlobStart;
958 IdentifiersLoaded.resize(Record[0]);
Douglas Gregor8c5a7602009-04-25 23:30:02 +0000959 PP.getHeaderSearchInfo().SetExternalLookup(this);
Douglas Gregorafaf3082009-04-11 00:14:32 +0000960 break;
Douglas Gregorfdd01722009-04-14 00:24:19 +0000961
962 case pch::EXTERNAL_DEFINITIONS:
963 if (!ExternalDefinitions.empty()) {
964 Error("Duplicate EXTERNAL_DEFINITIONS record in PCH file");
965 return Failure;
966 }
967 ExternalDefinitions.swap(Record);
968 break;
Douglas Gregor3e1af842009-04-17 22:13:46 +0000969
Douglas Gregorad1de002009-04-18 05:55:16 +0000970 case pch::SPECIAL_TYPES:
971 SpecialTypes.swap(Record);
972 break;
973
Douglas Gregor3e1af842009-04-17 22:13:46 +0000974 case pch::STATISTICS:
975 TotalNumStatements = Record[0];
Douglas Gregor37e26842009-04-21 23:56:24 +0000976 TotalNumMacros = Record[1];
Douglas Gregor25123082009-04-22 22:34:57 +0000977 TotalLexicalDeclContexts = Record[2];
978 TotalVisibleDeclContexts = Record[3];
Douglas Gregor3e1af842009-04-17 22:13:46 +0000979 break;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +0000980
Douglas Gregor4c0e86b2009-04-22 22:02:47 +0000981 case pch::TENTATIVE_DEFINITIONS:
982 if (!TentativeDefinitions.empty()) {
983 Error("Duplicate TENTATIVE_DEFINITIONS record in PCH file");
984 return Failure;
985 }
986 TentativeDefinitions.swap(Record);
987 break;
Douglas Gregor14c22f22009-04-22 22:18:58 +0000988
989 case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
990 if (!LocallyScopedExternalDecls.empty()) {
991 Error("Duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
992 return Failure;
993 }
994 LocallyScopedExternalDecls.swap(Record);
995 break;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +0000996
Douglas Gregor83941df2009-04-25 17:48:32 +0000997 case pch::SELECTOR_OFFSETS:
998 SelectorOffsets = (const uint32_t *)BlobStart;
999 TotalNumSelectors = Record[0];
1000 SelectorsLoaded.resize(TotalNumSelectors);
1001 break;
1002
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001003 case pch::METHOD_POOL:
Douglas Gregor83941df2009-04-25 17:48:32 +00001004 MethodPoolLookupTableData = (const unsigned char *)BlobStart;
1005 if (Record[0])
1006 MethodPoolLookupTable
1007 = PCHMethodPoolLookupTable::Create(
1008 MethodPoolLookupTableData + Record[0],
1009 MethodPoolLookupTableData,
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001010 PCHMethodPoolLookupTrait(*this));
Douglas Gregor83941df2009-04-25 17:48:32 +00001011 TotalSelectorsInMethodPool = Record[1];
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001012 break;
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001013
1014 case pch::PP_COUNTER_VALUE:
1015 if (!Record.empty())
1016 PP.setCounterValue(Record[0]);
1017 break;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001018
1019 case pch::SOURCE_LOCATION_OFFSETS:
Chris Lattner090d9b52009-04-27 19:01:47 +00001020 SLocOffsets = (const uint32_t *)BlobStart;
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001021 TotalNumSLocEntries = Record[0];
1022 PP.getSourceManager().PreallocateSLocEntries(this,
1023 TotalNumSLocEntries,
1024 Record[1]);
1025 break;
1026
1027 case pch::SOURCE_LOCATION_PRELOADS:
1028 for (unsigned I = 0, N = Record.size(); I != N; ++I) {
1029 PCHReadResult Result = ReadSLocEntryRecord(Record[I]);
1030 if (Result != Success)
1031 return Result;
1032 }
1033 break;
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001034
1035 case pch::STAT_CACHE:
1036 PP.getFileManager().setStatCache(
1037 new PCHStatCache((const unsigned char *)BlobStart + Record[0],
1038 (const unsigned char *)BlobStart,
1039 NumStatHits, NumStatMisses));
1040 break;
Douglas Gregorb81c1702009-04-27 20:06:05 +00001041
1042 case pch::EXT_VECTOR_DECLS:
1043 if (!ExtVectorDecls.empty()) {
1044 Error("Duplicate EXT_VECTOR_DECLS record in PCH file");
1045 return Failure;
1046 }
1047 ExtVectorDecls.swap(Record);
1048 break;
1049
1050 case pch::OBJC_CATEGORY_IMPLEMENTATIONS:
1051 if (!ObjCCategoryImpls.empty()) {
1052 Error("Duplicate OBJC_CATEGORY_IMPLEMENTATIONS record in PCH file");
1053 return Failure;
1054 }
1055 ObjCCategoryImpls.swap(Record);
1056 break;
Douglas Gregorafaf3082009-04-11 00:14:32 +00001057 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001058 }
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001059 Error("Premature end of bitstream");
1060 return Failure;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001061}
1062
Douglas Gregore1d918e2009-04-10 23:10:45 +00001063PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001064 // Set the PCH file name.
1065 this->FileName = FileName;
1066
Douglas Gregor2cf26342009-04-09 22:27:44 +00001067 // Open the PCH file.
1068 std::string ErrStr;
1069 Buffer.reset(llvm::MemoryBuffer::getFile(FileName.c_str(), &ErrStr));
Douglas Gregore1d918e2009-04-10 23:10:45 +00001070 if (!Buffer) {
1071 Error(ErrStr.c_str());
1072 return IgnorePCH;
1073 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001074
1075 // Initialize the stream
Chris Lattnerb9fa9172009-04-26 20:59:20 +00001076 StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
1077 (const unsigned char *)Buffer->getBufferEnd());
1078 Stream.init(StreamFile);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001079
1080 // Sniff for the signature.
1081 if (Stream.Read(8) != 'C' ||
1082 Stream.Read(8) != 'P' ||
1083 Stream.Read(8) != 'C' ||
Douglas Gregore1d918e2009-04-10 23:10:45 +00001084 Stream.Read(8) != 'H') {
1085 Error("Not a PCH file");
1086 return IgnorePCH;
1087 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001088
Douglas Gregor2cf26342009-04-09 22:27:44 +00001089 while (!Stream.AtEndOfStream()) {
1090 unsigned Code = Stream.ReadCode();
1091
Douglas Gregore1d918e2009-04-10 23:10:45 +00001092 if (Code != llvm::bitc::ENTER_SUBBLOCK) {
1093 Error("Invalid record at top-level");
1094 return Failure;
1095 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001096
1097 unsigned BlockID = Stream.ReadSubBlockID();
Douglas Gregor668c1a42009-04-21 22:25:48 +00001098
Douglas Gregor2cf26342009-04-09 22:27:44 +00001099 // We only know the PCH subblock ID.
1100 switch (BlockID) {
1101 case llvm::bitc::BLOCKINFO_BLOCK_ID:
Douglas Gregore1d918e2009-04-10 23:10:45 +00001102 if (Stream.ReadBlockInfoBlock()) {
1103 Error("Malformed BlockInfoBlock");
1104 return Failure;
1105 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001106 break;
1107 case pch::PCH_BLOCK_ID:
Douglas Gregor2eafc1b2009-04-26 00:07:37 +00001108 switch (ReadPCHBlock()) {
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001109 case Success:
1110 break;
1111
1112 case Failure:
Douglas Gregore1d918e2009-04-10 23:10:45 +00001113 return Failure;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001114
1115 case IgnorePCH:
Douglas Gregor2bec0412009-04-10 21:16:55 +00001116 // FIXME: We could consider reading through to the end of this
1117 // PCH block, skipping subblocks, to see if there are other
1118 // PCH blocks elsewhere.
Douglas Gregor2bf1eb02009-04-27 21:28:04 +00001119
1120 // Clear out any preallocated source location entries, so that
1121 // the source manager does not try to resolve them later.
1122 PP.getSourceManager().ClearPreallocatedSLocEntries();
1123
1124 // Remove the stat cache.
1125 PP.getFileManager().setStatCache(0);
1126
Douglas Gregore1d918e2009-04-10 23:10:45 +00001127 return IgnorePCH;
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001128 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001129 break;
1130 default:
Douglas Gregore1d918e2009-04-10 23:10:45 +00001131 if (Stream.SkipBlock()) {
1132 Error("Malformed block record");
1133 return Failure;
1134 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001135 break;
1136 }
1137 }
1138
1139 // Load the translation unit declaration
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001140 if (Context)
1141 ReadDeclRecord(DeclOffsets[0], 0);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001142
Douglas Gregor668c1a42009-04-21 22:25:48 +00001143 // Initialization of builtins and library builtins occurs before the
1144 // PCH file is read, so there may be some identifiers that were
1145 // loaded into the IdentifierTable before we intercepted the
1146 // creation of identifiers. Iterate through the list of known
1147 // identifiers and determine whether we have to establish
1148 // preprocessor definitions or top-level identifier declaration
1149 // chains for those identifiers.
1150 //
1151 // We copy the IdentifierInfo pointers to a small vector first,
1152 // since de-serializing declarations or macro definitions can add
1153 // new entries into the identifier table, invalidating the
1154 // iterators.
1155 llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
1156 for (IdentifierTable::iterator Id = PP.getIdentifierTable().begin(),
1157 IdEnd = PP.getIdentifierTable().end();
1158 Id != IdEnd; ++Id)
1159 Identifiers.push_back(Id->second);
1160 PCHIdentifierLookupTable *IdTable
1161 = (PCHIdentifierLookupTable *)IdentifierLookupTable;
1162 for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
1163 IdentifierInfo *II = Identifiers[I];
1164 // Look in the on-disk hash table for an entry for
1165 PCHIdentifierLookupTrait Info(*this, II);
1166 std::pair<const char*, unsigned> Key(II->getName(), II->getLength());
1167 PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
1168 if (Pos == IdTable->end())
1169 continue;
1170
1171 // Dereferencing the iterator has the effect of populating the
1172 // IdentifierInfo node with the various declarations it needs.
1173 (void)*Pos;
1174 }
1175
Douglas Gregorad1de002009-04-18 05:55:16 +00001176 // Load the special types.
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001177 if (Context) {
1178 Context->setBuiltinVaListType(
1179 GetType(SpecialTypes[pch::SPECIAL_TYPE_BUILTIN_VA_LIST]));
1180 if (unsigned Id = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID])
1181 Context->setObjCIdType(GetType(Id));
1182 if (unsigned Sel = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SELECTOR])
1183 Context->setObjCSelType(GetType(Sel));
1184 if (unsigned Proto = SpecialTypes[pch::SPECIAL_TYPE_OBJC_PROTOCOL])
1185 Context->setObjCProtoType(GetType(Proto));
1186 if (unsigned Class = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS])
1187 Context->setObjCClassType(GetType(Class));
1188 if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_CF_CONSTANT_STRING])
1189 Context->setCFConstantStringType(GetType(String));
1190 if (unsigned FastEnum
1191 = SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
1192 Context->setObjCFastEnumerationStateType(GetType(FastEnum));
1193 }
Douglas Gregor0b748912009-04-14 21:18:50 +00001194
Douglas Gregor668c1a42009-04-21 22:25:48 +00001195 return Success;
Douglas Gregor0b748912009-04-14 21:18:50 +00001196}
1197
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001198/// \brief Parse the record that corresponds to a LangOptions data
1199/// structure.
1200///
1201/// This routine compares the language options used to generate the
1202/// PCH file against the language options set for the current
1203/// compilation. For each option, we classify differences between the
1204/// two compiler states as either "benign" or "important". Benign
1205/// differences don't matter, and we accept them without complaint
1206/// (and without modifying the language options). Differences between
1207/// the states for important options cause the PCH file to be
1208/// unusable, so we emit a warning and return true to indicate that
1209/// there was an error.
1210///
1211/// \returns true if the PCH file is unacceptable, false otherwise.
1212bool PCHReader::ParseLanguageOptions(
1213 const llvm::SmallVectorImpl<uint64_t> &Record) {
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001214 const LangOptions &LangOpts = PP.getLangOptions();
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001215#define PARSE_LANGOPT_BENIGN(Option) ++Idx
1216#define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
1217 if (Record[Idx] != LangOpts.Option) { \
1218 Diag(DiagID) << (unsigned)Record[Idx] << LangOpts.Option; \
1219 Diag(diag::note_ignoring_pch) << FileName; \
1220 return true; \
1221 } \
1222 ++Idx
1223
1224 unsigned Idx = 0;
1225 PARSE_LANGOPT_BENIGN(Trigraphs);
1226 PARSE_LANGOPT_BENIGN(BCPLComment);
1227 PARSE_LANGOPT_BENIGN(DollarIdents);
1228 PARSE_LANGOPT_BENIGN(AsmPreprocessor);
1229 PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
1230 PARSE_LANGOPT_BENIGN(ImplicitInt);
1231 PARSE_LANGOPT_BENIGN(Digraphs);
1232 PARSE_LANGOPT_BENIGN(HexFloats);
1233 PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
1234 PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
1235 PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
1236 PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
1237 PARSE_LANGOPT_IMPORTANT(NoExtensions, diag::warn_pch_extensions);
1238 PARSE_LANGOPT_BENIGN(CXXOperatorName);
1239 PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
1240 PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
1241 PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
1242 PARSE_LANGOPT_BENIGN(PascalStrings);
1243 PARSE_LANGOPT_BENIGN(Boolean);
1244 PARSE_LANGOPT_BENIGN(WritableStrings);
1245 PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
1246 diag::warn_pch_lax_vector_conversions);
1247 PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
1248 PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
1249 PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
1250 PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
1251 PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
1252 diag::warn_pch_thread_safe_statics);
1253 PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
1254 PARSE_LANGOPT_BENIGN(EmitAllDecls);
1255 PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
1256 PARSE_LANGOPT_IMPORTANT(OverflowChecking, diag::warn_pch_overflow_checking);
1257 PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
1258 diag::warn_pch_heinous_extensions);
1259 // FIXME: Most of the options below are benign if the macro wasn't
1260 // used. Unfortunately, this means that a PCH compiled without
1261 // optimization can't be used with optimization turned on, even
1262 // though the only thing that changes is whether __OPTIMIZE__ was
1263 // defined... but if __OPTIMIZE__ never showed up in the header, it
1264 // doesn't matter. We could consider making this some special kind
1265 // of check.
1266 PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
1267 PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
1268 PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
1269 PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
1270 PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
1271 PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
1272 if ((LangOpts.getGCMode() != 0) != (Record[Idx] != 0)) {
1273 Diag(diag::warn_pch_gc_mode)
1274 << (unsigned)Record[Idx] << LangOpts.getGCMode();
1275 Diag(diag::note_ignoring_pch) << FileName;
1276 return true;
1277 }
1278 ++Idx;
1279 PARSE_LANGOPT_BENIGN(getVisibilityMode());
1280 PARSE_LANGOPT_BENIGN(InstantiationDepth);
1281#undef PARSE_LANGOPT_IRRELEVANT
1282#undef PARSE_LANGOPT_BENIGN
1283
1284 return false;
1285}
1286
Douglas Gregor2cf26342009-04-09 22:27:44 +00001287/// \brief Read and return the type at the given offset.
1288///
1289/// This routine actually reads the record corresponding to the type
1290/// at the given offset in the bitstream. It is a helper routine for
1291/// GetType, which deals with reading type IDs.
1292QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
Douglas Gregor0b748912009-04-14 21:18:50 +00001293 // Keep track of where we are in the stream, then jump back there
1294 // after reading this type.
1295 SavedStreamPosition SavedPosition(Stream);
1296
Douglas Gregor2cf26342009-04-09 22:27:44 +00001297 Stream.JumpToBit(Offset);
1298 RecordData Record;
1299 unsigned Code = Stream.ReadCode();
1300 switch ((pch::TypeCode)Stream.ReadRecord(Code, Record)) {
Douglas Gregor6d473962009-04-15 22:00:08 +00001301 case pch::TYPE_EXT_QUAL: {
1302 assert(Record.size() == 3 &&
1303 "Incorrect encoding of extended qualifier type");
1304 QualType Base = GetType(Record[0]);
1305 QualType::GCAttrTypes GCAttr = (QualType::GCAttrTypes)Record[1];
1306 unsigned AddressSpace = Record[2];
1307
1308 QualType T = Base;
1309 if (GCAttr != QualType::GCNone)
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001310 T = Context->getObjCGCQualType(T, GCAttr);
Douglas Gregor6d473962009-04-15 22:00:08 +00001311 if (AddressSpace)
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001312 T = Context->getAddrSpaceQualType(T, AddressSpace);
Douglas Gregor6d473962009-04-15 22:00:08 +00001313 return T;
1314 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001315
Douglas Gregor2cf26342009-04-09 22:27:44 +00001316 case pch::TYPE_FIXED_WIDTH_INT: {
1317 assert(Record.size() == 2 && "Incorrect encoding of fixed-width int type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001318 return Context->getFixedWidthIntType(Record[0], Record[1]);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001319 }
1320
1321 case pch::TYPE_COMPLEX: {
1322 assert(Record.size() == 1 && "Incorrect encoding of complex type");
1323 QualType ElemType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001324 return Context->getComplexType(ElemType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001325 }
1326
1327 case pch::TYPE_POINTER: {
1328 assert(Record.size() == 1 && "Incorrect encoding of pointer type");
1329 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001330 return Context->getPointerType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001331 }
1332
1333 case pch::TYPE_BLOCK_POINTER: {
1334 assert(Record.size() == 1 && "Incorrect encoding of block pointer type");
1335 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001336 return Context->getBlockPointerType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001337 }
1338
1339 case pch::TYPE_LVALUE_REFERENCE: {
1340 assert(Record.size() == 1 && "Incorrect encoding of lvalue reference type");
1341 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001342 return Context->getLValueReferenceType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001343 }
1344
1345 case pch::TYPE_RVALUE_REFERENCE: {
1346 assert(Record.size() == 1 && "Incorrect encoding of rvalue reference type");
1347 QualType PointeeType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001348 return Context->getRValueReferenceType(PointeeType);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001349 }
1350
1351 case pch::TYPE_MEMBER_POINTER: {
1352 assert(Record.size() == 1 && "Incorrect encoding of member pointer type");
1353 QualType PointeeType = GetType(Record[0]);
1354 QualType ClassType = GetType(Record[1]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001355 return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
Douglas Gregor2cf26342009-04-09 22:27:44 +00001356 }
1357
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001358 case pch::TYPE_CONSTANT_ARRAY: {
1359 QualType ElementType = GetType(Record[0]);
1360 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1361 unsigned IndexTypeQuals = Record[2];
1362 unsigned Idx = 3;
1363 llvm::APInt Size = ReadAPInt(Record, Idx);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001364 return Context->getConstantArrayType(ElementType, Size, ASM,IndexTypeQuals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001365 }
1366
1367 case pch::TYPE_INCOMPLETE_ARRAY: {
1368 QualType ElementType = GetType(Record[0]);
1369 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1370 unsigned IndexTypeQuals = Record[2];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001371 return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001372 }
1373
1374 case pch::TYPE_VARIABLE_ARRAY: {
Douglas Gregor0b748912009-04-14 21:18:50 +00001375 QualType ElementType = GetType(Record[0]);
1376 ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1377 unsigned IndexTypeQuals = Record[2];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001378 return Context->getVariableArrayType(ElementType, ReadTypeExpr(),
1379 ASM, IndexTypeQuals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001380 }
1381
1382 case pch::TYPE_VECTOR: {
1383 if (Record.size() != 2) {
1384 Error("Incorrect encoding of vector type in PCH file");
1385 return QualType();
1386 }
1387
1388 QualType ElementType = GetType(Record[0]);
1389 unsigned NumElements = Record[1];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001390 return Context->getVectorType(ElementType, NumElements);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001391 }
1392
1393 case pch::TYPE_EXT_VECTOR: {
1394 if (Record.size() != 2) {
1395 Error("Incorrect encoding of extended vector type in PCH file");
1396 return QualType();
1397 }
1398
1399 QualType ElementType = GetType(Record[0]);
1400 unsigned NumElements = Record[1];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001401 return Context->getExtVectorType(ElementType, NumElements);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001402 }
1403
1404 case pch::TYPE_FUNCTION_NO_PROTO: {
1405 if (Record.size() != 1) {
1406 Error("Incorrect encoding of no-proto function type");
1407 return QualType();
1408 }
1409 QualType ResultType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001410 return Context->getFunctionNoProtoType(ResultType);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001411 }
1412
1413 case pch::TYPE_FUNCTION_PROTO: {
1414 QualType ResultType = GetType(Record[0]);
1415 unsigned Idx = 1;
1416 unsigned NumParams = Record[Idx++];
1417 llvm::SmallVector<QualType, 16> ParamTypes;
1418 for (unsigned I = 0; I != NumParams; ++I)
1419 ParamTypes.push_back(GetType(Record[Idx++]));
1420 bool isVariadic = Record[Idx++];
1421 unsigned Quals = Record[Idx++];
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001422 return Context->getFunctionType(ResultType, &ParamTypes[0], NumParams,
1423 isVariadic, Quals);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001424 }
1425
1426 case pch::TYPE_TYPEDEF:
1427 assert(Record.size() == 1 && "Incorrect encoding of typedef type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001428 return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001429
1430 case pch::TYPE_TYPEOF_EXPR:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001431 return Context->getTypeOfExprType(ReadTypeExpr());
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001432
1433 case pch::TYPE_TYPEOF: {
1434 if (Record.size() != 1) {
1435 Error("Incorrect encoding of typeof(type) in PCH file");
1436 return QualType();
1437 }
1438 QualType UnderlyingType = GetType(Record[0]);
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001439 return Context->getTypeOfType(UnderlyingType);
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001440 }
1441
1442 case pch::TYPE_RECORD:
Douglas Gregor8c700062009-04-13 21:20:57 +00001443 assert(Record.size() == 1 && "Incorrect encoding of record type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001444 return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001445
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00001446 case pch::TYPE_ENUM:
1447 assert(Record.size() == 1 && "Incorrect encoding of enum type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001448 return Context->getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00001449
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001450 case pch::TYPE_OBJC_INTERFACE:
Chris Lattner4dcf151a2009-04-22 05:57:30 +00001451 assert(Record.size() == 1 && "Incorrect encoding of objc interface type");
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001452 return Context->getObjCInterfaceType(
Chris Lattner4dcf151a2009-04-22 05:57:30 +00001453 cast<ObjCInterfaceDecl>(GetDecl(Record[0])));
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001454
Chris Lattnerc6fa4452009-04-22 06:45:28 +00001455 case pch::TYPE_OBJC_QUALIFIED_INTERFACE: {
1456 unsigned Idx = 0;
1457 ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
1458 unsigned NumProtos = Record[Idx++];
1459 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
1460 for (unsigned I = 0; I != NumProtos; ++I)
1461 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001462 return Context->getObjCQualifiedInterfaceType(ItfD, &Protos[0], NumProtos);
Chris Lattnerc6fa4452009-04-22 06:45:28 +00001463 }
Douglas Gregorb4e715b2009-04-13 20:46:52 +00001464
Chris Lattnerd7a3fcd2009-04-22 06:40:03 +00001465 case pch::TYPE_OBJC_QUALIFIED_ID: {
1466 unsigned Idx = 0;
1467 unsigned NumProtos = Record[Idx++];
1468 llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
1469 for (unsigned I = 0; I != NumProtos; ++I)
1470 Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001471 return Context->getObjCQualifiedIdType(&Protos[0], NumProtos);
Chris Lattnerd7a3fcd2009-04-22 06:40:03 +00001472 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001473 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001474 // Suppress a GCC warning
1475 return QualType();
1476}
1477
Douglas Gregor2cf26342009-04-09 22:27:44 +00001478
Douglas Gregor8038d512009-04-10 17:25:41 +00001479QualType PCHReader::GetType(pch::TypeID ID) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00001480 unsigned Quals = ID & 0x07;
1481 unsigned Index = ID >> 3;
1482
1483 if (Index < pch::NUM_PREDEF_TYPE_IDS) {
1484 QualType T;
1485 switch ((pch::PredefinedTypeIDs)Index) {
1486 case pch::PREDEF_TYPE_NULL_ID: return QualType();
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001487 case pch::PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
1488 case pch::PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001489
1490 case pch::PREDEF_TYPE_CHAR_U_ID:
1491 case pch::PREDEF_TYPE_CHAR_S_ID:
1492 // FIXME: Check that the signedness of CharTy is correct!
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001493 T = Context->CharTy;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001494 break;
1495
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001496 case pch::PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
1497 case pch::PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
1498 case pch::PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
1499 case pch::PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
1500 case pch::PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
1501 case pch::PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
1502 case pch::PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
1503 case pch::PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
1504 case pch::PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
1505 case pch::PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
1506 case pch::PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
1507 case pch::PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
1508 case pch::PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
1509 case pch::PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
1510 case pch::PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
1511 case pch::PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001512 }
1513
1514 assert(!T.isNull() && "Unknown predefined type");
1515 return T.getQualifiedType(Quals);
1516 }
1517
1518 Index -= pch::NUM_PREDEF_TYPE_IDS;
Douglas Gregor366809a2009-04-26 03:49:13 +00001519 assert(Index < TypesLoaded.size() && "Type index out-of-range");
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001520 if (!TypesLoaded[Index])
1521 TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]).getTypePtr();
Douglas Gregor2cf26342009-04-09 22:27:44 +00001522
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001523 return QualType(TypesLoaded[Index], Quals);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001524}
1525
Douglas Gregor8038d512009-04-10 17:25:41 +00001526Decl *PCHReader::GetDecl(pch::DeclID ID) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00001527 if (ID == 0)
1528 return 0;
1529
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001530 if (ID > DeclsLoaded.size()) {
1531 Error("Declaration ID out-of-range for PCH file");
1532 return 0;
1533 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001534
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001535 unsigned Index = ID - 1;
1536 if (!DeclsLoaded[Index])
1537 ReadDeclRecord(DeclOffsets[Index], Index);
1538
1539 return DeclsLoaded[Index];
Douglas Gregor2cf26342009-04-09 22:27:44 +00001540}
1541
Chris Lattner887e2b32009-04-27 05:46:25 +00001542/// \brief Resolve the offset of a statement into a statement.
1543///
1544/// This operation will read a new statement from the external
1545/// source each time it is called, and is meant to be used via a
1546/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
1547Stmt *PCHReader::GetDeclStmt(uint64_t Offset) {
Chris Lattnerda930612009-04-27 05:58:23 +00001548 // Since we know tha this statement is part of a decl, make sure to use the
1549 // decl cursor to read it.
1550 DeclsCursor.JumpToBit(Offset);
1551 return ReadStmt(DeclsCursor);
Douglas Gregor250fc9c2009-04-18 00:07:54 +00001552}
1553
Douglas Gregor2cf26342009-04-09 22:27:44 +00001554bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
Douglas Gregor8038d512009-04-10 17:25:41 +00001555 llvm::SmallVectorImpl<pch::DeclID> &Decls) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00001556 assert(DC->hasExternalLexicalStorage() &&
1557 "DeclContext has no lexical decls in storage");
1558 uint64_t Offset = DeclContextOffsets[DC].first;
1559 assert(Offset && "DeclContext has no lexical decls in storage");
1560
Douglas Gregor0b748912009-04-14 21:18:50 +00001561 // Keep track of where we are in the stream, then jump back there
1562 // after reading this context.
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001563 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregor0b748912009-04-14 21:18:50 +00001564
Douglas Gregor2cf26342009-04-09 22:27:44 +00001565 // Load the record containing all of the declarations lexically in
1566 // this context.
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001567 DeclsCursor.JumpToBit(Offset);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001568 RecordData Record;
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001569 unsigned Code = DeclsCursor.ReadCode();
1570 unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
Douglas Gregor6a2bfb22009-04-15 18:43:11 +00001571 (void)RecCode;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001572 assert(RecCode == pch::DECL_CONTEXT_LEXICAL && "Expected lexical block");
1573
1574 // Load all of the declaration IDs
1575 Decls.clear();
1576 Decls.insert(Decls.end(), Record.begin(), Record.end());
Douglas Gregor25123082009-04-22 22:34:57 +00001577 ++NumLexicalDeclContextsRead;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001578 return false;
1579}
1580
1581bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001582 llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
Douglas Gregor2cf26342009-04-09 22:27:44 +00001583 assert(DC->hasExternalVisibleStorage() &&
1584 "DeclContext has no visible decls in storage");
1585 uint64_t Offset = DeclContextOffsets[DC].second;
1586 assert(Offset && "DeclContext has no visible decls in storage");
1587
Douglas Gregor0b748912009-04-14 21:18:50 +00001588 // Keep track of where we are in the stream, then jump back there
1589 // after reading this context.
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001590 SavedStreamPosition SavedPosition(DeclsCursor);
Douglas Gregor0b748912009-04-14 21:18:50 +00001591
Douglas Gregor2cf26342009-04-09 22:27:44 +00001592 // Load the record containing all of the declarations visible in
1593 // this context.
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001594 DeclsCursor.JumpToBit(Offset);
Douglas Gregor2cf26342009-04-09 22:27:44 +00001595 RecordData Record;
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001596 unsigned Code = DeclsCursor.ReadCode();
1597 unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
Douglas Gregor6a2bfb22009-04-15 18:43:11 +00001598 (void)RecCode;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001599 assert(RecCode == pch::DECL_CONTEXT_VISIBLE && "Expected visible block");
1600 if (Record.size() == 0)
1601 return false;
1602
1603 Decls.clear();
1604
1605 unsigned Idx = 0;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001606 while (Idx < Record.size()) {
1607 Decls.push_back(VisibleDeclaration());
1608 Decls.back().Name = ReadDeclarationName(Record, Idx);
1609
Douglas Gregor2cf26342009-04-09 22:27:44 +00001610 unsigned Size = Record[Idx++];
Chris Lattnerc47be9e2009-04-27 07:35:40 +00001611 llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001612 LoadedDecls.reserve(Size);
1613 for (unsigned I = 0; I < Size; ++I)
1614 LoadedDecls.push_back(Record[Idx++]);
1615 }
1616
Douglas Gregor25123082009-04-22 22:34:57 +00001617 ++NumVisibleDeclContextsRead;
Douglas Gregor2cf26342009-04-09 22:27:44 +00001618 return false;
1619}
1620
Douglas Gregorfdd01722009-04-14 00:24:19 +00001621void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
Douglas Gregor0af2ca42009-04-22 19:09:20 +00001622 this->Consumer = Consumer;
1623
Douglas Gregorfdd01722009-04-14 00:24:19 +00001624 if (!Consumer)
1625 return;
1626
1627 for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
1628 Decl *D = GetDecl(ExternalDefinitions[I]);
1629 DeclGroupRef DG(D);
1630 Consumer->HandleTopLevelDecl(DG);
1631 }
Douglas Gregorc62a2fe2009-04-25 00:41:30 +00001632
1633 for (unsigned I = 0, N = InterestingDecls.size(); I != N; ++I) {
1634 DeclGroupRef DG(InterestingDecls[I]);
1635 Consumer->HandleTopLevelDecl(DG);
1636 }
Douglas Gregorfdd01722009-04-14 00:24:19 +00001637}
1638
Douglas Gregor2cf26342009-04-09 22:27:44 +00001639void PCHReader::PrintStats() {
1640 std::fprintf(stderr, "*** PCH Statistics:\n");
1641
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001642 unsigned NumTypesLoaded
1643 = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
1644 (Type *)0);
1645 unsigned NumDeclsLoaded
1646 = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
1647 (Decl *)0);
1648 unsigned NumIdentifiersLoaded
1649 = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
1650 IdentifiersLoaded.end(),
1651 (IdentifierInfo *)0);
1652 unsigned NumSelectorsLoaded
1653 = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
1654 SelectorsLoaded.end(),
1655 Selector());
Douglas Gregor2d41cc12009-04-13 20:50:16 +00001656
Douglas Gregor4fed3f42009-04-27 18:38:38 +00001657 std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
1658 std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001659 if (TotalNumSLocEntries)
1660 std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
1661 NumSLocEntriesRead, TotalNumSLocEntries,
1662 ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001663 if (!TypesLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00001664 std::fprintf(stderr, " %u/%u types read (%f%%)\n",
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001665 NumTypesLoaded, (unsigned)TypesLoaded.size(),
1666 ((float)NumTypesLoaded/TypesLoaded.size() * 100));
1667 if (!DeclsLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00001668 std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
Douglas Gregor8f5dc7f2009-04-25 18:35:21 +00001669 NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
1670 ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001671 if (!IdentifiersLoaded.empty())
Douglas Gregor83941df2009-04-25 17:48:32 +00001672 std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001673 NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
1674 ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
Douglas Gregor83941df2009-04-25 17:48:32 +00001675 if (TotalNumSelectors)
1676 std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
1677 NumSelectorsLoaded, TotalNumSelectors,
1678 ((float)NumSelectorsLoaded/TotalNumSelectors * 100));
1679 if (TotalNumStatements)
1680 std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
1681 NumStatementsRead, TotalNumStatements,
1682 ((float)NumStatementsRead/TotalNumStatements * 100));
1683 if (TotalNumMacros)
1684 std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
1685 NumMacrosRead, TotalNumMacros,
1686 ((float)NumMacrosRead/TotalNumMacros * 100));
1687 if (TotalLexicalDeclContexts)
1688 std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
1689 NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
1690 ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
1691 * 100));
1692 if (TotalVisibleDeclContexts)
1693 std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
1694 NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
1695 ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
1696 * 100));
1697 if (TotalSelectorsInMethodPool) {
1698 std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
1699 NumMethodPoolSelectorsRead, TotalSelectorsInMethodPool,
1700 ((float)NumMethodPoolSelectorsRead/TotalSelectorsInMethodPool
1701 * 100));
1702 std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
1703 }
Douglas Gregor2cf26342009-04-09 22:27:44 +00001704 std::fprintf(stderr, "\n");
1705}
1706
Douglas Gregor668c1a42009-04-21 22:25:48 +00001707void PCHReader::InitializeSema(Sema &S) {
1708 SemaObj = &S;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001709 S.ExternalSource = this;
1710
Douglas Gregor6cfc1a82009-04-22 21:15:06 +00001711 // Makes sure any declarations that were deserialized "too early"
1712 // still get added to the identifier's declaration chains.
1713 for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
1714 SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(PreloadedDecls[I]));
1715 SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
Douglas Gregor668c1a42009-04-21 22:25:48 +00001716 }
Douglas Gregor6cfc1a82009-04-22 21:15:06 +00001717 PreloadedDecls.clear();
Douglas Gregor4c0e86b2009-04-22 22:02:47 +00001718
1719 // If there were any tentative definitions, deserialize them and add
1720 // them to Sema's table of tentative definitions.
1721 for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
1722 VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
1723 SemaObj->TentativeDefinitions[Var->getDeclName()] = Var;
1724 }
Douglas Gregor14c22f22009-04-22 22:18:58 +00001725
1726 // If there were any locally-scoped external declarations,
1727 // deserialize them and add them to Sema's table of locally-scoped
1728 // external declarations.
1729 for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
1730 NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
1731 SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
1732 }
Douglas Gregorb81c1702009-04-27 20:06:05 +00001733
1734 // If there were any ext_vector type declarations, deserialize them
1735 // and add them to Sema's vector of such declarations.
1736 for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
1737 SemaObj->ExtVectorDecls.push_back(
1738 cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
1739
1740 // If there were any Objective-C category implementations,
1741 // deserialize them and add them to Sema's vector of such
1742 // definitions.
1743 for (unsigned I = 0, N = ObjCCategoryImpls.size(); I != N; ++I)
1744 SemaObj->ObjCCategoryImpls.push_back(
1745 cast<ObjCCategoryImplDecl>(GetDecl(ObjCCategoryImpls[I])));
Douglas Gregor668c1a42009-04-21 22:25:48 +00001746}
1747
1748IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
1749 // Try to find this name within our on-disk hash table
1750 PCHIdentifierLookupTable *IdTable
1751 = (PCHIdentifierLookupTable *)IdentifierLookupTable;
1752 std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
1753 PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
1754 if (Pos == IdTable->end())
1755 return 0;
1756
1757 // Dereferencing the iterator has the effect of building the
1758 // IdentifierInfo node and populating it with the various
1759 // declarations it needs.
1760 return *Pos;
1761}
1762
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001763std::pair<ObjCMethodList, ObjCMethodList>
1764PCHReader::ReadMethodPool(Selector Sel) {
1765 if (!MethodPoolLookupTable)
1766 return std::pair<ObjCMethodList, ObjCMethodList>();
1767
1768 // Try to find this selector within our on-disk hash table.
1769 PCHMethodPoolLookupTable *PoolTable
1770 = (PCHMethodPoolLookupTable*)MethodPoolLookupTable;
1771 PCHMethodPoolLookupTable::iterator Pos = PoolTable->find(Sel);
Douglas Gregor83941df2009-04-25 17:48:32 +00001772 if (Pos == PoolTable->end()) {
1773 ++NumMethodPoolMisses;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001774 return std::pair<ObjCMethodList, ObjCMethodList>();;
Douglas Gregor83941df2009-04-25 17:48:32 +00001775 }
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001776
Douglas Gregor83941df2009-04-25 17:48:32 +00001777 ++NumMethodPoolSelectorsRead;
Douglas Gregorf0aaf7a2009-04-24 21:10:55 +00001778 return *Pos;
1779}
1780
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001781void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
Douglas Gregor668c1a42009-04-21 22:25:48 +00001782 assert(ID && "Non-zero identifier ID required");
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001783 assert(ID <= IdentifiersLoaded.size() && "Identifier ID out of range");
1784 IdentifiersLoaded[ID - 1] = II;
Douglas Gregor668c1a42009-04-21 22:25:48 +00001785}
1786
Chris Lattner7356a312009-04-11 21:15:38 +00001787IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
Douglas Gregorafaf3082009-04-11 00:14:32 +00001788 if (ID == 0)
1789 return 0;
Chris Lattner7356a312009-04-11 21:15:38 +00001790
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001791 if (!IdentifierTableData || IdentifiersLoaded.empty()) {
Douglas Gregorafaf3082009-04-11 00:14:32 +00001792 Error("No identifier table in PCH file");
1793 return 0;
1794 }
Chris Lattner7356a312009-04-11 21:15:38 +00001795
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001796 if (!IdentifiersLoaded[ID - 1]) {
1797 uint32_t Offset = IdentifierOffsets[ID - 1];
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001798 const char *Str = IdentifierTableData + Offset;
Douglas Gregord6595a42009-04-25 21:04:17 +00001799
1800 // If there is an identifier lookup table, but the offset of this
1801 // string is after the identifier table itself, then we know that
1802 // this string is not in the on-disk hash table. Therefore,
1803 // disable lookup into the hash table when looking for this
1804 // identifier.
1805 PCHIdentifierLookupTable *IdTable
1806 = (PCHIdentifierLookupTable *)IdentifierLookupTable;
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001807 if (!IdTable ||
1808 Offset >= uint32_t(IdTable->getBuckets() - IdTable->getBase())) {
1809 // Turn off lookup into the on-disk hash table. We know that
1810 // this identifier is not there.
1811 if (IdTable)
1812 PP.getIdentifierTable().setExternalIdentifierLookup(0);
Douglas Gregord6595a42009-04-25 21:04:17 +00001813
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001814 // All of the strings in the PCH file are preceded by a 16-bit
1815 // length. Extract that 16-bit length to avoid having to execute
1816 // strlen().
1817 const char *StrLenPtr = Str - 2;
1818 unsigned StrLen = (((unsigned) StrLenPtr[0])
1819 | (((unsigned) StrLenPtr[1]) << 8)) - 1;
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001820 IdentifiersLoaded[ID - 1]=&PP.getIdentifierTable().get(Str, Str + StrLen);
Douglas Gregord6595a42009-04-25 21:04:17 +00001821
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001822 // Turn on lookup into the on-disk hash table, if we have an
1823 // on-disk hash table.
1824 if (IdTable)
1825 PP.getIdentifierTable().setExternalIdentifierLookup(this);
1826 } else {
1827 // The identifier is a key in our on-disk hash table. Since we
1828 // know where the hash table entry starts, just read in this
1829 // (key, value) pair.
1830 PCHIdentifierLookupTrait Trait(const_cast<PCHReader &>(*this));
1831 const unsigned char *Pos = (const unsigned char *)Str - 4;
1832 std::pair<unsigned, unsigned> KeyDataLengths
1833 = Trait.ReadKeyDataLength(Pos);
Douglas Gregord6595a42009-04-25 21:04:17 +00001834
Douglas Gregor17e1c5e2009-04-25 21:21:38 +00001835 PCHIdentifierLookupTrait::internal_key_type InternalKey
1836 = Trait.ReadKey(Pos, KeyDataLengths.first);
1837 Pos = (const unsigned char *)Str + KeyDataLengths.first;
1838 IdentifiersLoaded[ID - 1] = Trait.ReadData(InternalKey, Pos,
1839 KeyDataLengths.second);
1840 }
Douglas Gregorafaf3082009-04-11 00:14:32 +00001841 }
Chris Lattner7356a312009-04-11 21:15:38 +00001842
Douglas Gregor2b3a5a82009-04-25 19:10:14 +00001843 return IdentifiersLoaded[ID - 1];
Douglas Gregor2cf26342009-04-09 22:27:44 +00001844}
1845
Douglas Gregor7f94b0b2009-04-27 06:38:32 +00001846void PCHReader::ReadSLocEntry(unsigned ID) {
1847 ReadSLocEntryRecord(ID);
1848}
1849
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001850Selector PCHReader::DecodeSelector(unsigned ID) {
1851 if (ID == 0)
1852 return Selector();
1853
Douglas Gregor83941df2009-04-25 17:48:32 +00001854 if (!MethodPoolLookupTableData) {
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001855 Error("No selector table in PCH file");
1856 return Selector();
1857 }
Douglas Gregor83941df2009-04-25 17:48:32 +00001858
1859 if (ID > TotalNumSelectors) {
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001860 Error("Selector ID out of range");
1861 return Selector();
1862 }
Douglas Gregor83941df2009-04-25 17:48:32 +00001863
1864 unsigned Index = ID - 1;
1865 if (SelectorsLoaded[Index].getAsOpaquePtr() == 0) {
1866 // Load this selector from the selector table.
1867 // FIXME: endianness portability issues with SelectorOffsets table
1868 PCHMethodPoolLookupTrait Trait(*this);
1869 SelectorsLoaded[Index]
1870 = Trait.ReadKey(MethodPoolLookupTableData + SelectorOffsets[Index], 0);
1871 }
1872
1873 return SelectorsLoaded[Index];
Steve Naroff90cd1bb2009-04-23 10:39:46 +00001874}
1875
Douglas Gregor2cf26342009-04-09 22:27:44 +00001876DeclarationName
1877PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
1878 DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
1879 switch (Kind) {
1880 case DeclarationName::Identifier:
1881 return DeclarationName(GetIdentifierInfo(Record, Idx));
1882
1883 case DeclarationName::ObjCZeroArgSelector:
1884 case DeclarationName::ObjCOneArgSelector:
1885 case DeclarationName::ObjCMultiArgSelector:
Steve Naroffa7503a72009-04-23 15:15:40 +00001886 return DeclarationName(GetSelector(Record, Idx));
Douglas Gregor2cf26342009-04-09 22:27:44 +00001887
1888 case DeclarationName::CXXConstructorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001889 return Context->DeclarationNames.getCXXConstructorName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00001890 GetType(Record[Idx++]));
1891
1892 case DeclarationName::CXXDestructorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001893 return Context->DeclarationNames.getCXXDestructorName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00001894 GetType(Record[Idx++]));
1895
1896 case DeclarationName::CXXConversionFunctionName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001897 return Context->DeclarationNames.getCXXConversionFunctionName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00001898 GetType(Record[Idx++]));
1899
1900 case DeclarationName::CXXOperatorName:
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001901 return Context->DeclarationNames.getCXXOperatorName(
Douglas Gregor2cf26342009-04-09 22:27:44 +00001902 (OverloadedOperatorKind)Record[Idx++]);
1903
1904 case DeclarationName::CXXUsingDirective:
1905 return DeclarationName::getUsingDirectiveName();
1906 }
1907
1908 // Required to silence GCC warning
1909 return DeclarationName();
1910}
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001911
Douglas Gregor0a2b45e2009-04-13 18:14:40 +00001912/// \brief Read an integral value
1913llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
1914 unsigned BitWidth = Record[Idx++];
1915 unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
1916 llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
1917 Idx += NumWords;
1918 return Result;
1919}
1920
1921/// \brief Read a signed integral value
1922llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
1923 bool isUnsigned = Record[Idx++];
1924 return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
1925}
1926
Douglas Gregor17fc2232009-04-14 21:55:33 +00001927/// \brief Read a floating-point value
1928llvm::APFloat PCHReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
Douglas Gregor17fc2232009-04-14 21:55:33 +00001929 return llvm::APFloat(ReadAPInt(Record, Idx));
1930}
1931
Douglas Gregor68a2eb02009-04-15 21:30:51 +00001932// \brief Read a string
1933std::string PCHReader::ReadString(const RecordData &Record, unsigned &Idx) {
1934 unsigned Len = Record[Idx++];
1935 std::string Result(&Record[Idx], &Record[Idx] + Len);
1936 Idx += Len;
1937 return Result;
1938}
1939
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001940DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
Douglas Gregore1d918e2009-04-10 23:10:45 +00001941 return Diag(SourceLocation(), DiagID);
1942}
1943
1944DiagnosticBuilder PCHReader::Diag(SourceLocation Loc, unsigned DiagID) {
1945 return PP.getDiagnostics().Report(FullSourceLoc(Loc,
Chris Lattnerd1d64a02009-04-27 21:45:14 +00001946 PP.getSourceManager()),
Douglas Gregor0a0428e2009-04-10 20:39:37 +00001947 DiagID);
1948}
Douglas Gregor025452f2009-04-17 00:04:06 +00001949
Douglas Gregor668c1a42009-04-21 22:25:48 +00001950/// \brief Retrieve the identifier table associated with the
1951/// preprocessor.
1952IdentifierTable &PCHReader::getIdentifierTable() {
1953 return PP.getIdentifierTable();
1954}
1955
Douglas Gregor025452f2009-04-17 00:04:06 +00001956/// \brief Record that the given ID maps to the given switch-case
1957/// statement.
1958void PCHReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
1959 assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
1960 SwitchCaseStmts[ID] = SC;
1961}
1962
1963/// \brief Retrieve the switch-case statement with the given ID.
1964SwitchCase *PCHReader::getSwitchCaseWithID(unsigned ID) {
1965 assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
1966 return SwitchCaseStmts[ID];
1967}
Douglas Gregor1de05fe2009-04-17 18:18:49 +00001968
1969/// \brief Record that the given label statement has been
1970/// deserialized and has the given ID.
1971void PCHReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
1972 assert(LabelStmts.find(ID) == LabelStmts.end() &&
1973 "Deserialized label twice");
1974 LabelStmts[ID] = S;
1975
1976 // If we've already seen any goto statements that point to this
1977 // label, resolve them now.
1978 typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
1979 std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
1980 for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
1981 Goto->second->setLabel(S);
1982 UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00001983
1984 // If we've already seen any address-label statements that point to
1985 // this label, resolve them now.
1986 typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
1987 std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
1988 = UnresolvedAddrLabelExprs.equal_range(ID);
1989 for (AddrLabelIter AddrLabel = AddrLabels.first;
1990 AddrLabel != AddrLabels.second; ++AddrLabel)
1991 AddrLabel->second->setLabel(S);
1992 UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
Douglas Gregor1de05fe2009-04-17 18:18:49 +00001993}
1994
1995/// \brief Set the label of the given statement to the label
1996/// identified by ID.
1997///
1998/// Depending on the order in which the label and other statements
1999/// referencing that label occur, this operation may complete
2000/// immediately (updating the statement) or it may queue the
2001/// statement to be back-patched later.
2002void PCHReader::SetLabelOf(GotoStmt *S, unsigned ID) {
2003 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
2004 if (Label != LabelStmts.end()) {
2005 // We've already seen this label, so set the label of the goto and
2006 // we're done.
2007 S->setLabel(Label->second);
2008 } else {
2009 // We haven't seen this label yet, so add this goto to the set of
2010 // unresolved goto statements.
2011 UnresolvedGotoStmts.insert(std::make_pair(ID, S));
2012 }
2013}
Douglas Gregor7d5c2f22009-04-17 18:58:21 +00002014
2015/// \brief Set the label of the given expression to the label
2016/// identified by ID.
2017///
2018/// Depending on the order in which the label and other statements
2019/// referencing that label occur, this operation may complete
2020/// immediately (updating the statement) or it may queue the
2021/// statement to be back-patched later.
2022void PCHReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
2023 std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
2024 if (Label != LabelStmts.end()) {
2025 // We've already seen this label, so set the label of the
2026 // label-address expression and we're done.
2027 S->setLabel(Label->second);
2028 } else {
2029 // We haven't seen this label yet, so add this label-address
2030 // expression to the set of unresolved label-address expressions.
2031 UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
2032 }
2033}