 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
59.4% |
462 / 778 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
88.0% |
685 / 778 |
| |
|
Line Coverage: |
77.9% |
1114 / 1430 |
| |
 |
|
 |
1 : //===--- PCHReader.cpp - Precompiled Headers Reader -------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the PCHReader class, which reads a precompiled header.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/Frontend/PCHReader.h"
15 : #include "clang/Frontend/FrontendDiagnostic.h"
16 : #include "clang/Frontend/Utils.h"
17 : #include "../Sema/Sema.h" // FIXME: move Sema headers elsewhere
18 : #include "clang/AST/ASTConsumer.h"
19 : #include "clang/AST/ASTContext.h"
20 : #include "clang/AST/Expr.h"
21 : #include "clang/AST/Type.h"
22 : #include "clang/AST/TypeLocVisitor.h"
23 : #include "clang/Lex/MacroInfo.h"
24 : #include "clang/Lex/Preprocessor.h"
25 : #include "clang/Lex/HeaderSearch.h"
26 : #include "clang/Basic/OnDiskHashTable.h"
27 : #include "clang/Basic/SourceManager.h"
28 : #include "clang/Basic/SourceManagerInternals.h"
29 : #include "clang/Basic/FileManager.h"
30 : #include "clang/Basic/TargetInfo.h"
31 : #include "clang/Basic/Version.h"
32 : #include "llvm/ADT/StringExtras.h"
33 : #include "llvm/Bitcode/BitstreamReader.h"
34 : #include "llvm/Support/MemoryBuffer.h"
35 : #include "llvm/Support/ErrorHandling.h"
36 : #include "llvm/System/Path.h"
37 : #include <algorithm>
38 : #include <iterator>
39 : #include <cstdio>
40 : #include <sys/stat.h>
41 : using namespace clang;
42 :
43 : //===----------------------------------------------------------------------===//
44 : // PCH reader validator implementation
45 : //===----------------------------------------------------------------------===//
46 :
44: branch 0 taken
44: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
44: branch 7 taken
47 44: PCHReaderListener::~PCHReaderListener() {}
48 :
49 : bool
50 35: PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
51 35: const LangOptions &PPLangOpts = PP.getLangOptions();
52 : #define PARSE_LANGOPT_BENIGN(Option)
53 : #define PARSE_LANGOPT_IMPORTANT(Option, DiagID) \
54 : if (PPLangOpts.Option != LangOpts.Option) { \
55 : Reader.Diag(DiagID) << LangOpts.Option << PPLangOpts.Option; \
56 : return true; \
57 : }
58 :
59 : PARSE_LANGOPT_BENIGN(Trigraphs);
60 : PARSE_LANGOPT_BENIGN(BCPLComment);
61 : PARSE_LANGOPT_BENIGN(DollarIdents);
62 : PARSE_LANGOPT_BENIGN(AsmPreprocessor);
0: branch 0 not taken
35: branch 1 taken
63 35: PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
64 : PARSE_LANGOPT_BENIGN(ImplicitInt);
65 : PARSE_LANGOPT_BENIGN(Digraphs);
66 : PARSE_LANGOPT_BENIGN(HexFloats);
0: branch 0 not taken
35: branch 1 taken
67 35: PARSE_LANGOPT_IMPORTANT(C99, diag::warn_pch_c99);
0: branch 0 not taken
35: branch 1 taken
68 35: PARSE_LANGOPT_IMPORTANT(Microsoft, diag::warn_pch_microsoft_extensions);
0: branch 0 not taken
35: branch 1 taken
69 35: PARSE_LANGOPT_IMPORTANT(CPlusPlus, diag::warn_pch_cplusplus);
0: branch 0 not taken
35: branch 1 taken
70 35: PARSE_LANGOPT_IMPORTANT(CPlusPlus0x, diag::warn_pch_cplusplus0x);
71 : PARSE_LANGOPT_BENIGN(CXXOperatorName);
0: branch 0 not taken
35: branch 1 taken
72 35: PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
0: branch 0 not taken
35: branch 1 taken
73 35: PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
0: branch 0 not taken
35: branch 1 taken
74 35: PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
0: branch 0 not taken
35: branch 1 taken
75 35: PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
76 : PARSE_LANGOPT_BENIGN(PascalStrings);
77 : PARSE_LANGOPT_BENIGN(WritableStrings);
0: branch 0 not taken
35: branch 1 taken
78 35: PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
79 : diag::warn_pch_lax_vector_conversions);
0: branch 0 not taken
35: branch 1 taken
80 35: PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
0: branch 0 not taken
35: branch 1 taken
81 35: PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
0: branch 0 not taken
35: branch 1 taken
82 35: PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
0: branch 0 not taken
35: branch 1 taken
83 35: PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
0: branch 0 not taken
35: branch 1 taken
84 35: PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
0: branch 0 not taken
35: branch 1 taken
85 35: PARSE_LANGOPT_IMPORTANT(ThreadsafeStatics,
86 : diag::warn_pch_thread_safe_statics);
0: branch 0 not taken
35: branch 1 taken
87 35: PARSE_LANGOPT_IMPORTANT(POSIXThreads, diag::warn_pch_posix_threads);
0: branch 0 not taken
35: branch 1 taken
88 35: PARSE_LANGOPT_IMPORTANT(Blocks, diag::warn_pch_blocks);
89 : PARSE_LANGOPT_BENIGN(EmitAllDecls);
0: branch 0 not taken
35: branch 1 taken
90 35: PARSE_LANGOPT_IMPORTANT(MathErrno, diag::warn_pch_math_errno);
0: branch 0 not taken
35: branch 1 taken
91 35: PARSE_LANGOPT_IMPORTANT(OverflowChecking, diag::warn_pch_overflow_checking);
0: branch 0 not taken
35: branch 1 taken
92 35: PARSE_LANGOPT_IMPORTANT(HeinousExtensions,
93 : diag::warn_pch_heinous_extensions);
94 : // FIXME: Most of the options below are benign if the macro wasn't
95 : // used. Unfortunately, this means that a PCH compiled without
96 : // optimization can't be used with optimization turned on, even
97 : // though the only thing that changes is whether __OPTIMIZE__ was
98 : // defined... but if __OPTIMIZE__ never showed up in the header, it
99 : // doesn't matter. We could consider making this some special kind
100 : // of check.
0: branch 0 not taken
35: branch 1 taken
101 35: PARSE_LANGOPT_IMPORTANT(Optimize, diag::warn_pch_optimize);
0: branch 0 not taken
35: branch 1 taken
102 35: PARSE_LANGOPT_IMPORTANT(OptimizeSize, diag::warn_pch_optimize_size);
0: branch 0 not taken
35: branch 1 taken
103 35: PARSE_LANGOPT_IMPORTANT(Static, diag::warn_pch_static);
0: branch 0 not taken
35: branch 1 taken
104 35: PARSE_LANGOPT_IMPORTANT(PICLevel, diag::warn_pch_pic_level);
0: branch 0 not taken
35: branch 1 taken
105 35: PARSE_LANGOPT_IMPORTANT(GNUInline, diag::warn_pch_gnu_inline);
0: branch 0 not taken
35: branch 1 taken
106 35: PARSE_LANGOPT_IMPORTANT(NoInline, diag::warn_pch_no_inline);
0: branch 0 not taken
35: branch 1 taken
107 35: PARSE_LANGOPT_IMPORTANT(AccessControl, diag::warn_pch_access_control);
0: branch 0 not taken
35: branch 1 taken
108 35: PARSE_LANGOPT_IMPORTANT(CharIsSigned, diag::warn_pch_char_signed);
0: branch 0 not taken
35: branch 1 taken
109 35: PARSE_LANGOPT_IMPORTANT(ShortWChar, diag::warn_pch_short_wchar);
0: branch 2 not taken
35: branch 3 taken
110 35: if ((PPLangOpts.getGCMode() != 0) != (LangOpts.getGCMode() != 0)) {
111 : Reader.Diag(diag::warn_pch_gc_mode)
112 0: << LangOpts.getGCMode() << PPLangOpts.getGCMode();
113 0: return true;
114 : }
115 : PARSE_LANGOPT_BENIGN(getVisibilityMode());
0: branch 2 not taken
35: branch 3 taken
116 35: PARSE_LANGOPT_IMPORTANT(getStackProtectorMode(),
117 : diag::warn_pch_stack_protector);
118 : PARSE_LANGOPT_BENIGN(InstantiationDepth);
0: branch 0 not taken
35: branch 1 taken
119 35: PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
120 : PARSE_LANGOPT_BENIGN(CatchUndefined);
0: branch 0 not taken
35: branch 1 taken
121 35: PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
122 : #undef PARSE_LANGOPT_IRRELEVANT
123 : #undef PARSE_LANGOPT_BENIGN
124 :
125 35: return false;
126 : }
127 :
128 35: bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
35: branch 5 taken
0: branch 6 not taken
129 35: if (Triple == PP.getTargetInfo().getTriple().str())
130 35: return false;
131 :
132 : Reader.Diag(diag::warn_pch_target_triple)
133 0: << Triple << PP.getTargetInfo().getTriple().str();
134 0: return true;
135 : }
136 :
137 : bool PCHValidator::ReadPredefinesBuffer(llvm::StringRef PCHPredef,
138 : FileID PCHBufferID,
139 : llvm::StringRef OriginalFileName,
140 34: std::string &SuggestedPredefines) {
141 : // We are in the context of an implicit include, so the predefines buffer will
142 : // have a #include entry for the PCH file itself (as normalized by the
143 : // preprocessor initialization). Find it and skip over it in the checking
144 : // below.
145 34: llvm::SmallString<256> PCHInclude;
146 34: PCHInclude += "#include \"";
147 34: PCHInclude += NormalizeDashIncludePath(OriginalFileName);
148 34: PCHInclude += "\"\n";
149 : std::pair<llvm::StringRef,llvm::StringRef> Split =
150 34: llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
151 34: llvm::StringRef Left = Split.first, Right = Split.second;
34: branch 3 taken
0: branch 4 not taken
152 34: assert(Left != PP.getPredefines() && "Missing PCH include entry!");
153 :
154 : // If the predefines is equal to the joined left and right halves, we're done!
31: branch 3 taken
3: branch 4 taken
31: branch 6 taken
0: branch 7 not taken
31: branch 9 taken
0: branch 10 not taken
31: branch 11 taken
3: branch 12 taken
155 65: if (Left.size() + Right.size() == PCHPredef.size() &&
156 : PCHPredef.startswith(Left) && PCHPredef.endswith(Right))
157 31: return false;
158 :
159 3: SourceManager &SourceMgr = PP.getSourceManager();
160 :
161 : // The predefines buffers are different. Determine what the differences are,
162 : // and whether they require us to reject the PCH file.
163 3: llvm::SmallVector<llvm::StringRef, 8> PCHLines;
164 3: PCHPredef.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
165 :
166 3: llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
167 3: Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
168 3: Right.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
169 :
170 : // Sort both sets of predefined buffer lines, since we allow some extra
171 : // definitions and they may appear at any point in the output.
172 3: std::sort(CmdLineLines.begin(), CmdLineLines.end());
173 3: std::sort(PCHLines.begin(), PCHLines.end());
174 :
175 : // Determine which predefines that were used to build the PCH file are missing
176 : // from the command line.
177 3: std::vector<llvm::StringRef> MissingPredefines;
178 : std::set_difference(PCHLines.begin(), PCHLines.end(),
179 : CmdLineLines.begin(), CmdLineLines.end(),
180 3: std::back_inserter(MissingPredefines));
181 :
182 3: bool MissingDefines = false;
183 3: bool ConflictingDefines = false;
1: branch 2 taken
0: branch 3 not taken
1: branch 4 taken
3: branch 5 taken
184 5: for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
185 1: llvm::StringRef Missing = MissingPredefines[I];
0: branch 2 not taken
1: branch 3 taken
186 1: if (!Missing.startswith("#define ")) {
187 0: Reader.Diag(diag::warn_pch_compiler_options_mismatch);
188 0: return true;
189 : }
190 :
191 : // This is a macro definition. Determine the name of the macro we're
192 : // defining.
193 1: std::string::size_type StartOfMacroName = strlen("#define ");
194 : std::string::size_type EndOfMacroName
195 1: = Missing.find_first_of("( \n\r", StartOfMacroName);
196 : assert(EndOfMacroName != std::string::npos &&
0: branch 0 not taken
1: branch 1 taken
197 1: "Couldn't find the end of the macro name");
198 1: llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
199 :
200 : // Determine whether this macro was given a different definition on the
201 : // command line.
202 1: std::string MacroDefStart = "#define " + MacroName.str();
203 1: std::string::size_type MacroDefLen = MacroDefStart.size();
204 : llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
205 : = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
206 1: MacroDefStart);
1: branch 1 taken
0: branch 2 not taken
207 1: for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
1: branch 2 taken
0: branch 3 not taken
208 1: if (!ConflictPos->startswith(MacroDefStart)) {
209 : // Different macro; we're done.
210 1: ConflictPos = CmdLineLines.end();
211 1: break;
212 : }
213 :
214 : assert(ConflictPos->size() > MacroDefLen &&
0: branch 1 not taken
0: branch 2 not taken
215 0: "Invalid #define in predefines buffer?");
0: branch 1 not taken
0: branch 2 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
216 0: if ((*ConflictPos)[MacroDefLen] != ' ' &&
217 : (*ConflictPos)[MacroDefLen] != '(')
218 0: continue; // Longer macro name; keep trying.
219 :
220 : // We found a conflicting macro definition.
221 0: break;
222 : }
223 :
0: branch 1 not taken
1: branch 2 taken
224 1: if (ConflictPos != CmdLineLines.end()) {
225 : Reader.Diag(diag::warn_cmdline_conflicting_macro_def)
226 0: << MacroName;
227 :
228 : // Show the definition of this macro within the PCH file.
229 0: llvm::StringRef::size_type Offset = PCHPredef.find(Missing);
0: branch 0 not taken
0: branch 1 not taken
230 0: assert(Offset != llvm::StringRef::npos && "Unable to find macro!");
231 : SourceLocation PCHMissingLoc = SourceMgr.getLocForStartOfFile(PCHBufferID)
232 0: .getFileLocWithOffset(Offset);
233 0: Reader.Diag(PCHMissingLoc, diag::note_pch_macro_defined_as) << MacroName;
234 :
235 0: ConflictingDefines = true;
236 0: continue;
237 : }
238 :
239 : // If the macro doesn't conflict, then we'll just pick up the macro
240 : // definition from the PCH file. Warn the user that they made a mistake.
0: branch 0 not taken
1: branch 1 taken
241 1: if (ConflictingDefines)
242 : continue; // Don't complain if there are already conflicting defs
243 :
1: branch 0 taken
0: branch 1 not taken
244 1: if (!MissingDefines) {
245 1: Reader.Diag(diag::warn_cmdline_missing_macro_defs);
246 1: MissingDefines = true;
247 : }
248 :
249 : // Show the definition of this macro within the PCH file.
250 1: llvm::StringRef::size_type Offset = PCHPredef.find(Missing);
0: branch 0 not taken
1: branch 1 taken
251 1: assert(Offset != llvm::StringRef::npos && "Unable to find macro!");
252 : SourceLocation PCHMissingLoc = SourceMgr.getLocForStartOfFile(PCHBufferID)
253 1: .getFileLocWithOffset(Offset);
254 1: Reader.Diag(PCHMissingLoc, diag::note_using_macro_def_from_pch);
255 : }
256 :
0: branch 0 not taken
3: branch 1 taken
257 3: if (ConflictingDefines)
258 0: return true;
259 :
260 : // Determine what predefines were introduced based on command-line
261 : // parameters that were not present when building the PCH
262 : // file. Extra #defines are okay, so long as the identifiers being
263 : // defined were not used within the precompiled header.
264 3: std::vector<llvm::StringRef> ExtraPredefines;
265 : std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
266 : PCHLines.begin(), PCHLines.end(),
267 3: std::back_inserter(ExtraPredefines));
4: branch 1 taken
2: branch 2 taken
268 6: for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
269 4: llvm::StringRef &Extra = ExtraPredefines[I];
0: branch 2 not taken
4: branch 3 taken
270 4: if (!Extra.startswith("#define ")) {
271 0: Reader.Diag(diag::warn_pch_compiler_options_mismatch);
272 0: return true;
273 : }
274 :
275 : // This is an extra macro definition. Determine the name of the
276 : // macro we're defining.
277 4: std::string::size_type StartOfMacroName = strlen("#define ");
278 : std::string::size_type EndOfMacroName
279 4: = Extra.find_first_of("( \n\r", StartOfMacroName);
280 : assert(EndOfMacroName != std::string::npos &&
0: branch 0 not taken
4: branch 1 taken
281 4: "Couldn't find the end of the macro name");
282 4: llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
283 :
284 : // Check whether this name was used somewhere in the PCH file. If
285 : // so, defining it as a macro could change behavior, so we reject
286 : // the PCH file.
1: branch 1 taken
3: branch 2 taken
287 4: if (IdentifierInfo *II = Reader.get(MacroName)) {
288 1: Reader.Diag(diag::warn_macro_name_used_in_pch) << II;
289 1: return true;
290 : }
291 :
292 : // Add this definition to the suggested predefines buffer.
293 3: SuggestedPredefines += Extra;
294 3: SuggestedPredefines += '\n';
295 : }
296 :
297 : // If we get here, it's because the predefines buffer had compatible
298 : // contents. Accept the PCH file.
299 2: return false;
300 : }
301 :
302 39: void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI) {
303 39: PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
304 39: }
305 :
306 4: void PCHValidator::ReadCounter(unsigned Value) {
307 4: PP.setCounterValue(Value);
308 4: }
309 :
310 : //===----------------------------------------------------------------------===//
311 : // PCH reader implementation
312 : //===----------------------------------------------------------------------===//
313 :
314 : PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,
315 35: const char *isysroot)
316 : : Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()),
317 : FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
318 : SemaObj(0), PP(&PP), Context(Context), StatCache(0), Consumer(0),
319 : IdentifierTableData(0), IdentifierLookupTable(0),
320 : IdentifierOffsets(0),
321 : MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
322 : TotalSelectorsInMethodPool(0), SelectorOffsets(0),
323 : TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot),
324 : NumStatHits(0), NumStatMisses(0),
325 : NumSLocEntriesRead(0), NumStatementsRead(0),
326 : NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
327 : NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
328 35: CurrentlyLoadingTypeOrDecl(0) {
329 35: RelocatablePCH = false;
330 35: }
331 :
332 : PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
333 13: Diagnostic &Diags, const char *isysroot)
334 : : SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags),
335 : SemaObj(0), PP(0), Context(0), StatCache(0), Consumer(0),
336 : IdentifierTableData(0), IdentifierLookupTable(0),
337 : IdentifierOffsets(0),
338 : MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
339 : TotalSelectorsInMethodPool(0), SelectorOffsets(0),
340 : TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot),
341 : NumStatHits(0), NumStatMisses(0),
342 : NumSLocEntriesRead(0), NumStatementsRead(0),
343 : NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
344 : NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0),
345 13: CurrentlyLoadingTypeOrDecl(0) {
346 13: RelocatablePCH = false;
347 13: }
348 :
44: branch 34 taken
0: branch 35 not taken
0: branch 71 not taken
0: branch 72 not taken
0: branch 108 not taken
0: branch 109 not taken
349 44: PCHReader::~PCHReader() {}
350 :
351 41: Expr *PCHReader::ReadDeclExpr() {
352 41: return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
353 : }
354 :
355 37: Expr *PCHReader::ReadTypeExpr() {
356 37: return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
357 : }
358 :
359 :
360 : namespace {
361 : class PCHMethodPoolLookupTrait {
362 : PCHReader &Reader;
363 :
364 : public:
365 : typedef std::pair<ObjCMethodList, ObjCMethodList> data_type;
366 :
367 : typedef Selector external_key_type;
368 : typedef external_key_type internal_key_type;
369 :
370 30: explicit PCHMethodPoolLookupTrait(PCHReader &Reader) : Reader(Reader) { }
371 :
372 : static bool EqualKey(const internal_key_type& a,
373 1: const internal_key_type& b) {
374 1: return a == b;
375 : }
376 :
377 1: static unsigned ComputeHash(Selector Sel) {
378 1: unsigned N = Sel.getNumArgs();
0: branch 0 not taken
1: branch 1 taken
379 1: if (N == 0)
380 0: ++N;
381 1: unsigned R = 5381;
1: branch 0 taken
1: branch 1 taken
382 2: for (unsigned I = 0; I != N; ++I)
1: branch 1 taken
0: branch 2 not taken
383 1: if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
384 1: R = llvm::HashString(II->getName(), R);
385 1: return R;
386 : }
387 :
388 : // This hopefully will just get inlined and removed by the optimizer.
389 : static const internal_key_type&
390 1: GetInternalKey(const external_key_type& x) { return x; }
391 :
392 : static std::pair<unsigned, unsigned>
393 1: ReadKeyDataLength(const unsigned char*& d) {
394 : using namespace clang::io;
395 1: unsigned KeyLen = ReadUnalignedLE16(d);
396 1: unsigned DataLen = ReadUnalignedLE16(d);
397 1: return std::make_pair(KeyLen, DataLen);
398 : }
399 :
400 25: internal_key_type ReadKey(const unsigned char* d, unsigned) {
401 : using namespace clang::io;
402 25: SelectorTable &SelTable = Reader.getContext()->Selectors;
403 25: unsigned N = ReadUnalignedLE16(d);
404 : IdentifierInfo *FirstII
405 25: = Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d));
19: branch 0 taken
6: branch 1 taken
406 25: if (N == 0)
407 19: return SelTable.getNullarySelector(FirstII);
6: branch 0 taken
0: branch 1 not taken
408 6: else if (N == 1)
409 6: return SelTable.getUnarySelector(FirstII);
410 :
411 0: llvm::SmallVector<IdentifierInfo *, 16> Args;
412 0: Args.push_back(FirstII);
0: branch 0 not taken
0: branch 1 not taken
413 0: for (unsigned I = 1; I != N; ++I)
414 0: Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
415 :
416 0: return SelTable.getSelector(N, Args.data());
417 : }
418 :
419 1: data_type ReadData(Selector, const unsigned char* d, unsigned DataLen) {
420 : using namespace clang::io;
421 1: unsigned NumInstanceMethods = ReadUnalignedLE16(d);
422 1: unsigned NumFactoryMethods = ReadUnalignedLE16(d);
423 :
424 1: data_type Result;
425 :
426 : // Load instance methods
427 1: ObjCMethodList *Prev = 0;
2: branch 0 taken
1: branch 1 taken
428 3: for (unsigned I = 0; I != NumInstanceMethods; ++I) {
429 : ObjCMethodDecl *Method
430 2: = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
1: branch 0 taken
1: branch 1 taken
431 2: if (!Result.first.Method) {
432 : // This is the first method, which is the easy case.
433 1: Result.first.Method = Method;
434 1: Prev = &Result.first;
435 1: continue;
436 : }
437 :
438 1: Prev->Next = new ObjCMethodList(Method, 0);
439 1: Prev = Prev->Next;
440 : }
441 :
442 : // Load factory methods
443 1: Prev = 0;
0: branch 0 not taken
1: branch 1 taken
444 1: for (unsigned I = 0; I != NumFactoryMethods; ++I) {
445 : ObjCMethodDecl *Method
446 0: = cast<ObjCMethodDecl>(Reader.GetDecl(ReadUnalignedLE32(d)));
0: branch 0 not taken
0: branch 1 not taken
447 0: if (!Result.second.Method) {
448 : // This is the first method, which is the easy case.
449 0: Result.second.Method = Method;
450 0: Prev = &Result.second;
451 0: continue;
452 : }
453 :
454 0: Prev->Next = new ObjCMethodList(Method, 0);
455 0: Prev = Prev->Next;
456 : }
457 :
458 : return Result;
459 : }
460 : };
461 :
462 : } // end anonymous namespace
463 :
464 : /// \brief The on-disk hash table used for the global method pool.
465 : typedef OnDiskChainedHashTable<PCHMethodPoolLookupTrait>
466 : PCHMethodPoolLookupTable;
467 :
468 : namespace {
469 : class PCHIdentifierLookupTrait {
470 : PCHReader &Reader;
471 :
472 : // If we know the IdentifierInfo in advance, it is here and we will
473 : // not build a new one. Used when deserializing information about an
474 : // identifier that was constructed before the PCH file was read.
475 : IdentifierInfo *KnownII;
476 :
477 : public:
478 : typedef IdentifierInfo * data_type;
479 :
480 : typedef const std::pair<const char*, unsigned> external_key_type;
481 :
482 : typedef external_key_type internal_key_type;
483 :
484 3890: explicit PCHIdentifierLookupTrait(PCHReader &Reader, IdentifierInfo *II = 0)
485 3890: : Reader(Reader), KnownII(II) { }
486 :
487 : static bool EqualKey(const internal_key_type& a,
488 5417: const internal_key_type& b) {
489 : return (a.second == b.second) ? memcmp(a.first, b.first, a.second) == 0
5417: branch 0 taken
0: branch 1 not taken
5416: branch 3 taken
1: branch 4 taken
490 5417: : false;
491 : }
492 :
493 5613: static unsigned ComputeHash(const internal_key_type& a) {
494 5613: return llvm::HashString(llvm::StringRef(a.first, a.second));
495 : }
496 :
497 : // This hopefully will just get inlined and removed by the optimizer.
498 : static const internal_key_type&
499 5613: GetInternalKey(const external_key_type& x) { return x; }
500 :
501 : static std::pair<unsigned, unsigned>
502 6779: ReadKeyDataLength(const unsigned char*& d) {
503 : using namespace clang::io;
504 6779: unsigned DataLen = ReadUnalignedLE16(d);
505 6779: unsigned KeyLen = ReadUnalignedLE16(d);
506 6779: return std::make_pair(KeyLen, DataLen);
507 : }
508 :
509 : static std::pair<const char*, unsigned>
510 5417: ReadKey(const unsigned char* d, unsigned n) {
5417: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
5417: branch 3 taken
511 5417: assert(n >= 2 && d[n-1] == '\0');
512 5417: return std::make_pair((const char*) d, n-1);
513 : }
514 :
515 : IdentifierInfo *ReadData(const internal_key_type& k,
516 : const unsigned char* d,
517 5416: unsigned DataLen) {
518 : using namespace clang::io;
519 5416: pch::IdentID ID = ReadUnalignedLE32(d);
520 5416: bool IsInteresting = ID & 0x01;
521 :
522 : // Wipe out the "is interesting" bit.
523 5416: ID = ID >> 1;
524 :
3483: branch 0 taken
1933: branch 1 taken
525 5416: if (!IsInteresting) {
526 : // For unintersting identifiers, just build the IdentifierInfo
527 : // and associate it with the persistent ID.
528 3483: IdentifierInfo *II = KnownII;
305: branch 0 taken
3178: branch 1 taken
529 3483: if (!II)
530 : II = &Reader.getIdentifierTable().CreateIdentifierInfo(
531 305: k.first, k.first + k.second);
532 3483: Reader.SetIdentifierInfo(ID, II);
533 3483: return II;
534 : }
535 :
536 1933: unsigned Bits = ReadUnalignedLE16(d);
537 1933: bool CPlusPlusOperatorKeyword = Bits & 0x01;
538 1933: Bits >>= 1;
539 1933: bool Poisoned = Bits & 0x01;
540 1933: Bits >>= 1;
541 1933: bool ExtensionToken = Bits & 0x01;
542 1933: Bits >>= 1;
543 1933: bool hasMacroDefinition = Bits & 0x01;
544 1933: Bits >>= 1;
545 1933: unsigned ObjCOrBuiltinID = Bits & 0x3FF;
546 1933: Bits >>= 10;
547 :
0: branch 0 not taken
1933: branch 1 taken
548 1933: assert(Bits == 0 && "Extra bits in the identifier?");
549 1933: DataLen -= 6;
550 :
551 : // Build the IdentifierInfo itself and link the identifier ID with
552 : // the new IdentifierInfo.
553 1933: IdentifierInfo *II = KnownII;
1268: branch 0 taken
665: branch 1 taken
554 1933: if (!II)
555 : II = &Reader.getIdentifierTable().CreateIdentifierInfo(
556 1268: k.first, k.first + k.second);
557 1933: Reader.SetIdentifierInfo(ID, II);
558 :
559 : // Set or check the various bits in the IdentifierInfo structure.
560 : // FIXME: Load token IDs lazily, too?
561 1933: II->setObjCOrBuiltinID(ObjCOrBuiltinID);
562 : assert(II->isExtensionToken() == ExtensionToken &&
1933: branch 1 taken
0: branch 2 not taken
563 1933: "Incorrect extension token flag");
564 : (void)ExtensionToken;
565 1933: II->setIsPoisoned(Poisoned);
566 : assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword &&
1933: branch 1 taken
0: branch 2 not taken
567 1933: "Incorrect C++ operator keyword flag");
568 : (void)CPlusPlusOperatorKeyword;
569 :
570 : // If this identifier is a macro, deserialize the macro
571 : // definition.
324: branch 0 taken
1609: branch 1 taken
572 1933: if (hasMacroDefinition) {
573 324: uint32_t Offset = ReadUnalignedLE32(d);
574 324: Reader.ReadMacroRecord(Offset);
575 324: DataLen -= 4;
576 : }
577 :
578 : // Read all of the declarations visible at global scope with this
579 : // name.
0: branch 1 not taken
1933: branch 2 taken
580 1933: if (Reader.getContext() == 0) return II;
287: branch 0 taken
1646: branch 1 taken
581 1933: if (DataLen > 0) {
582 287: llvm::SmallVector<uint32_t, 4> DeclIDs;
299: branch 0 taken
287: branch 1 taken
583 586: for (; DataLen > 0; DataLen -= 4)
584 299: DeclIDs.push_back(ReadUnalignedLE32(d));
585 287: Reader.SetGloballyVisibleDecls(II, DeclIDs);
586 : }
587 :
588 1933: return II;
589 : }
590 : };
591 :
592 : } // end anonymous namespace
593 :
594 : /// \brief The on-disk hash table used to contain information about
595 : /// all of the identifiers in the program.
596 : typedef OnDiskChainedHashTable<PCHIdentifierLookupTrait>
597 : PCHIdentifierLookupTable;
598 :
599 1: bool PCHReader::Error(const char *Msg) {
600 1: unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Fatal, Msg);
601 1: Diag(DiagID);
602 1: return true;
603 : }
604 :
605 : /// \brief Check the contents of the predefines buffer against the
606 : /// contents of the predefines buffer used to build the PCH file.
607 : ///
608 : /// The contents of the two predefines buffers should be the same. If
609 : /// not, then some command-line option changed the preprocessor state
610 : /// and we must reject the PCH file.
611 : ///
612 : /// \param PCHPredef The start of the predefines buffer in the PCH
613 : /// file.
614 : ///
615 : /// \param PCHPredefLen The length of the predefines buffer in the PCH
616 : /// file.
617 : ///
618 : /// \param PCHBufferID The FileID for the PCH predefines buffer.
619 : ///
620 : /// \returns true if there was a mismatch (in which case the PCH file
621 : /// should be ignored), or false otherwise.
622 : bool PCHReader::CheckPredefinesBuffer(llvm::StringRef PCHPredef,
623 47: FileID PCHBufferID) {
47: branch 1 taken
0: branch 2 not taken
624 47: if (Listener)
625 : return Listener->ReadPredefinesBuffer(PCHPredef, PCHBufferID,
626 : ActualOriginalFileName,
627 47: SuggestedPredefines);
628 0: return false;
629 : }
630 :
631 : //===----------------------------------------------------------------------===//
632 : // Source Manager Deserialization
633 : //===----------------------------------------------------------------------===//
634 :
635 : /// \brief Read the line table in the source manager block.
636 : /// \returns true if ther was an error.
637 48: bool PCHReader::ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record) {
638 48: unsigned Idx = 0;
639 48: LineTableInfo &LineTable = SourceMgr.getLineTable();
640 :
641 : // Parse the file names
642 48: std::map<int, int> FileIDs;
97: branch 2 taken
48: branch 3 taken
643 145: for (int I = 0, N = Record[Idx++]; I != N; ++I) {
644 : // Extract the file name
645 97: unsigned FilenameLen = Record[Idx++];
646 97: std::string Filename(&Record[Idx], &Record[Idx] + FilenameLen);
647 97: Idx += FilenameLen;
648 97: MaybeAddSystemRootToFilename(Filename);
649 : FileIDs[I] = LineTable.getLineTableFilenameID(Filename.c_str(),
650 97: Filename.size());
651 : }
652 :
653 : // Parse the line entries
654 48: std::vector<LineEntry> Entries;
49: branch 1 taken
48: branch 2 taken
655 145: while (Idx < Record.size()) {
656 49: int FID = FileIDs[Record[Idx++]];
657 :
658 : // Extract the line entries
659 49: unsigned NumEntries = Record[Idx++];
660 49: Entries.clear();
661 49: Entries.reserve(NumEntries);
145: branch 0 taken
49: branch 1 taken
662 194: for (unsigned I = 0; I != NumEntries; ++I) {
663 145: unsigned FileOffset = Record[Idx++];
664 145: unsigned LineNo = Record[Idx++];
665 145: int FilenameID = Record[Idx++];
666 : SrcMgr::CharacteristicKind FileKind
667 145: = (SrcMgr::CharacteristicKind)Record[Idx++];
668 145: unsigned IncludeOffset = Record[Idx++];
669 : Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID,
670 145: FileKind, IncludeOffset));
671 : }
672 49: LineTable.AddEntry(FID, Entries);
673 : }
674 :
675 48: return false;
676 : }
677 :
678 : namespace {
679 :
680 : class PCHStatData {
681 : public:
682 : const bool hasStat;
683 : const ino_t ino;
684 : const dev_t dev;
685 : const mode_t mode;
686 : const time_t mtime;
687 : const off_t size;
688 :
689 95: PCHStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s)
690 95: : hasStat(true), ino(i), dev(d), mode(mo), mtime(m), size(s) {}
691 :
692 0: PCHStatData()
693 0: : hasStat(false), ino(0), dev(0), mode(0), mtime(0), size(0) {}
694 : };
695 :
696 : class PCHStatLookupTrait {
697 : public:
698 : typedef const char *external_key_type;
699 : typedef const char *internal_key_type;
700 :
701 : typedef PCHStatData data_type;
702 :
703 133: static unsigned ComputeHash(const char *path) {
704 133: return llvm::HashString(path);
705 : }
706 :
707 133: static internal_key_type GetInternalKey(const char *path) { return path; }
708 :
709 95: static bool EqualKey(internal_key_type a, internal_key_type b) {
710 95: return strcmp(a, b) == 0;
711 : }
712 :
713 : static std::pair<unsigned, unsigned>
714 96: ReadKeyDataLength(const unsigned char*& d) {
715 96: unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
716 96: unsigned DataLen = (unsigned) *d++;
717 96: return std::make_pair(KeyLen + 1, DataLen);
718 : }
719 :
720 95: static internal_key_type ReadKey(const unsigned char *d, unsigned) {
721 95: return (const char *)d;
722 : }
723 :
724 : static data_type ReadData(const internal_key_type, const unsigned char *d,
725 95: unsigned /*DataLen*/) {
726 : using namespace clang::io;
727 :
0: branch 0 not taken
95: branch 1 taken
728 95: if (*d++ == 1)
729 0: return data_type();
730 :
731 95: ino_t ino = (ino_t) ReadUnalignedLE32(d);
732 95: dev_t dev = (dev_t) ReadUnalignedLE32(d);
733 95: mode_t mode = (mode_t) ReadUnalignedLE16(d);
734 95: time_t mtime = (time_t) ReadUnalignedLE64(d);
735 95: off_t size = (off_t) ReadUnalignedLE64(d);
736 95: return data_type(ino, dev, mode, mtime, size);
737 : }
738 : };
739 :
740 : /// \brief stat() cache for precompiled headers.
741 : ///
742 : /// This cache is very similar to the stat cache used by pretokenized
743 : /// headers.
744 : class PCHStatCache : public StatSysCallCache {
745 : typedef OnDiskChainedHashTable<PCHStatLookupTrait> CacheTy;
746 : CacheTy *Cache;
747 :
748 : unsigned &NumStatHits, &NumStatMisses;
749 : public:
750 : PCHStatCache(const unsigned char *Buckets,
751 : const unsigned char *Base,
752 : unsigned &NumStatHits,
753 46: unsigned &NumStatMisses)
754 46: : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) {
755 46: Cache = CacheTy::Create(Buckets, Base);
756 46: }
757 :
43: branch 2 taken
0: branch 3 not taken
0: branch 7 not taken
0: branch 8 not taken
758 43: ~PCHStatCache() { delete Cache; }
759 :
760 133: int stat(const char *path, struct stat *buf) {
761 : // Do the lookup for the file's data in the PCH file.
762 133: CacheTy::iterator I = Cache->find(path);
763 :
764 : // If we don't get a hit in the PCH file just forward to 'stat'.
38: branch 2 taken
95: branch 3 taken
765 133: if (I == Cache->end()) {
766 38: ++NumStatMisses;
767 38: return StatSysCallCache::stat(path, buf);
768 : }
769 :
770 95: ++NumStatHits;
771 95: PCHStatData Data = *I;
772 :
0: branch 0 not taken
95: branch 1 taken
773 95: if (!Data.hasStat)
774 0: return 1;
775 :
776 95: buf->st_ino = Data.ino;
777 95: buf->st_dev = Data.dev;
778 95: buf->st_mtime = Data.mtime;
779 95: buf->st_mode = Data.mode;
780 95: buf->st_size = Data.size;
781 95: return 0;
782 : }
783 : };
784 : } // end anonymous namespace
785 :
786 :
787 : /// \brief Read the source manager block
788 48: PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {
789 : using namespace SrcMgr;
790 :
791 : // Set the source-location entry cursor to the current position in
792 : // the stream. This cursor will be used to read the contents of the
793 : // source manager block initially, and then lazily read
794 : // source-location entries as needed.
795 48: SLocEntryCursor = Stream;
796 :
797 : // The stream itself is going to skip over the source manager block.
0: branch 1 not taken
48: branch 2 taken
798 48: if (Stream.SkipBlock()) {
799 0: Error("malformed block record in PCH file");
800 0: return Failure;
801 : }
802 :
803 : // Enter the source manager block.
0: branch 1 not taken
48: branch 2 taken
804 48: if (SLocEntryCursor.EnterSubBlock(pch::SOURCE_MANAGER_BLOCK_ID)) {
805 0: Error("malformed source manager block record in PCH file");
806 0: return Failure;
807 : }
808 :
809 48: RecordData Record;
810 296: while (true) {
811 344: unsigned Code = SLocEntryCursor.ReadCode();
0: branch 0 not taken
344: branch 1 taken
812 344: if (Code == llvm::bitc::END_BLOCK) {
0: branch 1 not taken
0: branch 2 not taken
813 0: if (SLocEntryCursor.ReadBlockEnd()) {
814 0: Error("error at end of Source Manager block in PCH file");
815 0: return Failure;
816 : }
817 0: return Success;
818 : }
819 :
0: branch 0 not taken
344: branch 1 taken
820 344: if (Code == llvm::bitc::ENTER_SUBBLOCK) {
821 : // No known subblocks, always skip them.
822 0: SLocEntryCursor.ReadSubBlockID();
0: branch 1 not taken
0: branch 2 not taken
823 0: if (SLocEntryCursor.SkipBlock()) {
824 0: Error("malformed block record in PCH file");
825 0: return Failure;
826 : }
827 0: continue;
828 : }
829 :
192: branch 0 taken
152: branch 1 taken
830 344: if (Code == llvm::bitc::DEFINE_ABBREV) {
831 192: SLocEntryCursor.ReadAbbrevRecord();
832 192: continue;
833 : }
834 :
835 : // Read a record.
836 : const char *BlobStart;
837 : unsigned BlobLen;
838 152: Record.clear();
0: branch 1 not taken
48: branch 2 taken
56: branch 3 taken
48: branch 4 taken
839 152: switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
840 : default: // Default behavior: ignore.
841 0: break;
842 :
843 : case pch::SM_LINE_TABLE:
0: branch 1 not taken
48: branch 2 taken
844 48: if (ParseLineTable(Record))
845 0: return Failure;
846 48: break;
847 :
848 : case pch::SM_HEADER_FILE_INFO: {
849 56: HeaderFileInfo HFI;
850 56: HFI.isImport = Record[0];
851 56: HFI.DirInfo = Record[1];
852 56: HFI.NumIncludes = Record[2];
853 56: HFI.ControllingMacroID = Record[3];
56: branch 1 taken
0: branch 2 not taken
854 56: if (Listener)
855 56: Listener->ReadHeaderFileInfo(HFI);
856 56: break;
857 : }
858 :
859 : case pch::SM_SLOC_FILE_ENTRY:
860 : case pch::SM_SLOC_BUFFER_ENTRY:
861 : case pch::SM_SLOC_INSTANTIATION_ENTRY:
862 : // Once we hit one of the source location entries, we're done.
863 48: return Success;
864 : }
865 48: }
866 : }
867 :
868 : /// \brief Read in the source location entry with the given ID.
869 141: PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {
0: branch 0 not taken
141: branch 1 taken
870 141: if (ID == 0)
871 0: return Success;
872 :
0: branch 0 not taken
141: branch 1 taken
873 141: if (ID > TotalNumSLocEntries) {
874 0: Error("source location entry ID out-of-range for PCH file");
875 0: return Failure;
876 : }
877 :
878 141: ++NumSLocEntriesRead;
879 141: SLocEntryCursor.JumpToBit(SLocOffsets[ID - 1]);
880 141: unsigned Code = SLocEntryCursor.ReadCode();
141: branch 0 taken
0: branch 1 not taken
141: branch 2 taken
0: branch 3 not taken
0: branch 4 not taken
141: branch 5 taken
881 141: if (Code == llvm::bitc::END_BLOCK ||
882 : Code == llvm::bitc::ENTER_SUBBLOCK ||
883 : Code == llvm::bitc::DEFINE_ABBREV) {
884 0: Error("incorrectly-formatted source location entry in PCH file");
885 0: return Failure;
886 : }
887 :
888 141: RecordData Record;
889 : const char *BlobStart;
890 : unsigned BlobLen;
0: branch 1 not taken
53: branch 2 taken
52: branch 3 taken
36: branch 4 taken
891 141: switch (SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
892 : default:
893 0: Error("incorrectly-formatted source location entry in PCH file");
894 0: return Failure;
895 :
896 : case pch::SM_SLOC_FILE_ENTRY: {
897 53: std::string Filename(BlobStart, BlobStart + BlobLen);
898 53: MaybeAddSystemRootToFilename(Filename);
899 53: const FileEntry *File = FileMgr.getFile(Filename);
1: branch 0 taken
52: branch 1 taken
900 53: if (File == 0) {
901 1: std::string ErrorStr = "could not find file '";
902 1: ErrorStr += Filename;
903 1: ErrorStr += "' referenced by PCH file";
904 1: Error(ErrorStr.c_str());
905 1: return Failure;
906 : }
907 :
908 : FileID FID = SourceMgr.createFileID(File,
909 : SourceLocation::getFromRawEncoding(Record[1]),
910 : (SrcMgr::CharacteristicKind)Record[2],
911 52: ID, Record[0]);
1: branch 1 taken
51: branch 2 taken
912 52: if (Record[3])
913 : const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())
914 1: .setHasLineDirectives();
915 :
1: branch 1 taken
52: branch 2 taken
916 53: break;
917 : }
918 :
919 : case pch::SM_SLOC_BUFFER_ENTRY: {
920 52: const char *Name = BlobStart;
921 52: unsigned Offset = Record[0];
922 52: unsigned Code = SLocEntryCursor.ReadCode();
923 52: Record.clear();
924 : unsigned RecCode
925 52: = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen);
0: branch 0 not taken
52: branch 1 taken
926 52: assert(RecCode == pch::SM_SLOC_BUFFER_BLOB && "Ill-formed PCH file");
927 : (void)RecCode;
928 : llvm::MemoryBuffer *Buffer
929 : = llvm::MemoryBuffer::getMemBuffer(BlobStart,
930 : BlobStart + BlobLen - 1,
931 52: Name);
932 52: FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID, Offset);
933 :
49: branch 1 taken
3: branch 2 taken
934 52: if (strcmp(Name, "<built-in>") == 0) {
935 49: PCHPredefinesBufferID = BufferID;
936 49: PCHPredefines = BlobStart;
937 49: PCHPredefinesLen = BlobLen - 1;
938 : }
939 :
940 52: break;
941 : }
942 :
943 : case pch::SM_SLOC_INSTANTIATION_ENTRY: {
944 : SourceLocation SpellingLoc
945 36: = SourceLocation::getFromRawEncoding(Record[1]);
946 : SourceMgr.createInstantiationLoc(SpellingLoc,
947 : SourceLocation::getFromRawEncoding(Record[2]),
948 : SourceLocation::getFromRawEncoding(Record[3]),
949 : Record[4],
950 : ID,
951 36: Record[0]);
952 : break;
953 : }
954 : }
955 :
956 140: return Success;
957 : }
958 :
959 : /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
960 : /// specified cursor. Read the abbreviations that are at the top of the block
961 : /// and then leave the cursor pointing into the block.
962 : bool PCHReader::ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
963 47: unsigned BlockID) {
0: branch 1 not taken
47: branch 2 taken
964 47: if (Cursor.EnterSubBlock(BlockID)) {
965 0: Error("malformed block record in PCH file");
966 0: return Failure;
967 : }
968 :
969 47: while (true) {
970 94: unsigned Code = Cursor.ReadCode();
971 :
972 : // We expect all abbrevs to be at the start of the block.
47: branch 0 taken
47: branch 1 taken
973 94: if (Code != llvm::bitc::DEFINE_ABBREV)
974 47: return false;
975 47: Cursor.ReadAbbrevRecord();
976 : }
977 : }
978 :
979 324: void PCHReader::ReadMacroRecord(uint64_t Offset) {
0: branch 0 not taken
324: branch 1 taken
980 324: assert(PP && "Forgot to set Preprocessor ?");
981 :
982 : // Keep track of where we are in the stream, then jump back there
983 : // after reading this macro.
984 324: SavedStreamPosition SavedPosition(Stream);
985 :
986 324: Stream.JumpToBit(Offset);
987 324: RecordData Record;
988 324: llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
989 324: MacroInfo *Macro = 0;
990 :
991 732: while (true) {
992 1056: unsigned Code = Stream.ReadCode();
3: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
1053: branch 3 taken
993 1056: switch (Code) {
994 : case llvm::bitc::END_BLOCK:
995 : return;
996 :
997 : case llvm::bitc::ENTER_SUBBLOCK:
998 : // No known subblocks, always skip them.
999 0: Stream.ReadSubBlockID();
0: branch 1 not taken
0: branch 2 not taken
1000 0: if (Stream.SkipBlock()) {
1001 0: Error("malformed block record in PCH file");
1002 : return;
1003 : }
1004 0: continue;
1005 :
1006 : case llvm::bitc::DEFINE_ABBREV:
1007 0: Stream.ReadAbbrevRecord();
1008 0: continue;
1009 : default: break;
1010 : }
1011 :
1012 : // Read a record.
1013 1053: Record.clear();
1014 : pch::PreprocessorRecordTypes RecType =
1015 1053: (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record);
645: branch 0 taken
408: branch 1 taken
0: branch 2 not taken
1016 1053: switch (RecType) {
1017 : case pch::PP_MACRO_OBJECT_LIKE:
1018 : case pch::PP_MACRO_FUNCTION_LIKE: {
1019 : // If we already have a macro, that means that we've hit the end
1020 : // of the definition of the macro we were looking for. We're
1021 : // done.
324: branch 0 taken
321: branch 1 taken
1022 645: if (Macro)
1023 : return;
1024 :
1025 324: IdentifierInfo *II = DecodeIdentifierInfo(Record[0]);
0: branch 0 not taken
324: branch 1 taken
1026 324: if (II == 0) {
1027 0: Error("macro must have a name in PCH file");
1028 : return;
1029 : }
1030 324: SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]);
1031 324: bool isUsed = Record[2];
1032 :
1033 324: MacroInfo *MI = PP->AllocateMacroInfo(Loc);
1034 324: MI->setIsUsed(isUsed);
1035 :
10: branch 0 taken
314: branch 1 taken
1036 324: if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {
1037 : // Decode function-like macro info.
1038 10: bool isC99VarArgs = Record[3];
1039 10: bool isGNUVarArgs = Record[4];
1040 10: MacroArgs.clear();
1041 10: unsigned NumArgs = Record[5];
15: branch 0 taken
10: branch 1 taken
1042 25: for (unsigned i = 0; i != NumArgs; ++i)
1043 15: MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i]));
1044 :
1045 : // Install function-like macro info.
1046 10: MI->setIsFunctionLike();
2: branch 0 taken
8: branch 1 taken
1047 10: if (isC99VarArgs) MI->setIsC99Varargs();
0: branch 0 not taken
10: branch 1 taken
1048 10: if (isGNUVarArgs) MI->setIsGNUVarargs();
1049 : MI->setArgumentList(MacroArgs.data(), MacroArgs.size(),
1050 10: PP->getPreprocessorAllocator());
1051 : }
1052 :
1053 : // Finally, install the macro.
1054 324: PP->setMacroInfo(II, MI);
1055 :
1056 : // Remember that we saw this macro last so that we add the tokens that
1057 : // form its body to it.
1058 324: Macro = MI;
1059 324: ++NumMacrosRead;
1060 324: break;
1061 : }
1062 :
1063 : case pch::PP_TOKEN: {
1064 : // If we see a TOKEN before a PP_MACRO_*, then the file is
1065 : // erroneous, just pretend we didn't see this.
408: branch 0 taken
0: branch 1 not taken
1066 408: if (Macro == 0) break;
1067 :
1068 408: Token Tok;
1069 408: Tok.startToken();
1070 408: Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0]));
1071 408: Tok.setLength(Record[1]);
77: branch 2 taken
331: branch 3 taken
1072 408: if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2]))
1073 77: Tok.setIdentifierInfo(II);
1074 408: Tok.setKind((tok::TokenKind)Record[3]);
1075 408: Tok.setFlag((Token::TokenFlags)Record[4]);
1076 408: Macro->AddTokenToBody(Tok);
1077 : break;
1078 : }
1079 : }
1080 324: }
1081 : }
1082 :
1083 3: void PCHReader::ReadDefinedMacros() {
1084 : // If there was no preprocessor block, do nothing.
0: branch 1 not taken
3: branch 2 taken
1085 3: if (!MacroCursor.getBitStreamReader())
1086 0: return;
1087 :
1088 3: llvm::BitstreamCursor Cursor = MacroCursor;
0: branch 1 not taken
3: branch 2 taken
1089 3: if (Cursor.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID)) {
1090 0: Error("malformed preprocessor block record in PCH file");
1091 : return;
1092 : }
1093 :
1094 3: RecordData Record;
1095 701: while (true) {
1096 704: unsigned Code = Cursor.ReadCode();
3: branch 0 taken
701: branch 1 taken
1097 704: if (Code == llvm::bitc::END_BLOCK) {
0: branch 1 not taken
3: branch 2 taken
1098 3: if (Cursor.ReadBlockEnd())
1099 0: Error("error at end of preprocessor block in PCH file");
1100 : return;
1101 : }
1102 :
0: branch 0 not taken
701: branch 1 taken
1103 701: if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1104 : // No known subblocks, always skip them.
1105 0: Cursor.ReadSubBlockID();
0: branch 1 not taken
0: branch 2 not taken
1106 0: if (Cursor.SkipBlock()) {
1107 0: Error("malformed block record in PCH file");
1108 : return;
1109 : }
1110 0: continue;
1111 : }
1112 :
0: branch 0 not taken
701: branch 1 taken
1113 701: if (Code == llvm::bitc::DEFINE_ABBREV) {
1114 0: Cursor.ReadAbbrevRecord();
1115 0: continue;
1116 : }
1117 :
1118 : // Read a record.
1119 : const char *BlobStart;
1120 : unsigned BlobLen;
1121 701: Record.clear();
0: branch 1 not taken
315: branch 2 taken
386: branch 3 taken
1122 701: switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
1123 : default: // Default behavior: ignore.
1124 0: break;
1125 :
1126 : case pch::PP_MACRO_OBJECT_LIKE:
1127 : case pch::PP_MACRO_FUNCTION_LIKE:
1128 315: DecodeIdentifierInfo(Record[0]);
1129 : break;
1130 :
1131 : case pch::PP_TOKEN:
1132 : // Ignore tokens.
1133 : break;
1134 : }
1135 3: }
1136 : }
1137 :
1138 : /// \brief If we are loading a relocatable PCH file, and the filename is
1139 : /// not an absolute path, add the system root to the beginning of the file
1140 : /// name.
1141 198: void PCHReader::MaybeAddSystemRootToFilename(std::string &Filename) {
1142 : // If this is not a relocatable PCH file, there's nothing to do.
188: branch 0 taken
10: branch 1 taken
1143 198: if (!RelocatablePCH)
1144 188: return;
1145 :
10: branch 1 taken
0: branch 2 not taken
1: branch 6 taken
9: branch 7 taken
10: branch 8 taken
0: branch 9 not taken
1: branch 11 taken
9: branch 12 taken
1146 10: if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
1147 1: return;
1148 :
0: branch 0 not taken
9: branch 1 taken
1149 9: if (isysroot == 0) {
1150 : // If no system root was given, default to '/'
1151 0: Filename.insert(Filename.begin(), '/');
1152 0: return;
1153 : }
1154 :
1155 9: unsigned Length = strlen(isysroot);
5: branch 0 taken
4: branch 1 taken
1156 9: if (isysroot[Length - 1] != '/')
1157 5: Filename.insert(Filename.begin(), '/');
1158 :
1159 9: Filename.insert(Filename.begin(), isysroot, isysroot + Length);
1160 : }
1161 :
1162 : PCHReader::PCHReadResult
1163 48: PCHReader::ReadPCHBlock() {
0: branch 1 not taken
48: branch 2 taken
1164 48: if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
1165 0: Error("malformed block record in PCH file");
1166 0: return Failure;
1167 : }
1168 :
1169 : // Read all of the records and blocks for the PCH file.
1170 48: RecordData Record;
1378: branch 1 taken
0: branch 2 not taken
1171 48: while (!Stream.AtEndOfStream()) {
1172 1378: unsigned Code = Stream.ReadCode();
47: branch 0 taken
1331: branch 1 taken
1173 1378: if (Code == llvm::bitc::END_BLOCK) {
0: branch 1 not taken
47: branch 2 taken
1174 47: if (Stream.ReadBlockEnd()) {
1175 0: Error("error at end of module block in PCH file");
1176 0: return Failure;
1177 : }
1178 :
1179 47: return Success;
1180 : }
1181 :
142: branch 0 taken
1189: branch 1 taken
1182 1331: if (Code == llvm::bitc::ENTER_SUBBLOCK) {
47: branch 1 taken
47: branch 2 taken
48: branch 3 taken
0: branch 4 not taken
1183 142: switch (Stream.ReadSubBlockID()) {
1184 : case pch::DECLTYPES_BLOCK_ID:
1185 : // We lazily load the decls block, but we want to set up the
1186 : // DeclsCursor cursor to point into it. Clone our current bitcode
1187 : // cursor to it, enter the block and read the abbrevs in that block.
1188 : // With the main cursor, we just skip over it.
1189 47: DeclsCursor = Stream;
47: branch 1 taken
0: branch 2 not taken
0: branch 4 not taken
47: branch 5 taken
0: branch 6 not taken
47: branch 7 taken
1190 47: if (Stream.SkipBlock() || // Skip with the main cursor.
1191 : // Read the abbrevs.
1192 : ReadBlockAbbrevs(DeclsCursor, pch::DECLTYPES_BLOCK_ID)) {
1193 0: Error("malformed block record in PCH file");
1194 0: return Failure;
1195 : }
1196 47: break;
1197 :
1198 : case pch::PREPROCESSOR_BLOCK_ID:
1199 47: MacroCursor = Stream;
34: branch 0 taken
13: branch 1 taken
1200 47: if (PP)
1201 34: PP->setExternalSource(this);
1202 :
0: branch 1 not taken
47: branch 2 taken
1203 47: if (Stream.SkipBlock()) {
1204 0: Error("malformed block record in PCH file");
1205 0: return Failure;
1206 : }
1207 47: break;
1208 :
1209 : case pch::SOURCE_MANAGER_BLOCK_ID:
48: branch 1 taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
1210 48: switch (ReadSourceManagerBlock()) {
1211 : case Success:
1212 48: break;
1213 :
1214 : case Failure:
1215 0: Error("malformed source manager block in PCH file");
1216 0: return Failure;
1217 :
1218 : case IgnorePCH:
1219 0: return IgnorePCH;
1220 : }
1221 : break;
1222 : }
1223 142: continue;
1224 : }
1225 :
477: branch 0 taken
712: branch 1 taken
1226 1189: if (Code == llvm::bitc::DEFINE_ABBREV) {
1227 477: Stream.ReadAbbrevRecord();
1228 477: continue;
1229 : }
1230 :
1231 : // Read and process a record.
1232 712: Record.clear();
1233 712: const char *BlobStart = 0;
1234 712: unsigned BlobLen = 0;
0: branch 1 not taken
47: branch 2 taken
47: branch 3 taken
48: branch 4 taken
48: branch 5 taken
47: branch 6 taken
47: branch 7 taken
23: branch 8 taken
47: branch 9 taken
47: branch 10 taken
13: branch 11 taken
2: branch 12 taken
6: branch 13 taken
6: branch 14 taken
4: branch 15 taken
48: branch 16 taken
48: branch 17 taken
46: branch 18 taken
3: branch 19 taken
48: branch 20 taken
39: branch 21 taken
48: branch 22 taken
1235 712: switch ((pch::PCHRecordTypes)Stream.ReadRecord(Code, Record,
1236 : &BlobStart, &BlobLen)) {
1237 : default: // Default behavior: ignore.
1238 0: break;
1239 :
1240 : case pch::TYPE_OFFSET:
0: branch 1 not taken
47: branch 2 taken
1241 47: if (!TypesLoaded.empty()) {
1242 0: Error("duplicate TYPE_OFFSET record in PCH file");
1243 0: return Failure;
1244 : }
1245 47: TypeOffsets = (const uint32_t *)BlobStart;
1246 47: TypesLoaded.resize(Record[0]);
1247 47: break;
1248 :
1249 : case pch::DECL_OFFSET:
0: branch 1 not taken
47: branch 2 taken
1250 47: if (!DeclsLoaded.empty()) {
1251 0: Error("duplicate DECL_OFFSET record in PCH file");
1252 0: return Failure;
1253 : }
1254 47: DeclOffsets = (const uint32_t *)BlobStart;
1255 47: DeclsLoaded.resize(Record[0]);
1256 47: break;
1257 :
1258 : case pch::LANGUAGE_OPTIONS:
0: branch 1 not taken
48: branch 2 taken
1259 48: if (ParseLanguageOptions(Record))
1260 0: return IgnorePCH;
1261 48: break;
1262 :
1263 : case pch::METADATA: {
0: branch 1 not taken
48: branch 2 taken
1264 48: if (Record[0] != pch::VERSION_MAJOR) {
1265 : Diag(Record[0] < pch::VERSION_MAJOR? diag::warn_pch_version_too_old
0: branch 1 not taken
0: branch 2 not taken
1266 0: : diag::warn_pch_version_too_new);
1267 0: return IgnorePCH;
1268 : }
1269 :
1270 48: RelocatablePCH = Record[4];
48: branch 1 taken
0: branch 2 not taken
1271 48: if (Listener) {
1272 48: std::string TargetTriple(BlobStart, BlobLen);
0: branch 3 not taken
48: branch 4 taken
1273 48: if (Listener->ReadTargetTriple(TargetTriple))
48: branch 1 taken
0: branch 2 not taken
1274 0: return IgnorePCH;
1275 : }
1276 48: break;
1277 : }
1278 :
1279 : case pch::IDENTIFIER_TABLE:
1280 47: IdentifierTableData = BlobStart;
47: branch 1 taken
0: branch 2 not taken
1281 47: if (Record[0]) {
1282 : IdentifierLookupTable
1283 : = PCHIdentifierLookupTable::Create(
1284 : (const unsigned char *)IdentifierTableData + Record[0],
1285 : (const unsigned char *)IdentifierTableData,
1286 47: PCHIdentifierLookupTrait(*this));
34: branch 0 taken
13: branch 1 taken
1287 47: if (PP)
1288 34: PP->getIdentifierTable().setExternalIdentifierLookup(this);
1289 : }
1290 47: break;
1291 :
1292 : case pch::IDENTIFIER_OFFSET:
0: branch 1 not taken
47: branch 2 taken
1293 47: if (!IdentifiersLoaded.empty()) {
1294 0: Error("duplicate IDENTIFIER_OFFSET record in PCH file");
1295 0: return Failure;
1296 : }
1297 47: IdentifierOffsets = (const uint32_t *)BlobStart;
1298 47: IdentifiersLoaded.resize(Record[0]);
34: branch 0 taken
13: branch 1 taken
1299 47: if (PP)
1300 34: PP->getHeaderSearchInfo().SetExternalLookup(this);
1301 47: break;
1302 :
1303 : case pch::EXTERNAL_DEFINITIONS:
0: branch 1 not taken
23: branch 2 taken
1304 23: if (!ExternalDefinitions.empty()) {
1305 0: Error("duplicate EXTERNAL_DEFINITIONS record in PCH file");
1306 0: return Failure;
1307 : }
1308 23: ExternalDefinitions.swap(Record);
1309 23: break;
1310 :
1311 : case pch::SPECIAL_TYPES:
1312 47: SpecialTypes.swap(Record);
1313 47: break;
1314 :
1315 : case pch::STATISTICS:
1316 47: TotalNumStatements = Record[0];
1317 47: TotalNumMacros = Record[1];
1318 47: TotalLexicalDeclContexts = Record[2];
1319 47: TotalVisibleDeclContexts = Record[3];
1320 47: break;
1321 :
1322 : case pch::TENTATIVE_DEFINITIONS:
0: branch 1 not taken
13: branch 2 taken
1323 13: if (!TentativeDefinitions.empty()) {
1324 0: Error("duplicate TENTATIVE_DEFINITIONS record in PCH file");
1325 0: return Failure;
1326 : }
1327 13: TentativeDefinitions.swap(Record);
1328 13: break;
1329 :
1330 : case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
0: branch 1 not taken
2: branch 2 taken
1331 2: if (!LocallyScopedExternalDecls.empty()) {
1332 0: Error("duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
1333 0: return Failure;
1334 : }
1335 2: LocallyScopedExternalDecls.swap(Record);
1336 2: break;
1337 :
1338 : case pch::SELECTOR_OFFSETS:
1339 6: SelectorOffsets = (const uint32_t *)BlobStart;
1340 6: TotalNumSelectors = Record[0];
1341 6: SelectorsLoaded.resize(TotalNumSelectors);
1342 6: break;
1343 :
1344 : case pch::METHOD_POOL:
1345 6: MethodPoolLookupTableData = (const unsigned char *)BlobStart;
6: branch 1 taken
0: branch 2 not taken
1346 6: if (Record[0])
1347 : MethodPoolLookupTable
1348 : = PCHMethodPoolLookupTable::Create(
1349 : MethodPoolLookupTableData + Record[0],
1350 : MethodPoolLookupTableData,
1351 6: PCHMethodPoolLookupTrait(*this));
1352 6: TotalSelectorsInMethodPool = Record[1];
1353 6: break;
1354 :
1355 : case pch::PP_COUNTER_VALUE:
4: branch 1 taken
0: branch 2 not taken
4: branch 4 taken
0: branch 5 not taken
4: branch 6 taken
0: branch 7 not taken
1356 4: if (!Record.empty() && Listener)
1357 4: Listener->ReadCounter(Record[0]);
1358 4: break;
1359 :
1360 : case pch::SOURCE_LOCATION_OFFSETS:
1361 48: SLocOffsets = (const uint32_t *)BlobStart;
1362 48: TotalNumSLocEntries = Record[0];
1363 48: SourceMgr.PreallocateSLocEntries(this, TotalNumSLocEntries, Record[1]);
1364 48: break;
1365 :
1366 : case pch::SOURCE_LOCATION_PRELOADS:
102: branch 1 taken
47: branch 2 taken
1367 149: for (unsigned I = 0, N = Record.size(); I != N; ++I) {
1368 102: PCHReadResult Result = ReadSLocEntryRecord(Record[I]);
1: branch 0 taken
101: branch 1 taken
1369 102: if (Result != Success)
1370 1: return Result;
1371 : }
1372 47: break;
1373 :
1374 : case pch::STAT_CACHE: {
1375 : PCHStatCache *MyStatCache =
1376 : new PCHStatCache((const unsigned char *)BlobStart + Record[0],
1377 : (const unsigned char *)BlobStart,
1378 46: NumStatHits, NumStatMisses);
1379 46: FileMgr.addStatCache(MyStatCache);
1380 46: StatCache = MyStatCache;
1381 46: break;
1382 : }
1383 :
1384 : case pch::EXT_VECTOR_DECLS:
0: branch 1 not taken
3: branch 2 taken
1385 3: if (!ExtVectorDecls.empty()) {
1386 0: Error("duplicate EXT_VECTOR_DECLS record in PCH file");
1387 0: return Failure;
1388 : }
1389 3: ExtVectorDecls.swap(Record);
1390 3: break;
1391 :
1392 : case pch::ORIGINAL_FILE_NAME:
1393 48: ActualOriginalFileName.assign(BlobStart, BlobLen);
1394 48: OriginalFileName = ActualOriginalFileName;
1395 48: MaybeAddSystemRootToFilename(OriginalFileName);
1396 48: break;
1397 :
1398 : case pch::COMMENT_RANGES:
1399 39: Comments = (SourceRange *)BlobStart;
1400 39: NumComments = BlobLen / sizeof(SourceRange);
1401 39: break;
1402 :
1403 : case pch::VERSION_CONTROL_BRANCH_REVISION: {
1404 48: llvm::StringRef CurBranch = getClangFullRepositoryVersion();
1405 48: llvm::StringRef PCHBranch(BlobStart, BlobLen);
0: branch 1 not taken
48: branch 2 taken
1406 48: if (CurBranch != PCHBranch) {
1407 0: Diag(diag::warn_pch_different_branch) << PCHBranch << CurBranch;
1408 0: return IgnorePCH;
1409 : }
1410 : break;
1411 : }
1412 : }
1413 : }
1414 0: Error("premature end of bitstream in PCH file");
1415 0: return Failure;
1416 : }
1417 :
1418 48: PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
1419 : // Set the PCH file name.
1420 48: this->FileName = FileName;
1421 :
1422 : // Open the PCH file.
1423 : //
1424 : // FIXME: This shouldn't be here, we should just take a raw_ostream.
1425 48: std::string ErrStr;
1426 48: Buffer.reset(llvm::MemoryBuffer::getFileOrSTDIN(FileName, &ErrStr));
0: branch 1 not taken
48: branch 2 taken
1427 48: if (!Buffer) {
1428 0: Error(ErrStr.c_str());
1429 0: return IgnorePCH;
1430 : }
1431 :
1432 : // Initialize the stream
1433 : StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
1434 48: (const unsigned char *)Buffer->getBufferEnd());
1435 48: Stream.init(StreamFile);
1436 :
1437 : // Sniff for the signature.
48: branch 1 taken
0: branch 2 not taken
48: branch 4 taken
0: branch 5 not taken
48: branch 7 taken
0: branch 8 not taken
0: branch 10 not taken
48: branch 11 taken
0: branch 12 not taken
48: branch 13 taken
1438 48: if (Stream.Read(8) != 'C' ||
1439 : Stream.Read(8) != 'P' ||
1440 : Stream.Read(8) != 'C' ||
1441 : Stream.Read(8) != 'H') {
1442 0: Diag(diag::err_not_a_pch_file) << FileName;
1443 0: return Failure;
1444 : }
1445 :
96: branch 1 taken
47: branch 2 taken
1446 191: while (!Stream.AtEndOfStream()) {
1447 96: unsigned Code = Stream.ReadCode();
1448 :
0: branch 0 not taken
96: branch 1 taken
1449 96: if (Code != llvm::bitc::ENTER_SUBBLOCK) {
1450 0: Error("invalid record at top-level of PCH file");
1451 0: return Failure;
1452 : }
1453 :
1454 96: unsigned BlockID = Stream.ReadSubBlockID();
1455 :
1456 : // We only know the PCH subblock ID.
48: branch 0 taken
48: branch 1 taken
0: branch 2 not taken
1457 96: switch (BlockID) {
1458 : case llvm::bitc::BLOCKINFO_BLOCK_ID:
0: branch 1 not taken
48: branch 2 taken
1459 48: if (Stream.ReadBlockInfoBlock()) {
1460 0: Error("malformed BlockInfoBlock in PCH file");
1461 0: return Failure;
1462 : }
1463 48: break;
1464 : case pch::PCH_BLOCK_ID:
47: branch 1 taken
1: branch 2 taken
0: branch 3 not taken
0: branch 4 not taken
1465 48: switch (ReadPCHBlock()) {
1466 : case Success:
1467 47: break;
1468 :
1469 : case Failure:
1470 1: return Failure;
1471 :
1472 : case IgnorePCH:
1473 : // FIXME: We could consider reading through to the end of this
1474 : // PCH block, skipping subblocks, to see if there are other
1475 : // PCH blocks elsewhere.
1476 :
1477 : // Clear out any preallocated source location entries, so that
1478 : // the source manager does not try to resolve them later.
1479 0: SourceMgr.ClearPreallocatedSLocEntries();
1480 :
1481 : // Remove the stat cache.
0: branch 0 not taken
0: branch 1 not taken
1482 0: if (StatCache)
1483 0: FileMgr.removeStatCache((PCHStatCache*)StatCache);
1484 :
1485 0: return IgnorePCH;
1486 : }
1487 47: break;
1488 : default:
0: branch 1 not taken
0: branch 2 not taken
1489 0: if (Stream.SkipBlock()) {
1490 0: Error("malformed block record in PCH file");
1491 0: return Failure;
1492 : }
1493 : break;
1494 : }
1495 : }
1496 :
1497 : // Check the predefines buffer.
1: branch 2 taken
46: branch 3 taken
1498 47: if (CheckPredefinesBuffer(llvm::StringRef(PCHPredefines, PCHPredefinesLen),
1499 : PCHPredefinesBufferID))
1500 1: return IgnorePCH;
1501 :
33: branch 0 taken
13: branch 1 taken
1502 46: if (PP) {
1503 : // Initialization of keywords and pragmas occurs before the
1504 : // PCH file is read, so there may be some identifiers that were
1505 : // loaded into the IdentifierTable before we intercepted the
1506 : // creation of identifiers. Iterate through the list of known
1507 : // identifiers and determine whether we have to establish
1508 : // preprocessor definitions or top-level identifier declaration
1509 : // chains for those identifiers.
1510 : //
1511 : // We copy the IdentifierInfo pointers to a small vector first,
1512 : // since de-serializing declarations or macro definitions can add
1513 : // new entries into the identifier table, invalidating the
1514 : // iterators.
1515 33: llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
3843: branch 4 taken
33: branch 5 taken
1516 3909: for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
1517 33: IdEnd = PP->getIdentifierTable().end();
1518 : Id != IdEnd; ++Id)
1519 3843: Identifiers.push_back(Id->second);
1520 : PCHIdentifierLookupTable *IdTable
1521 33: = (PCHIdentifierLookupTable *)IdentifierLookupTable;
3843: branch 1 taken
33: branch 2 taken
1522 3876: for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
1523 3843: IdentifierInfo *II = Identifiers[I];
1524 : // Look in the on-disk hash table for an entry for
1525 3843: PCHIdentifierLookupTrait Info(*this, II);
1526 3843: std::pair<const char*, unsigned> Key(II->getNameStart(), II->getLength());
1527 3843: PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
0: branch 2 not taken
3843: branch 3 taken
1528 3843: if (Pos == IdTable->end())
1529 0: continue;
1530 :
1531 : // Dereferencing the iterator has the effect of populating the
1532 : // IdentifierInfo node with the various declarations it needs.
1533 3843: (void)*Pos;
1534 33: }
1535 : }
1536 :
33: branch 0 taken
13: branch 1 taken
1537 46: if (Context)
1538 33: InitializeContext(*Context);
1539 :
1540 46: return Success;
1541 : }
1542 :
1543 46: void PCHReader::InitializeContext(ASTContext &Ctx) {
1544 46: Context = &Ctx;
0: branch 0 not taken
46: branch 1 taken
1545 46: assert(Context && "Passed null context!");
1546 :
0: branch 0 not taken
46: branch 1 taken
1547 46: assert(PP && "Forgot to set Preprocessor ?");
1548 46: PP->getIdentifierTable().setExternalIdentifierLookup(this);
1549 46: PP->getHeaderSearchInfo().SetExternalLookup(this);
1550 46: PP->setExternalSource(this);
1551 :
1552 : // Load the translation unit declaration
1553 46: ReadDeclRecord(DeclOffsets[0], 0);
1554 :
1555 : // Load the special types.
1556 : Context->setBuiltinVaListType(
1557 46: GetType(SpecialTypes[pch::SPECIAL_TYPE_BUILTIN_VA_LIST]));
12: branch 1 taken
34: branch 2 taken
1558 46: if (unsigned Id = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID])
1559 12: Context->setObjCIdType(GetType(Id));
12: branch 1 taken
34: branch 2 taken
1560 46: if (unsigned Sel = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SELECTOR])
1561 12: Context->setObjCSelType(GetType(Sel));
12: branch 1 taken
34: branch 2 taken
1562 46: if (unsigned Proto = SpecialTypes[pch::SPECIAL_TYPE_OBJC_PROTOCOL])
1563 12: Context->setObjCProtoType(GetType(Proto));
12: branch 1 taken
34: branch 2 taken
1564 46: if (unsigned Class = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS])
1565 12: Context->setObjCClassType(GetType(Class));
1566 :
0: branch 1 not taken
46: branch 2 taken
1567 46: if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_CF_CONSTANT_STRING])
1568 0: Context->setCFConstantStringType(GetType(String));
0: branch 0 not taken
46: branch 1 taken
1569 46: if (unsigned FastEnum
1570 46: = SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
1571 0: Context->setObjCFastEnumerationStateType(GetType(FastEnum));
1: branch 1 taken
45: branch 2 taken
1572 46: if (unsigned File = SpecialTypes[pch::SPECIAL_TYPE_FILE]) {
1573 1: QualType FileType = GetType(File);
1: branch 1 taken
0: branch 2 not taken
1574 1: assert(!FileType.isNull() && "FILE type is NULL");
1: branch 2 taken
0: branch 3 not taken
1575 1: if (const TypedefType *Typedef = FileType->getAs<TypedefType>())
1576 1: Context->setFILEDecl(Typedef->getDecl());
1577 : else {
1578 0: const TagType *Tag = FileType->getAs<TagType>();
0: branch 0 not taken
0: branch 1 not taken
1579 0: assert(Tag && "Invalid FILE type in PCH file");
1580 0: Context->setFILEDecl(Tag->getDecl());
1581 : }
1582 : }
0: branch 1 not taken
46: branch 2 taken
1583 46: if (unsigned Jmp_buf = SpecialTypes[pch::SPECIAL_TYPE_jmp_buf]) {
1584 0: QualType Jmp_bufType = GetType(Jmp_buf);
0: branch 1 not taken
0: branch 2 not taken
1585 0: assert(!Jmp_bufType.isNull() && "jmp_bug type is NULL");
0: branch 2 not taken
0: branch 3 not taken
1586 0: if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())
1587 0: Context->setjmp_bufDecl(Typedef->getDecl());
1588 : else {
1589 0: const TagType *Tag = Jmp_bufType->getAs<TagType>();
0: branch 0 not taken
0: branch 1 not taken
1590 0: assert(Tag && "Invalid jmp_bug type in PCH file");
1591 0: Context->setjmp_bufDecl(Tag->getDecl());
1592 : }
1593 : }
0: branch 1 not taken
46: branch 2 taken
1594 46: if (unsigned Sigjmp_buf = SpecialTypes[pch::SPECIAL_TYPE_sigjmp_buf]) {
1595 0: QualType Sigjmp_bufType = GetType(Sigjmp_buf);
0: branch 1 not taken
0: branch 2 not taken
1596 0: assert(!Sigjmp_bufType.isNull() && "sigjmp_buf type is NULL");
0: branch 2 not taken
0: branch 3 not taken
1597 0: if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())
1598 0: Context->setsigjmp_bufDecl(Typedef->getDecl());
1599 : else {
1600 0: const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
0: branch 0 not taken
0: branch 1 not taken
1601 0: assert(Tag && "Invalid sigjmp_buf type in PCH file");
1602 0: Context->setsigjmp_bufDecl(Tag->getDecl());
1603 : }
1604 : }
12: branch 0 taken
34: branch 1 taken
1605 46: if (unsigned ObjCIdRedef
1606 46: = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID_REDEFINITION])
1607 12: Context->ObjCIdRedefinitionType = GetType(ObjCIdRedef);
12: branch 0 taken
34: branch 1 taken
1608 46: if (unsigned ObjCClassRedef
1609 46: = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
1610 12: Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
1611 : #if 0
1612 : // FIXME. Accommodate for this in several PCH/Index tests
1613 : if (unsigned ObjCSelRedef
1614 : = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
1615 : Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
1616 : #endif
0: branch 1 not taken
46: branch 2 taken
1617 46: if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_DESCRIPTOR])
1618 0: Context->setBlockDescriptorType(GetType(String));
0: branch 0 not taken
46: branch 1 taken
1619 46: if (unsigned String
1620 46: = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
1621 0: Context->setBlockDescriptorExtendedType(GetType(String));
1622 46: }
1623 :
1624 : /// \brief Retrieve the name of the original source file name
1625 : /// directly from the PCH file, without actually loading the PCH
1626 : /// file.
1627 : std::string PCHReader::getOriginalSourceFile(const std::string &PCHFileName,
1628 36: Diagnostic &Diags) {
1629 : // Open the PCH file.
1630 36: std::string ErrStr;
1631 36: llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
1632 36: Buffer.reset(llvm::MemoryBuffer::getFile(PCHFileName.c_str(), &ErrStr));
0: branch 1 not taken
36: branch 2 taken
1633 36: if (!Buffer) {
1634 0: Diags.Report(diag::err_fe_unable_to_read_pch_file) << ErrStr;
1635 0: return std::string();
1636 : }
1637 :
1638 : // Initialize the stream
1639 36: llvm::BitstreamReader StreamFile;
1640 36: llvm::BitstreamCursor Stream;
1641 : StreamFile.init((const unsigned char *)Buffer->getBufferStart(),
1642 36: (const unsigned char *)Buffer->getBufferEnd());
1643 36: Stream.init(StreamFile);
1644 :
1645 : // Sniff for the signature.
36: branch 1 taken
0: branch 2 not taken
36: branch 4 taken
0: branch 5 not taken
36: branch 7 taken
0: branch 8 not taken
0: branch 10 not taken
36: branch 11 taken
0: branch 12 not taken
36: branch 13 taken
1646 36: if (Stream.Read(8) != 'C' ||
1647 : Stream.Read(8) != 'P' ||
1648 : Stream.Read(8) != 'C' ||
1649 : Stream.Read(8) != 'H') {
1650 0: Diags.Report(diag::err_fe_not_a_pch_file) << PCHFileName;
1651 0: return std::string();
1652 : }
1653 :
1654 36: RecordData Record;
216: branch 1 taken
0: branch 2 not taken
1655 36: while (!Stream.AtEndOfStream()) {
1656 216: unsigned Code = Stream.ReadCode();
1657 :
72: branch 0 taken
144: branch 1 taken
1658 216: if (Code == llvm::bitc::ENTER_SUBBLOCK) {
1659 72: unsigned BlockID = Stream.ReadSubBlockID();
1660 :
1661 : // We only know the PCH subblock ID.
36: branch 0 taken
36: branch 1 taken
1662 72: switch (BlockID) {
1663 : case pch::PCH_BLOCK_ID:
0: branch 1 not taken
36: branch 2 taken
1664 36: if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) {
1665 0: Diags.Report(diag::err_fe_pch_malformed_block) << PCHFileName;
1666 0: return std::string();
1667 : }
1668 36: break;
1669 :
1670 : default:
0: branch 1 not taken
36: branch 2 taken
1671 36: if (Stream.SkipBlock()) {
1672 0: Diags.Report(diag::err_fe_pch_malformed_block) << PCHFileName;
1673 0: return std::string();
1674 : }
1675 : break;
1676 : }
1677 72: continue;
1678 : }
1679 :
0: branch 0 not taken
144: branch 1 taken
1680 144: if (Code == llvm::bitc::END_BLOCK) {
0: branch 1 not taken
0: branch 2 not taken
1681 0: if (Stream.ReadBlockEnd()) {
1682 0: Diags.Report(diag::err_fe_pch_error_at_end_block) << PCHFileName;
1683 0: return std::string();
1684 : }
1685 0: continue;
1686 : }
1687 :
72: branch 0 taken
72: branch 1 taken
1688 144: if (Code == llvm::bitc::DEFINE_ABBREV) {
1689 72: Stream.ReadAbbrevRecord();
1690 72: continue;
1691 : }
1692 :
1693 72: Record.clear();
1694 72: const char *BlobStart = 0;
1695 72: unsigned BlobLen = 0;
36: branch 1 taken
36: branch 2 taken
1696 72: if (Stream.ReadRecord(Code, Record, &BlobStart, &BlobLen)
1697 : == pch::ORIGINAL_FILE_NAME)
1698 36: return std::string(BlobStart, BlobLen);
1699 : }
1700 :
1701 0: return std::string();
1702 : }
1703 :
1704 : /// \brief Parse the record that corresponds to a LangOptions data
1705 : /// structure.
1706 : ///
1707 : /// This routine compares the language options used to generate the
1708 : /// PCH file against the language options set for the current
1709 : /// compilation. For each option, we classify differences between the
1710 : /// two compiler states as either "benign" or "important". Benign
1711 : /// differences don't matter, and we accept them without complaint
1712 : /// (and without modifying the language options). Differences between
1713 : /// the states for important options cause the PCH file to be
1714 : /// unusable, so we emit a warning and return true to indicate that
1715 : /// there was an error.
1716 : ///
1717 : /// \returns true if the PCH file is unacceptable, false otherwise.
1718 : bool PCHReader::ParseLanguageOptions(
1719 48: const llvm::SmallVectorImpl<uint64_t> &Record) {
48: branch 1 taken
0: branch 2 not taken
1720 48: if (Listener) {
1721 48: LangOptions LangOpts;
1722 :
1723 : #define PARSE_LANGOPT(Option) \
1724 : LangOpts.Option = Record[Idx]; \
1725 : ++Idx
1726 :
1727 48: unsigned Idx = 0;
1728 48: PARSE_LANGOPT(Trigraphs);
1729 48: PARSE_LANGOPT(BCPLComment);
1730 48: PARSE_LANGOPT(DollarIdents);
1731 48: PARSE_LANGOPT(AsmPreprocessor);
1732 48: PARSE_LANGOPT(GNUMode);
1733 48: PARSE_LANGOPT(ImplicitInt);
1734 48: PARSE_LANGOPT(Digraphs);
1735 48: PARSE_LANGOPT(HexFloats);
1736 48: PARSE_LANGOPT(C99);
1737 48: PARSE_LANGOPT(Microsoft);
1738 48: PARSE_LANGOPT(CPlusPlus);
1739 48: PARSE_LANGOPT(CPlusPlus0x);
1740 48: PARSE_LANGOPT(CXXOperatorNames);
1741 48: PARSE_LANGOPT(ObjC1);
1742 48: PARSE_LANGOPT(ObjC2);
1743 48: PARSE_LANGOPT(ObjCNonFragileABI);
1744 48: PARSE_LANGOPT(ObjCNonFragileABI2);
1745 48: PARSE_LANGOPT(PascalStrings);
1746 48: PARSE_LANGOPT(WritableStrings);
1747 48: PARSE_LANGOPT(LaxVectorConversions);
1748 48: PARSE_LANGOPT(AltiVec);
1749 48: PARSE_LANGOPT(Exceptions);
1750 48: PARSE_LANGOPT(NeXTRuntime);
1751 48: PARSE_LANGOPT(Freestanding);
1752 48: PARSE_LANGOPT(NoBuiltin);
1753 48: PARSE_LANGOPT(ThreadsafeStatics);
1754 48: PARSE_LANGOPT(POSIXThreads);
1755 48: PARSE_LANGOPT(Blocks);
1756 48: PARSE_LANGOPT(EmitAllDecls);
1757 48: PARSE_LANGOPT(MathErrno);
1758 48: PARSE_LANGOPT(OverflowChecking);
1759 48: PARSE_LANGOPT(HeinousExtensions);
1760 48: PARSE_LANGOPT(Optimize);
1761 48: PARSE_LANGOPT(OptimizeSize);
1762 48: PARSE_LANGOPT(Static);
1763 48: PARSE_LANGOPT(PICLevel);
1764 48: PARSE_LANGOPT(GNUInline);
1765 48: PARSE_LANGOPT(NoInline);
1766 48: PARSE_LANGOPT(AccessControl);
1767 48: PARSE_LANGOPT(CharIsSigned);
1768 48: PARSE_LANGOPT(ShortWChar);
1769 48: LangOpts.setGCMode((LangOptions::GCMode)Record[Idx]);
1770 48: ++Idx;
1771 48: LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx]);
1772 48: ++Idx;
1773 : LangOpts.setStackProtectorMode((LangOptions::StackProtectorMode)
1774 48: Record[Idx]);
1775 48: ++Idx;
1776 48: PARSE_LANGOPT(InstantiationDepth);
1777 48: PARSE_LANGOPT(OpenCL);
1778 48: PARSE_LANGOPT(CatchUndefined);
1779 : // FIXME: Missing ElideConstructors?!
1780 : #undef PARSE_LANGOPT
1781 :
1782 48: return Listener->ReadLanguageOptions(LangOpts);
1783 : }
1784 :
1785 0: return false;
1786 : }
1787 :
1788 0: void PCHReader::ReadComments(std::vector<SourceRange> &Comments) {
1789 0: Comments.resize(NumComments);
1790 : std::copy(this->Comments, this->Comments + NumComments,
1791 0: Comments.begin());
1792 0: }
1793 :
1794 : /// \brief Read and return the type at the given offset.
1795 : ///
1796 : /// This routine actually reads the record corresponding to the type
1797 : /// at the given offset in the bitstream. It is a helper routine for
1798 : /// GetType, which deals with reading type IDs.
1799 379: QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
1800 : // Keep track of where we are in the stream, then jump back there
1801 : // after reading this type.
1802 379: SavedStreamPosition SavedPosition(DeclsCursor);
1803 :
1804 : // Note that we are loading a type record.
1805 379: LoadingTypeOrDecl Loading(*this);
1806 :
1807 379: DeclsCursor.JumpToBit(Offset);
1808 379: RecordData Record;
1809 379: unsigned Code = DeclsCursor.ReadCode();
1: branch 1 taken
2: branch 2 taken
68: branch 3 taken
2: branch 4 taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
23: branch 8 taken
6: branch 9 taken
1: branch 10 taken
1: branch 11 taken
4: branch 12 taken
5: branch 13 taken
39: branch 14 taken
0: branch 15 not taken
88: branch 16 taken
36: branch 17 taken
4: branch 18 taken
0: branch 19 not taken
31: branch 20 taken
6: branch 21 taken
0: branch 22 not taken
22: branch 23 taken
40: branch 24 taken
0: branch 25 not taken
0: branch 26 not taken
1810 379: switch ((pch::TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
1811 : case pch::TYPE_EXT_QUAL: {
1812 : assert(Record.size() == 2 &&
1: branch 1 taken
0: branch 2 not taken
1813 1: "Incorrect encoding of extended qualifier type");
1814 1: QualType Base = GetType(Record[0]);
1815 1: Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);
1816 1: return Context->getQualifiedType(Base, Quals);
1817 : }
1818 :
1819 : case pch::TYPE_COMPLEX: {
2: branch 1 taken
0: branch 2 not taken
1820 2: assert(Record.size() == 1 && "Incorrect encoding of complex type");
1821 2: QualType ElemType = GetType(Record[0]);
1822 2: return Context->getComplexType(ElemType);
1823 : }
1824 :
1825 : case pch::TYPE_POINTER: {
68: branch 1 taken
0: branch 2 not taken
1826 68: assert(Record.size() == 1 && "Incorrect encoding of pointer type");
1827 68: QualType PointeeType = GetType(Record[0]);
1828 68: return Context->getPointerType(PointeeType);
1829 : }
1830 :
1831 : case pch::TYPE_BLOCK_POINTER: {
2: branch 1 taken
0: branch 2 not taken
1832 2: assert(Record.size() == 1 && "Incorrect encoding of block pointer type");
1833 2: QualType PointeeType = GetType(Record[0]);
1834 2: return Context->getBlockPointerType(PointeeType);
1835 : }
1836 :
1837 : case pch::TYPE_LVALUE_REFERENCE: {
0: branch 1 not taken
0: branch 2 not taken
1838 0: assert(Record.size() == 1 && "Incorrect encoding of lvalue reference type");
1839 0: QualType PointeeType = GetType(Record[0]);
1840 0: return Context->getLValueReferenceType(PointeeType);
1841 : }
1842 :
1843 : case pch::TYPE_RVALUE_REFERENCE: {
0: branch 1 not taken
0: branch 2 not taken
1844 0: assert(Record.size() == 1 && "Incorrect encoding of rvalue reference type");
1845 0: QualType PointeeType = GetType(Record[0]);
1846 0: return Context->getRValueReferenceType(PointeeType);
1847 : }
1848 :
1849 : case pch::TYPE_MEMBER_POINTER: {
0: branch 1 not taken
0: branch 2 not taken
1850 0: assert(Record.size() == 1 && "Incorrect encoding of member pointer type");
1851 0: QualType PointeeType = GetType(Record[0]);
1852 0: QualType ClassType = GetType(Record[1]);
1853 0: return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr());
1854 : }
1855 :
1856 : case pch::TYPE_CONSTANT_ARRAY: {
1857 23: QualType ElementType = GetType(Record[0]);
1858 23: ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1859 23: unsigned IndexTypeQuals = Record[2];
1860 23: unsigned Idx = 3;
1861 23: llvm::APInt Size = ReadAPInt(Record, Idx);
1862 : return Context->getConstantArrayType(ElementType, Size,
1863 23: ASM, IndexTypeQuals);
1864 : }
1865 :
1866 : case pch::TYPE_INCOMPLETE_ARRAY: {
1867 6: QualType ElementType = GetType(Record[0]);
1868 6: ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1869 6: unsigned IndexTypeQuals = Record[2];
1870 6: return Context->getIncompleteArrayType(ElementType, ASM, IndexTypeQuals);
1871 : }
1872 :
1873 : case pch::TYPE_VARIABLE_ARRAY: {
1874 1: QualType ElementType = GetType(Record[0]);
1875 1: ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
1876 1: unsigned IndexTypeQuals = Record[2];
1877 1: SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
1878 1: SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
1879 : return Context->getVariableArrayType(ElementType, ReadTypeExpr(),
1880 : ASM, IndexTypeQuals,
1881 1: SourceRange(LBLoc, RBLoc));
1882 : }
1883 :
1884 : case pch::TYPE_VECTOR: {
0: branch 1 not taken
1: branch 2 taken
1885 1: if (Record.size() != 4) {
1886 0: Error("incorrect encoding of vector type in PCH file");
1887 0: return QualType();
1888 : }
1889 :
1890 1: QualType ElementType = GetType(Record[0]);
1891 1: unsigned NumElements = Record[1];
1892 1: bool AltiVec = Record[2];
1893 1: bool Pixel = Record[3];
1894 1: return Context->getVectorType(ElementType, NumElements, AltiVec, Pixel);
1895 : }
1896 :
1897 : case pch::TYPE_EXT_VECTOR: {
0: branch 1 not taken
4: branch 2 taken
1898 4: if (Record.size() != 4) {
1899 0: Error("incorrect encoding of extended vector type in PCH file");
1900 0: return QualType();
1901 : }
1902 :
1903 4: QualType ElementType = GetType(Record[0]);
1904 4: unsigned NumElements = Record[1];
1905 4: return Context->getExtVectorType(ElementType, NumElements);
1906 : }
1907 :
1908 : case pch::TYPE_FUNCTION_NO_PROTO: {
0: branch 1 not taken
5: branch 2 taken
1909 5: if (Record.size() != 3) {
1910 0: Error("incorrect encoding of no-proto function type");
1911 0: return QualType();
1912 : }
1913 5: QualType ResultType = GetType(Record[0]);
1914 : return Context->getFunctionNoProtoType(ResultType, Record[1],
1915 5: (CallingConv)Record[2]);
1916 : }
1917 :
1918 : case pch::TYPE_FUNCTION_PROTO: {
1919 39: QualType ResultType = GetType(Record[0]);
1920 39: bool NoReturn = Record[1];
1921 39: CallingConv CallConv = (CallingConv)Record[2];
1922 39: unsigned Idx = 3;
1923 39: unsigned NumParams = Record[Idx++];
1924 39: llvm::SmallVector<QualType, 16> ParamTypes;
58: branch 0 taken
39: branch 1 taken
1925 97: for (unsigned I = 0; I != NumParams; ++I)
1926 58: ParamTypes.push_back(GetType(Record[Idx++]));
1927 39: bool isVariadic = Record[Idx++];
1928 39: unsigned Quals = Record[Idx++];
1929 39: bool hasExceptionSpec = Record[Idx++];
1930 39: bool hasAnyExceptionSpec = Record[Idx++];
1931 39: unsigned NumExceptions = Record[Idx++];
1932 39: llvm::SmallVector<QualType, 2> Exceptions;
0: branch 0 not taken
39: branch 1 taken
1933 39: for (unsigned I = 0; I != NumExceptions; ++I)
1934 0: Exceptions.push_back(GetType(Record[Idx++]));
1935 : return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams,
1936 : isVariadic, Quals, hasExceptionSpec,
1937 : hasAnyExceptionSpec, NumExceptions,
1938 39: Exceptions.data(), NoReturn, CallConv);
1939 : }
1940 :
1941 : case pch::TYPE_UNRESOLVED_USING:
1942 : return Context->getTypeDeclType(
1943 0: cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));
1944 :
1945 : case pch::TYPE_TYPEDEF:
88: branch 1 taken
0: branch 2 not taken
1946 88: assert(Record.size() == 1 && "incorrect encoding of typedef type");
1947 88: return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));
1948 :
1949 : case pch::TYPE_TYPEOF_EXPR:
1950 36: return Context->getTypeOfExprType(ReadTypeExpr());
1951 :
1952 : case pch::TYPE_TYPEOF: {
0: branch 1 not taken
4: branch 2 taken
1953 4: if (Record.size() != 1) {
1954 0: Error("incorrect encoding of typeof(type) in PCH file");
1955 0: return QualType();
1956 : }
1957 4: QualType UnderlyingType = GetType(Record[0]);
1958 4: return Context->getTypeOfType(UnderlyingType);
1959 : }
1960 :
1961 : case pch::TYPE_DECLTYPE:
1962 0: return Context->getDecltypeType(ReadTypeExpr());
1963 :
1964 : case pch::TYPE_RECORD:
31: branch 1 taken
0: branch 2 not taken
1965 31: assert(Record.size() == 1 && "incorrect encoding of record type");
1966 31: return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
1967 :
1968 : case pch::TYPE_ENUM:
6: branch 1 taken
0: branch 2 not taken
1969 6: assert(Record.size() == 1 && "incorrect encoding of enum type");
1970 6: return Context->getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));
1971 :
1972 : case pch::TYPE_ELABORATED: {
0: branch 1 not taken
0: branch 2 not taken
1973 0: assert(Record.size() == 2 && "incorrect encoding of elaborated type");
1974 0: unsigned Tag = Record[1];
1975 : return Context->getElaboratedType(GetType(Record[0]),
1976 0: (ElaboratedType::TagKind) Tag);
1977 : }
1978 :
1979 : case pch::TYPE_OBJC_INTERFACE: {
1980 22: unsigned Idx = 0;
1981 22: ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));
1982 22: unsigned NumProtos = Record[Idx++];
1983 22: llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
1: branch 0 taken
22: branch 1 taken
1984 23: for (unsigned I = 0; I != NumProtos; ++I)
1985 1: Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
1986 22: return Context->getObjCInterfaceType(ItfD, Protos.data(), NumProtos);
1987 : }
1988 :
1989 : case pch::TYPE_OBJC_OBJECT_POINTER: {
1990 40: unsigned Idx = 0;
1991 40: QualType OIT = GetType(Record[Idx++]);
1992 40: unsigned NumProtos = Record[Idx++];
1993 40: llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
6: branch 0 taken
40: branch 1 taken
1994 46: for (unsigned I = 0; I != NumProtos; ++I)
1995 6: Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
1996 40: return Context->getObjCObjectPointerType(OIT, Protos.data(), NumProtos);
1997 : }
1998 :
1999 : case pch::TYPE_SUBST_TEMPLATE_TYPE_PARM: {
2000 0: unsigned Idx = 0;
2001 0: QualType Parm = GetType(Record[Idx++]);
2002 0: QualType Replacement = GetType(Record[Idx++]);
2003 : return
2004 : Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
2005 0: Replacement);
2006 : }
2007 : }
2008 : // Suppress a GCC warning
2009 0: return QualType();
2010 : }
2011 :
2012 : namespace {
2013 :
2014 : class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
2015 : PCHReader &Reader;
2016 : const PCHReader::RecordData &Record;
2017 : unsigned &Idx;
2018 :
2019 : public:
2020 : TypeLocReader(PCHReader &Reader, const PCHReader::RecordData &Record,
2021 373: unsigned &Idx)
2022 373: : Reader(Reader), Record(Record), Idx(Idx) { }
2023 :
2024 : // We want compile-time assurance that we've enumerated all of
2025 : // these, so unfortunately we have to declare them first, then
2026 : // define them out-of-line.
2027 : #define ABSTRACT_TYPELOC(CLASS, PARENT)
2028 : #define TYPELOC(CLASS, PARENT) \
2029 : void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
2030 : #include "clang/AST/TypeLocNodes.def"
2031 :
2032 : void VisitFunctionTypeLoc(FunctionTypeLoc);
2033 : void VisitArrayTypeLoc(ArrayTypeLoc);
2034 : };
2035 :
2036 : }
2037 :
2038 14: void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
2039 : // nothing to do
2040 14: }
2041 284: void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
2042 284: TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
178: branch 1 taken
106: branch 2 taken
2043 284: if (TL.needsExtraLocalData()) {
2044 178: TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++]));
2045 178: TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++]));
2046 178: TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++]));
2047 178: TL.setModeAttr(Record[Idx++]);
2048 : }
2049 284: }
2050 1: void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
2051 1: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2052 1: }
2053 71: void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
2054 71: TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2055 71: }
2056 2: void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
2057 2: TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2058 2: }
2059 0: void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
2060 0: TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2061 0: }
2062 0: void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
2063 0: TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2064 0: }
2065 0: void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
2066 0: TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2067 0: }
2068 19: void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
2069 19: TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2070 19: TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
12: branch 1 taken
7: branch 2 taken
2071 19: if (Record[Idx++])
2072 12: TL.setSizeExpr(Reader.ReadDeclExpr());
2073 : else
2074 7: TL.setSizeExpr(0);
2075 19: }
2076 11: void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
2077 11: VisitArrayTypeLoc(TL);
2078 11: }
2079 7: void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
2080 7: VisitArrayTypeLoc(TL);
2081 7: }
2082 1: void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
2083 1: VisitArrayTypeLoc(TL);
2084 1: }
2085 : void TypeLocReader::VisitDependentSizedArrayTypeLoc(
2086 0: DependentSizedArrayTypeLoc TL) {
2087 0: VisitArrayTypeLoc(TL);
2088 0: }
2089 : void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
2090 0: DependentSizedExtVectorTypeLoc TL) {
2091 0: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2092 0: }
2093 1: void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
2094 1: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2095 1: }
2096 4: void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
2097 4: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2098 4: }
2099 49: void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
2100 49: TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2101 49: TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
59: branch 1 taken
49: branch 2 taken
2102 108: for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2103 59: TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
2104 : }
2105 49: }
2106 43: void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
2107 43: VisitFunctionTypeLoc(TL);
2108 43: }
2109 6: void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
2110 6: VisitFunctionTypeLoc(TL);
2111 6: }
2112 0: void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
2113 0: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2114 0: }
2115 15: void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
2116 15: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2117 15: }
2118 36: void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
2119 36: TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2120 36: TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2121 36: TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2122 36: }
2123 4: void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
2124 4: TL.setTypeofLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2125 4: TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2126 4: TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2127 4: TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(Record, Idx));
2128 4: }
2129 0: void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
2130 0: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2131 0: }
2132 19: void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
2133 19: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2134 19: }
2135 1: void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
2136 1: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2137 1: }
2138 0: void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
2139 0: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2140 0: }
2141 0: void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
2142 0: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2143 0: }
2144 : void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc(
2145 0: SubstTemplateTypeParmTypeLoc TL) {
2146 0: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2147 0: }
2148 : void TypeLocReader::VisitTemplateSpecializationTypeLoc(
2149 0: TemplateSpecializationTypeLoc TL) {
2150 0: TL.setTemplateNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2151 0: TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2152 0: TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
0: branch 1 not taken
0: branch 2 not taken
2153 0: for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
2154 : TL.setArgLocInfo(i,
2155 : Reader.GetTemplateArgumentLocInfo(TL.getTypePtr()->getArg(i).getKind(),
2156 0: Record, Idx));
2157 0: }
2158 0: void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
2159 0: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2160 0: }
2161 0: void TypeLocReader::VisitTypenameTypeLoc(TypenameTypeLoc TL) {
2162 0: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2163 0: }
2164 8: void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
2165 8: TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2166 8: TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2167 8: TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
1: branch 1 taken
8: branch 2 taken
2168 9: for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
2169 1: TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
2170 8: }
2171 37: void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
2172 37: TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2173 37: TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2174 37: TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
2175 37: TL.setHasBaseTypeAsWritten(Record[Idx++]);
2176 37: TL.setHasProtocolsAsWritten(Record[Idx++]);
5: branch 1 taken
32: branch 2 taken
2177 37: if (TL.hasProtocolsAsWritten())
5: branch 1 taken
5: branch 2 taken
2178 10: for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
2179 5: TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
2180 37: }
2181 :
2182 : TypeSourceInfo *PCHReader::GetTypeSourceInfo(const RecordData &Record,
2183 380: unsigned &Idx) {
2184 380: QualType InfoTy = GetType(Record[Idx++]);
7: branch 1 taken
373: branch 2 taken
2185 380: if (InfoTy.isNull())
2186 7: return 0;
2187 :
2188 373: TypeSourceInfo *TInfo = getContext()->CreateTypeSourceInfo(InfoTy);
2189 373: TypeLocReader TLR(*this, Record, Idx);
565: branch 3 taken
373: branch 4 taken
2190 938: for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
2191 565: TLR.Visit(TL);
2192 373: return TInfo;
2193 : }
2194 :
2195 1651: QualType PCHReader::GetType(pch::TypeID ID) {
2196 1651: unsigned FastQuals = ID & Qualifiers::FastMask;
2197 1651: unsigned Index = ID >> Qualifiers::FastWidth;
2198 :
931: branch 0 taken
720: branch 1 taken
2199 1651: if (Index < pch::NUM_PREDEF_TYPE_IDS) {
2200 931: QualType T;
166: branch 0 taken
33: branch 1 taken
8: branch 2 taken
43: branch 3 taken
0: branch 4 not taken
0: branch 5 not taken
30: branch 6 taken
0: branch 7 not taken
0: branch 8 not taken
9: branch 9 taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
458: branch 13 taken
2: branch 14 taken
0: branch 15 not taken
9: branch 16 taken
75: branch 17 taken
55: branch 18 taken
0: branch 19 not taken
0: branch 20 not taken
0: branch 21 not taken
2: branch 22 taken
0: branch 23 not taken
0: branch 24 not taken
17: branch 25 taken
12: branch 26 taken
12: branch 27 taken
0: branch 28 not taken
2201 931: switch ((pch::PredefinedTypeIDs)Index) {
2202 166: case pch::PREDEF_TYPE_NULL_ID: return QualType();
2203 33: case pch::PREDEF_TYPE_VOID_ID: T = Context->VoidTy; break;
2204 8: case pch::PREDEF_TYPE_BOOL_ID: T = Context->BoolTy; break;
2205 :
2206 : case pch::PREDEF_TYPE_CHAR_U_ID:
2207 : case pch::PREDEF_TYPE_CHAR_S_ID:
2208 : // FIXME: Check that the signedness of CharTy is correct!
2209 43: T = Context->CharTy;
2210 43: break;
2211 :
2212 0: case pch::PREDEF_TYPE_UCHAR_ID: T = Context->UnsignedCharTy; break;
2213 0: case pch::PREDEF_TYPE_USHORT_ID: T = Context->UnsignedShortTy; break;
2214 30: case pch::PREDEF_TYPE_UINT_ID: T = Context->UnsignedIntTy; break;
2215 0: case pch::PREDEF_TYPE_ULONG_ID: T = Context->UnsignedLongTy; break;
2216 0: case pch::PREDEF_TYPE_ULONGLONG_ID: T = Context->UnsignedLongLongTy; break;
2217 9: case pch::PREDEF_TYPE_UINT128_ID: T = Context->UnsignedInt128Ty; break;
2218 0: case pch::PREDEF_TYPE_SCHAR_ID: T = Context->SignedCharTy; break;
2219 0: case pch::PREDEF_TYPE_WCHAR_ID: T = Context->WCharTy; break;
2220 0: case pch::PREDEF_TYPE_SHORT_ID: T = Context->ShortTy; break;
2221 458: case pch::PREDEF_TYPE_INT_ID: T = Context->IntTy; break;
2222 2: case pch::PREDEF_TYPE_LONG_ID: T = Context->LongTy; break;
2223 0: case pch::PREDEF_TYPE_LONGLONG_ID: T = Context->LongLongTy; break;
2224 9: case pch::PREDEF_TYPE_INT128_ID: T = Context->Int128Ty; break;
2225 75: case pch::PREDEF_TYPE_FLOAT_ID: T = Context->FloatTy; break;
2226 55: case pch::PREDEF_TYPE_DOUBLE_ID: T = Context->DoubleTy; break;
2227 0: case pch::PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
2228 0: case pch::PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
2229 0: case pch::PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
2230 2: case pch::PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
2231 0: case pch::PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
2232 0: case pch::PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
2233 17: case pch::PREDEF_TYPE_OBJC_ID: T = Context->ObjCBuiltinIdTy; break;
2234 12: case pch::PREDEF_TYPE_OBJC_CLASS: T = Context->ObjCBuiltinClassTy; break;
2235 12: case pch::PREDEF_TYPE_OBJC_SEL: T = Context->ObjCBuiltinSelTy; break;
2236 : }
2237 :
765: branch 1 taken
0: branch 2 not taken
2238 765: assert(!T.isNull() && "Unknown predefined type");
2239 765: return T.withFastQualifiers(FastQuals);
2240 : }
2241 :
2242 720: Index -= pch::NUM_PREDEF_TYPE_IDS;
2243 : //assert(Index < TypesLoaded.size() && "Type index out-of-range");
379: branch 2 taken
341: branch 3 taken
2244 720: if (TypesLoaded[Index].isNull())
2245 379: TypesLoaded[Index] = ReadTypeRecord(TypeOffsets[Index]);
2246 :
2247 720: return TypesLoaded[Index].withFastQualifiers(FastQuals);
2248 : }
2249 :
2250 : TemplateArgumentLocInfo
2251 : PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
2252 : const RecordData &Record,
2253 0: unsigned &Index) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
2254 0: switch (Kind) {
2255 : case TemplateArgument::Expression:
2256 0: return ReadDeclExpr();
2257 : case TemplateArgument::Type:
2258 0: return GetTypeSourceInfo(Record, Index);
2259 : case TemplateArgument::Template: {
2260 : SourceLocation
2261 0: QualStart = SourceLocation::getFromRawEncoding(Record[Index++]),
2262 0: QualEnd = SourceLocation::getFromRawEncoding(Record[Index++]),
2263 0: TemplateNameLoc = SourceLocation::getFromRawEncoding(Record[Index++]);
2264 : return TemplateArgumentLocInfo(SourceRange(QualStart, QualEnd),
2265 0: TemplateNameLoc);
2266 : }
2267 : case TemplateArgument::Null:
2268 : case TemplateArgument::Integral:
2269 : case TemplateArgument::Declaration:
2270 : case TemplateArgument::Pack:
2271 0: return TemplateArgumentLocInfo();
2272 : }
2273 0: llvm_unreachable("unexpected template argument loc");
2274 : return TemplateArgumentLocInfo();
2275 : }
2276 :
2277 2377: Decl *PCHReader::GetDecl(pch::DeclID ID) {
428: branch 0 taken
1949: branch 1 taken
2278 2377: if (ID == 0)
2279 428: return 0;
2280 :
0: branch 1 not taken
1949: branch 2 taken
2281 1949: if (ID > DeclsLoaded.size()) {
2282 0: Error("declaration ID out-of-range for PCH file");
2283 0: return 0;
2284 : }
2285 :
2286 1949: unsigned Index = ID - 1;
471: branch 1 taken
1478: branch 2 taken
2287 1949: if (!DeclsLoaded[Index])
2288 471: ReadDeclRecord(DeclOffsets[Index], Index);
2289 :
2290 1949: return DeclsLoaded[Index];
2291 : }
2292 :
2293 : /// \brief Resolve the offset of a statement into a statement.
2294 : ///
2295 : /// This operation will read a new statement from the external
2296 : /// source each time it is called, and is meant to be used via a
2297 : /// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
2298 25: Stmt *PCHReader::GetDeclStmt(uint64_t Offset) {
2299 : // Since we know tha this statement is part of a decl, make sure to use the
2300 : // decl cursor to read it.
2301 25: DeclsCursor.JumpToBit(Offset);
2302 25: return ReadStmt(DeclsCursor);
2303 : }
2304 :
2305 : bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,
2306 36: llvm::SmallVectorImpl<pch::DeclID> &Decls) {
2307 : assert(DC->hasExternalLexicalStorage() &&
36: branch 1 taken
0: branch 2 not taken
2308 36: "DeclContext has no lexical decls in storage");
2309 36: uint64_t Offset = DeclContextOffsets[DC].first;
0: branch 0 not taken
36: branch 1 taken
2310 36: assert(Offset && "DeclContext has no lexical decls in storage");
2311 :
2312 : // Keep track of where we are in the stream, then jump back there
2313 : // after reading this context.
2314 36: SavedStreamPosition SavedPosition(DeclsCursor);
2315 :
2316 : // Load the record containing all of the declarations lexically in
2317 : // this context.
2318 36: DeclsCursor.JumpToBit(Offset);
2319 36: RecordData Record;
2320 36: unsigned Code = DeclsCursor.ReadCode();
2321 36: unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
2322 : (void)RecCode;
0: branch 0 not taken
36: branch 1 taken
2323 36: assert(RecCode == pch::DECL_CONTEXT_LEXICAL && "Expected lexical block");
2324 :
2325 : // Load all of the declaration IDs
2326 36: Decls.clear();
2327 36: Decls.insert(Decls.end(), Record.begin(), Record.end());
2328 36: ++NumLexicalDeclContextsRead;
2329 36: return false;
2330 : }
2331 :
2332 : bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,
2333 6: llvm::SmallVectorImpl<VisibleDeclaration> &Decls) {
2334 : assert(DC->hasExternalVisibleStorage() &&
6: branch 1 taken
0: branch 2 not taken
2335 6: "DeclContext has no visible decls in storage");
2336 6: uint64_t Offset = DeclContextOffsets[DC].second;
0: branch 0 not taken
6: branch 1 taken
2337 6: assert(Offset && "DeclContext has no visible decls in storage");
2338 :
2339 : // Keep track of where we are in the stream, then jump back there
2340 : // after reading this context.
2341 6: SavedStreamPosition SavedPosition(DeclsCursor);
2342 :
2343 : // Load the record containing all of the declarations visible in
2344 : // this context.
2345 6: DeclsCursor.JumpToBit(Offset);
2346 6: RecordData Record;
2347 6: unsigned Code = DeclsCursor.ReadCode();
2348 6: unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
2349 : (void)RecCode;
0: branch 0 not taken
6: branch 1 taken
2350 6: assert(RecCode == pch::DECL_CONTEXT_VISIBLE && "Expected visible block");
0: branch 1 not taken
6: branch 2 taken
2351 6: if (Record.size() == 0)
2352 0: return false;
2353 :
2354 6: Decls.clear();
2355 :
2356 6: unsigned Idx = 0;
19: branch 1 taken
6: branch 2 taken
2357 31: while (Idx < Record.size()) {
2358 19: Decls.push_back(VisibleDeclaration());
2359 19: Decls.back().Name = ReadDeclarationName(Record, Idx);
2360 :
2361 19: unsigned Size = Record[Idx++];
2362 19: llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
2363 19: LoadedDecls.reserve(Size);
21: branch 0 taken
19: branch 1 taken
2364 40: for (unsigned I = 0; I < Size; ++I)
2365 21: LoadedDecls.push_back(Record[Idx++]);
2366 : }
2367 :
2368 6: ++NumVisibleDeclContextsRead;
2369 6: return false;
2370 : }
2371 :
2372 35: void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
2373 35: this->Consumer = Consumer;
2374 :
0: branch 0 not taken
35: branch 1 taken
2375 35: if (!Consumer)
2376 0: return;
2377 :
36: branch 1 taken
35: branch 2 taken
2378 71: for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
2379 : // Force deserialization of this decl, which will cause it to be passed to
2380 : // the consumer (or queued).
2381 36: GetDecl(ExternalDefinitions[I]);
2382 : }
2383 :
4: branch 1 taken
35: branch 2 taken
2384 39: for (unsigned I = 0, N = InterestingDecls.size(); I != N; ++I) {
2385 4: DeclGroupRef DG(InterestingDecls[I]);
2386 4: Consumer->HandleTopLevelDecl(DG);
2387 : }
2388 : }
2389 :
2390 0: void PCHReader::PrintStats() {
2391 0: std::fprintf(stderr, "*** PCH Statistics:\n");
2392 :
2393 : unsigned NumTypesLoaded
2394 : = TypesLoaded.size() - std::count(TypesLoaded.begin(), TypesLoaded.end(),
2395 0: QualType());
2396 : unsigned NumDeclsLoaded
2397 : = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
2398 0: (Decl *)0);
2399 : unsigned NumIdentifiersLoaded
2400 : = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
2401 : IdentifiersLoaded.end(),
2402 0: (IdentifierInfo *)0);
2403 : unsigned NumSelectorsLoaded
2404 : = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
2405 : SelectorsLoaded.end(),
2406 0: Selector());
2407 :
2408 0: std::fprintf(stderr, " %u stat cache hits\n", NumStatHits);
2409 0: std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses);
0: branch 0 not taken
0: branch 1 not taken
2410 0: if (TotalNumSLocEntries)
2411 : std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n",
2412 : NumSLocEntriesRead, TotalNumSLocEntries,
2413 0: ((float)NumSLocEntriesRead/TotalNumSLocEntries * 100));
0: branch 1 not taken
0: branch 2 not taken
2414 0: if (!TypesLoaded.empty())
2415 : std::fprintf(stderr, " %u/%u types read (%f%%)\n",
2416 : NumTypesLoaded, (unsigned)TypesLoaded.size(),
2417 0: ((float)NumTypesLoaded/TypesLoaded.size() * 100));
0: branch 1 not taken
0: branch 2 not taken
2418 0: if (!DeclsLoaded.empty())
2419 : std::fprintf(stderr, " %u/%u declarations read (%f%%)\n",
2420 : NumDeclsLoaded, (unsigned)DeclsLoaded.size(),
2421 0: ((float)NumDeclsLoaded/DeclsLoaded.size() * 100));
0: branch 1 not taken
0: branch 2 not taken
2422 0: if (!IdentifiersLoaded.empty())
2423 : std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
2424 : NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
2425 0: ((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
0: branch 0 not taken
0: branch 1 not taken
2426 0: if (TotalNumSelectors)
2427 : std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
2428 : NumSelectorsLoaded, TotalNumSelectors,
2429 0: ((float)NumSelectorsLoaded/TotalNumSelectors * 100));
0: branch 0 not taken
0: branch 1 not taken
2430 0: if (TotalNumStatements)
2431 : std::fprintf(stderr, " %u/%u statements read (%f%%)\n",
2432 : NumStatementsRead, TotalNumStatements,
2433 0: ((float)NumStatementsRead/TotalNumStatements * 100));
0: branch 0 not taken
0: branch 1 not taken
2434 0: if (TotalNumMacros)
2435 : std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
2436 : NumMacrosRead, TotalNumMacros,
2437 0: ((float)NumMacrosRead/TotalNumMacros * 100));
0: branch 0 not taken
0: branch 1 not taken
2438 0: if (TotalLexicalDeclContexts)
2439 : std::fprintf(stderr, " %u/%u lexical declcontexts read (%f%%)\n",
2440 : NumLexicalDeclContextsRead, TotalLexicalDeclContexts,
2441 : ((float)NumLexicalDeclContextsRead/TotalLexicalDeclContexts
2442 0: * 100));
0: branch 0 not taken
0: branch 1 not taken
2443 0: if (TotalVisibleDeclContexts)
2444 : std::fprintf(stderr, " %u/%u visible declcontexts read (%f%%)\n",
2445 : NumVisibleDeclContextsRead, TotalVisibleDeclContexts,
2446 : ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts
2447 0: * 100));
0: branch 0 not taken
0: branch 1 not taken
2448 0: if (TotalSelectorsInMethodPool) {
2449 : std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n",
2450 : NumMethodPoolSelectorsRead, TotalSelectorsInMethodPool,
2451 : ((float)NumMethodPoolSelectorsRead/TotalSelectorsInMethodPool
2452 0: * 100));
2453 0: std::fprintf(stderr, " %u method pool misses\n", NumMethodPoolMisses);
2454 : }
2455 0: std::fprintf(stderr, "\n");
2456 0: }
2457 :
2458 35: void PCHReader::InitializeSema(Sema &S) {
2459 35: SemaObj = &S;
2460 35: S.ExternalSource = this;
2461 :
2462 : // Makes sure any declarations that were deserialized "too early"
2463 : // still get added to the identifier's declaration chains.
35: branch 1 taken
35: branch 2 taken
2464 70: for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
2465 35: SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(PreloadedDecls[I]));
2466 35: SemaObj->IdResolver.AddDecl(PreloadedDecls[I]);
2467 : }
2468 35: PreloadedDecls.clear();
2469 :
2470 : // If there were any tentative definitions, deserialize them and add
2471 : // them to Sema's list of tentative definitions.
27: branch 1 taken
35: branch 2 taken
2472 62: for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
2473 27: VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
2474 27: SemaObj->TentativeDefinitions.push_back(Var);
2475 : }
2476 :
2477 : // If there were any locally-scoped external declarations,
2478 : // deserialize them and add them to Sema's table of locally-scoped
2479 : // external declarations.
4: branch 1 taken
35: branch 2 taken
2480 39: for (unsigned I = 0, N = LocallyScopedExternalDecls.size(); I != N; ++I) {
2481 4: NamedDecl *D = cast<NamedDecl>(GetDecl(LocallyScopedExternalDecls[I]));
2482 4: SemaObj->LocallyScopedExternalDecls[D->getDeclName()] = D;
2483 : }
2484 :
2485 : // If there were any ext_vector type declarations, deserialize them
2486 : // and add them to Sema's vector of such declarations.
4: branch 1 taken
35: branch 2 taken
2487 39: for (unsigned I = 0, N = ExtVectorDecls.size(); I != N; ++I)
2488 : SemaObj->ExtVectorDecls.push_back(
2489 4: cast<TypedefDecl>(GetDecl(ExtVectorDecls[I])));
2490 35: }
2491 :
2492 1770: IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
2493 : // Try to find this name within our on-disk hash table
2494 : PCHIdentifierLookupTable *IdTable
2495 1770: = (PCHIdentifierLookupTable *)IdentifierLookupTable;
2496 1770: std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
2497 1770: PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
197: branch 2 taken
1573: branch 3 taken
2498 1770: if (Pos == IdTable->end())
2499 197: return 0;
2500 :
2501 : // Dereferencing the iterator has the effect of building the
2502 : // IdentifierInfo node and populating it with the various
2503 : // declarations it needs.
2504 1573: return *Pos;
2505 : }
2506 :
2507 : std::pair<ObjCMethodList, ObjCMethodList>
2508 1: PCHReader::ReadMethodPool(Selector Sel) {
0: branch 0 not taken
1: branch 1 taken
2509 1: if (!MethodPoolLookupTable)
2510 0: return std::pair<ObjCMethodList, ObjCMethodList>();
2511 :
2512 : // Try to find this selector within our on-disk hash table.
2513 : PCHMethodPoolLookupTable *PoolTable
2514 1: = (PCHMethodPoolLookupTable*)MethodPoolLookupTable;
2515 1: PCHMethodPoolLookupTable::iterator Pos = PoolTable->find(Sel);
0: branch 2 not taken
1: branch 3 taken
2516 1: if (Pos == PoolTable->end()) {
2517 0: ++NumMethodPoolMisses;
2518 0: return std::pair<ObjCMethodList, ObjCMethodList>();;
2519 : }
2520 :
2521 1: ++NumMethodPoolSelectorsRead;
2522 1: return *Pos;
2523 : }
2524 :
2525 5416: void PCHReader::SetIdentifierInfo(unsigned ID, IdentifierInfo *II) {
0: branch 0 not taken
5416: branch 1 taken
2526 5416: assert(ID && "Non-zero identifier ID required");
5416: branch 1 taken
0: branch 2 not taken
2527 5416: assert(ID <= IdentifiersLoaded.size() && "identifier ID out of range");
2528 5416: IdentifiersLoaded[ID - 1] = II;
2529 5416: }
2530 :
2531 : /// \brief Set the globally-visible declarations associated with the given
2532 : /// identifier.
2533 : ///
2534 : /// If the PCH reader is currently in a state where the given declaration IDs
2535 : /// cannot safely be resolved, they are queued until it is safe to resolve
2536 : /// them.
2537 : ///
2538 : /// \param II an IdentifierInfo that refers to one or more globally-visible
2539 : /// declarations.
2540 : ///
2541 : /// \param DeclIDs the set of declaration IDs with the name @p II that are
2542 : /// visible at global scope.
2543 : ///
2544 : /// \param Nonrecursive should be true to indicate that the caller knows that
2545 : /// this call is non-recursive, and therefore the globally-visible declarations
2546 : /// will not be placed onto the pending queue.
2547 : void
2548 : PCHReader::SetGloballyVisibleDecls(IdentifierInfo *II,
2549 : const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
2550 505: bool Nonrecursive) {
436: branch 0 taken
69: branch 1 taken
218: branch 2 taken
218: branch 3 taken
2551 505: if (CurrentlyLoadingTypeOrDecl && !Nonrecursive) {
2552 218: PendingIdentifierInfos.push_back(PendingIdentifierInfo());
2553 218: PendingIdentifierInfo &PII = PendingIdentifierInfos.back();
2554 218: PII.II = II;
228: branch 1 taken
218: branch 2 taken
2555 446: for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I)
2556 228: PII.DeclIDs.push_back(DeclIDs[I]);
2557 218: return;
2558 : }
2559 :
299: branch 1 taken
287: branch 2 taken
2560 586: for (unsigned I = 0, N = DeclIDs.size(); I != N; ++I) {
2561 299: NamedDecl *D = cast<NamedDecl>(GetDecl(DeclIDs[I]));
168: branch 0 taken
131: branch 1 taken
2562 299: if (SemaObj) {
2563 : // Introduce this declaration into the translation-unit scope
2564 : // and add it to the declaration chain for this identifier, so
2565 : // that (unqualified) name lookup will find it.
2566 168: SemaObj->TUScope->AddDecl(Action::DeclPtrTy::make(D));
2567 168: SemaObj->IdResolver.AddDeclToIdentifierChain(II, D);
2568 : } else {
2569 : // Queue this declaration so that it will be added to the
2570 : // translation unit scope and identifier's declaration chain
2571 : // once a Sema object is known.
2572 131: PreloadedDecls.push_back(D);
2573 : }
2574 : }
2575 : }
2576 :
2577 1547: IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {
357: branch 0 taken
1190: branch 1 taken
2578 1547: if (ID == 0)
2579 357: return 0;
2580 :
1190: branch 0 taken
0: branch 1 not taken
0: branch 3 not taken
1190: branch 4 taken
0: branch 5 not taken
1190: branch 6 taken
2581 1190: if (!IdentifierTableData || IdentifiersLoaded.empty()) {
2582 0: Error("no identifier table in PCH file");
2583 0: return 0;
2584 : }
2585 :
0: branch 0 not taken
1190: branch 1 taken
2586 1190: assert(PP && "Forgot to set Preprocessor ?");
652: branch 1 taken
538: branch 2 taken
2587 1190: if (!IdentifiersLoaded[ID - 1]) {
2588 652: uint32_t Offset = IdentifierOffsets[ID - 1];
2589 652: const char *Str = IdentifierTableData + Offset;
2590 :
2591 : // All of the strings in the PCH file are preceded by a 16-bit
2592 : // length. Extract that 16-bit length to avoid having to execute
2593 : // strlen().
2594 : // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as
2595 : // unsigned integers. This is important to avoid integer overflow when
2596 : // we cast them to 'unsigned'.
2597 652: const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;
2598 : unsigned StrLen = (((unsigned) StrLenPtr[0])
2599 652: | (((unsigned) StrLenPtr[1]) << 8)) - 1;
2600 : IdentifiersLoaded[ID - 1]
2601 652: = &PP->getIdentifierTable().get(Str, Str + StrLen);
2602 : }
2603 :
2604 1190: return IdentifiersLoaded[ID - 1];
2605 : }
2606 :
2607 39: void PCHReader::ReadSLocEntry(unsigned ID) {
2608 39: ReadSLocEntryRecord(ID);
2609 39: }
2610 :
2611 51: Selector PCHReader::DecodeSelector(unsigned ID) {
0: branch 0 not taken
51: branch 1 taken
2612 51: if (ID == 0)
2613 0: return Selector();
2614 :
3: branch 0 taken
48: branch 1 taken
2615 51: if (!MethodPoolLookupTableData)
2616 3: return Selector();
2617 :
0: branch 0 not taken
48: branch 1 taken
2618 48: if (ID > TotalNumSelectors) {
2619 0: Error("selector ID out of range in PCH file");
2620 0: return Selector();
2621 : }
2622 :
2623 48: unsigned Index = ID - 1;
24: branch 2 taken
24: branch 3 taken
2624 48: if (SelectorsLoaded[Index].getAsOpaquePtr() == 0) {
2625 : // Load this selector from the selector table.
2626 : // FIXME: endianness portability issues with SelectorOffsets table
2627 24: PCHMethodPoolLookupTrait Trait(*this);
2628 : SelectorsLoaded[Index]
2629 24: = Trait.ReadKey(MethodPoolLookupTableData + SelectorOffsets[Index], 0);
2630 : }
2631 :
2632 48: return SelectorsLoaded[Index];
2633 : }
2634 :
2635 : DeclarationName
2636 487: PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
2637 487: DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
449: branch 0 taken
38: branch 1 taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
2638 487: switch (Kind) {
2639 : case DeclarationName::Identifier:
2640 449: return DeclarationName(GetIdentifierInfo(Record, Idx));
2641 :
2642 : case DeclarationName::ObjCZeroArgSelector:
2643 : case DeclarationName::ObjCOneArgSelector:
2644 : case DeclarationName::ObjCMultiArgSelector:
2645 38: return DeclarationName(GetSelector(Record, Idx));
2646 :
2647 : case DeclarationName::CXXConstructorName:
2648 : return Context->DeclarationNames.getCXXConstructorName(
2649 0: Context->getCanonicalType(GetType(Record[Idx++])));
2650 :
2651 : case DeclarationName::CXXDestructorName:
2652 : return Context->DeclarationNames.getCXXDestructorName(
2653 0: Context->getCanonicalType(GetType(Record[Idx++])));
2654 :
2655 : case DeclarationName::CXXConversionFunctionName:
2656 : return Context->DeclarationNames.getCXXConversionFunctionName(
2657 0: Context->getCanonicalType(GetType(Record[Idx++])));
2658 :
2659 : case DeclarationName::CXXOperatorName:
2660 : return Context->DeclarationNames.getCXXOperatorName(
2661 0: (OverloadedOperatorKind)Record[Idx++]);
2662 :
2663 : case DeclarationName::CXXLiteralOperatorName:
2664 : return Context->DeclarationNames.getCXXLiteralOperatorName(
2665 0: GetIdentifierInfo(Record, Idx));
2666 :
2667 : case DeclarationName::CXXUsingDirective:
2668 0: return DeclarationName::getUsingDirectiveName();
2669 : }
2670 :
2671 : // Required to silence GCC warning
2672 0: return DeclarationName();
2673 : }
2674 :
2675 : /// \brief Read an integral value
2676 116: llvm::APInt PCHReader::ReadAPInt(const RecordData &Record, unsigned &Idx) {
2677 116: unsigned BitWidth = Record[Idx++];
2678 116: unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
2679 116: llvm::APInt Result(BitWidth, NumWords, &Record[Idx]);
2680 116: Idx += NumWords;
2681 : return Result;
2682 : }
2683 :
2684 : /// \brief Read a signed integral value
2685 6: llvm::APSInt PCHReader::ReadAPSInt(const RecordData &Record, unsigned &Idx) {
2686 6: bool isUnsigned = Record[Idx++];
2687 6: return llvm::APSInt(ReadAPInt(Record, Idx), isUnsigned);
2688 : }
2689 :
2690 : /// \brief Read a floating-point value
2691 12: llvm::APFloat PCHReader::ReadAPFloat(const RecordData &Record, unsigned &Idx) {
2692 12: return llvm::APFloat(ReadAPInt(Record, Idx));
2693 : }
2694 :
2695 : // \brief Read a string
2696 4: std::string PCHReader::ReadString(const RecordData &Record, unsigned &Idx) {
2697 4: unsigned Len = Record[Idx++];
2698 4: std::string Result(Record.data() + Idx, Record.data() + Idx + Len);
2699 4: Idx += Len;
2700 : return Result;
2701 : }
2702 :
2703 3: DiagnosticBuilder PCHReader::Diag(unsigned DiagID) {
2704 3: return Diag(SourceLocation(), DiagID);
2705 : }
2706 :
2707 4: DiagnosticBuilder PCHReader::Diag(SourceLocation Loc, unsigned DiagID) {
2708 4: return Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
2709 : }
2710 :
2711 : /// \brief Retrieve the identifier table associated with the
2712 : /// preprocessor.
2713 1573: IdentifierTable &PCHReader::getIdentifierTable() {
0: branch 0 not taken
1573: branch 1 taken
2714 1573: assert(PP && "Forgot to set Preprocessor ?");
2715 1573: return PP->getIdentifierTable();
2716 : }
2717 :
2718 : /// \brief Record that the given ID maps to the given switch-case
2719 : /// statement.
2720 8: void PCHReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
8: branch 1 taken
0: branch 2 not taken
2721 8: assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
2722 8: SwitchCaseStmts[ID] = SC;
2723 8: }
2724 :
2725 : /// \brief Retrieve the switch-case statement with the given ID.
2726 8: SwitchCase *PCHReader::getSwitchCaseWithID(unsigned ID) {
8: branch 1 taken
0: branch 2 not taken
2727 8: assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
2728 8: return SwitchCaseStmts[ID];
2729 : }
2730 :
2731 : /// \brief Record that the given label statement has been
2732 : /// deserialized and has the given ID.
2733 4: void PCHReader::RecordLabelStmt(LabelStmt *S, unsigned ID) {
2734 : assert(LabelStmts.find(ID) == LabelStmts.end() &&
4: branch 3 taken
0: branch 4 not taken
2735 4: "Deserialized label twice");
2736 4: LabelStmts[ID] = S;
2737 :
2738 : // If we've already seen any goto statements that point to this
2739 : // label, resolve them now.
2740 : typedef std::multimap<unsigned, GotoStmt *>::iterator GotoIter;
2741 4: std::pair<GotoIter, GotoIter> Gotos = UnresolvedGotoStmts.equal_range(ID);
2: branch 2 taken
4: branch 3 taken
2742 6: for (GotoIter Goto = Gotos.first; Goto != Gotos.second; ++Goto)
2743 2: Goto->second->setLabel(S);
2744 4: UnresolvedGotoStmts.erase(Gotos.first, Gotos.second);
2745 :
2746 : // If we've already seen any address-label statements that point to
2747 : // this label, resolve them now.
2748 : typedef std::multimap<unsigned, AddrLabelExpr *>::iterator AddrLabelIter;
2749 : std::pair<AddrLabelIter, AddrLabelIter> AddrLabels
2750 4: = UnresolvedAddrLabelExprs.equal_range(ID);
1: branch 2 taken
4: branch 3 taken
2751 5: for (AddrLabelIter AddrLabel = AddrLabels.first;
2752 : AddrLabel != AddrLabels.second; ++AddrLabel)
2753 1: AddrLabel->second->setLabel(S);
2754 4: UnresolvedAddrLabelExprs.erase(AddrLabels.first, AddrLabels.second);
2755 4: }
2756 :
2757 : /// \brief Set the label of the given statement to the label
2758 : /// identified by ID.
2759 : ///
2760 : /// Depending on the order in which the label and other statements
2761 : /// referencing that label occur, this operation may complete
2762 : /// immediately (updating the statement) or it may queue the
2763 : /// statement to be back-patched later.
2764 2: void PCHReader::SetLabelOf(GotoStmt *S, unsigned ID) {
2765 2: std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
0: branch 2 not taken
2: branch 3 taken
2766 2: if (Label != LabelStmts.end()) {
2767 : // We've already seen this label, so set the label of the goto and
2768 : // we're done.
2769 0: S->setLabel(Label->second);
2770 : } else {
2771 : // We haven't seen this label yet, so add this goto to the set of
2772 : // unresolved goto statements.
2773 2: UnresolvedGotoStmts.insert(std::make_pair(ID, S));
2774 : }
2775 2: }
2776 :
2777 : /// \brief Set the label of the given expression to the label
2778 : /// identified by ID.
2779 : ///
2780 : /// Depending on the order in which the label and other statements
2781 : /// referencing that label occur, this operation may complete
2782 : /// immediately (updating the statement) or it may queue the
2783 : /// statement to be back-patched later.
2784 2: void PCHReader::SetLabelOf(AddrLabelExpr *S, unsigned ID) {
2785 2: std::map<unsigned, LabelStmt *>::iterator Label = LabelStmts.find(ID);
1: branch 2 taken
1: branch 3 taken
2786 2: if (Label != LabelStmts.end()) {
2787 : // We've already seen this label, so set the label of the
2788 : // label-address expression and we're done.
2789 1: S->setLabel(Label->second);
2790 : } else {
2791 : // We haven't seen this label yet, so add this label-address
2792 : // expression to the set of unresolved label-address expressions.
2793 1: UnresolvedAddrLabelExprs.insert(std::make_pair(ID, S));
2794 : }
2795 2: }
2796 :
2797 :
2798 896: PCHReader::LoadingTypeOrDecl::LoadingTypeOrDecl(PCHReader &Reader)
2799 896: : Reader(Reader), Parent(Reader.CurrentlyLoadingTypeOrDecl) {
2800 896: Reader.CurrentlyLoadingTypeOrDecl = this;
2801 896: }
2802 :
2803 896: PCHReader::LoadingTypeOrDecl::~LoadingTypeOrDecl() {
375: branch 0 taken
521: branch 1 taken
521: branch 2 taken
521: branch 3 taken
2804 896: if (!Parent) {
2805 : // If any identifiers with corresponding top-level declarations have
2806 : // been loaded, load those declarations now.
218: branch 1 taken
375: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
2807 968: while (!Reader.PendingIdentifierInfos.empty()) {
2808 : Reader.SetGloballyVisibleDecls(Reader.PendingIdentifierInfos.front().II,
2809 : Reader.PendingIdentifierInfos.front().DeclIDs,
2810 218: true);
2811 218: Reader.PendingIdentifierInfos.pop_front();
2812 : }
2813 : }
2814 :
2815 896: Reader.CurrentlyLoadingTypeOrDecl = Parent;
2816 896: }
Generated: 2010-02-10 01:31 by zcov