/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Serialization/ASTReader.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ASTReader.cpp - AST File Reader ------------------------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file defines the ASTReader class, which reads AST files. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "ASTCommon.h" |
14 | | #include "ASTReaderInternals.h" |
15 | | #include "clang/AST/ASTConsumer.h" |
16 | | #include "clang/AST/ASTContext.h" |
17 | | #include "clang/AST/ASTMutationListener.h" |
18 | | #include "clang/AST/ASTStructuralEquivalence.h" |
19 | | #include "clang/AST/ASTUnresolvedSet.h" |
20 | | #include "clang/AST/AbstractTypeReader.h" |
21 | | #include "clang/AST/Decl.h" |
22 | | #include "clang/AST/DeclBase.h" |
23 | | #include "clang/AST/DeclCXX.h" |
24 | | #include "clang/AST/DeclFriend.h" |
25 | | #include "clang/AST/DeclGroup.h" |
26 | | #include "clang/AST/DeclObjC.h" |
27 | | #include "clang/AST/DeclTemplate.h" |
28 | | #include "clang/AST/DeclarationName.h" |
29 | | #include "clang/AST/Expr.h" |
30 | | #include "clang/AST/ExprCXX.h" |
31 | | #include "clang/AST/ExternalASTSource.h" |
32 | | #include "clang/AST/NestedNameSpecifier.h" |
33 | | #include "clang/AST/ODRDiagsEmitter.h" |
34 | | #include "clang/AST/ODRHash.h" |
35 | | #include "clang/AST/OpenMPClause.h" |
36 | | #include "clang/AST/RawCommentList.h" |
37 | | #include "clang/AST/TemplateBase.h" |
38 | | #include "clang/AST/TemplateName.h" |
39 | | #include "clang/AST/Type.h" |
40 | | #include "clang/AST/TypeLoc.h" |
41 | | #include "clang/AST/TypeLocVisitor.h" |
42 | | #include "clang/AST/UnresolvedSet.h" |
43 | | #include "clang/Basic/CommentOptions.h" |
44 | | #include "clang/Basic/Diagnostic.h" |
45 | | #include "clang/Basic/DiagnosticError.h" |
46 | | #include "clang/Basic/DiagnosticOptions.h" |
47 | | #include "clang/Basic/DiagnosticSema.h" |
48 | | #include "clang/Basic/ExceptionSpecificationType.h" |
49 | | #include "clang/Basic/FileManager.h" |
50 | | #include "clang/Basic/FileSystemOptions.h" |
51 | | #include "clang/Basic/IdentifierTable.h" |
52 | | #include "clang/Basic/LLVM.h" |
53 | | #include "clang/Basic/LangOptions.h" |
54 | | #include "clang/Basic/Module.h" |
55 | | #include "clang/Basic/ObjCRuntime.h" |
56 | | #include "clang/Basic/OpenMPKinds.h" |
57 | | #include "clang/Basic/OperatorKinds.h" |
58 | | #include "clang/Basic/PragmaKinds.h" |
59 | | #include "clang/Basic/Sanitizers.h" |
60 | | #include "clang/Basic/SourceLocation.h" |
61 | | #include "clang/Basic/SourceManager.h" |
62 | | #include "clang/Basic/SourceManagerInternals.h" |
63 | | #include "clang/Basic/Specifiers.h" |
64 | | #include "clang/Basic/TargetInfo.h" |
65 | | #include "clang/Basic/TargetOptions.h" |
66 | | #include "clang/Basic/TokenKinds.h" |
67 | | #include "clang/Basic/Version.h" |
68 | | #include "clang/Lex/HeaderSearch.h" |
69 | | #include "clang/Lex/HeaderSearchOptions.h" |
70 | | #include "clang/Lex/MacroInfo.h" |
71 | | #include "clang/Lex/ModuleMap.h" |
72 | | #include "clang/Lex/PreprocessingRecord.h" |
73 | | #include "clang/Lex/Preprocessor.h" |
74 | | #include "clang/Lex/PreprocessorOptions.h" |
75 | | #include "clang/Lex/Token.h" |
76 | | #include "clang/Sema/ObjCMethodList.h" |
77 | | #include "clang/Sema/Scope.h" |
78 | | #include "clang/Sema/Sema.h" |
79 | | #include "clang/Sema/Weak.h" |
80 | | #include "clang/Serialization/ASTBitCodes.h" |
81 | | #include "clang/Serialization/ASTDeserializationListener.h" |
82 | | #include "clang/Serialization/ASTRecordReader.h" |
83 | | #include "clang/Serialization/ContinuousRangeMap.h" |
84 | | #include "clang/Serialization/GlobalModuleIndex.h" |
85 | | #include "clang/Serialization/InMemoryModuleCache.h" |
86 | | #include "clang/Serialization/ModuleFile.h" |
87 | | #include "clang/Serialization/ModuleFileExtension.h" |
88 | | #include "clang/Serialization/ModuleManager.h" |
89 | | #include "clang/Serialization/PCHContainerOperations.h" |
90 | | #include "clang/Serialization/SerializationDiagnostic.h" |
91 | | #include "llvm/ADT/APFloat.h" |
92 | | #include "llvm/ADT/APInt.h" |
93 | | #include "llvm/ADT/APSInt.h" |
94 | | #include "llvm/ADT/ArrayRef.h" |
95 | | #include "llvm/ADT/DenseMap.h" |
96 | | #include "llvm/ADT/FloatingPointMode.h" |
97 | | #include "llvm/ADT/FoldingSet.h" |
98 | | #include "llvm/ADT/Hashing.h" |
99 | | #include "llvm/ADT/IntrusiveRefCntPtr.h" |
100 | | #include "llvm/ADT/STLExtras.h" |
101 | | #include "llvm/ADT/ScopeExit.h" |
102 | | #include "llvm/ADT/SmallPtrSet.h" |
103 | | #include "llvm/ADT/SmallString.h" |
104 | | #include "llvm/ADT/SmallVector.h" |
105 | | #include "llvm/ADT/StringExtras.h" |
106 | | #include "llvm/ADT/StringMap.h" |
107 | | #include "llvm/ADT/StringRef.h" |
108 | | #include "llvm/ADT/iterator_range.h" |
109 | | #include "llvm/Bitstream/BitstreamReader.h" |
110 | | #include "llvm/Support/Casting.h" |
111 | | #include "llvm/Support/Compiler.h" |
112 | | #include "llvm/Support/Compression.h" |
113 | | #include "llvm/Support/DJB.h" |
114 | | #include "llvm/Support/Endian.h" |
115 | | #include "llvm/Support/Error.h" |
116 | | #include "llvm/Support/ErrorHandling.h" |
117 | | #include "llvm/Support/FileSystem.h" |
118 | | #include "llvm/Support/LEB128.h" |
119 | | #include "llvm/Support/MemoryBuffer.h" |
120 | | #include "llvm/Support/Path.h" |
121 | | #include "llvm/Support/SaveAndRestore.h" |
122 | | #include "llvm/Support/TimeProfiler.h" |
123 | | #include "llvm/Support/Timer.h" |
124 | | #include "llvm/Support/VersionTuple.h" |
125 | | #include "llvm/Support/raw_ostream.h" |
126 | | #include "llvm/TargetParser/Triple.h" |
127 | | #include <algorithm> |
128 | | #include <cassert> |
129 | | #include <cstddef> |
130 | | #include <cstdint> |
131 | | #include <cstdio> |
132 | | #include <ctime> |
133 | | #include <iterator> |
134 | | #include <limits> |
135 | | #include <map> |
136 | | #include <memory> |
137 | | #include <optional> |
138 | | #include <string> |
139 | | #include <system_error> |
140 | | #include <tuple> |
141 | | #include <utility> |
142 | | #include <vector> |
143 | | |
144 | | using namespace clang; |
145 | | using namespace clang::serialization; |
146 | | using namespace clang::serialization::reader; |
147 | | using llvm::BitstreamCursor; |
148 | | |
149 | | //===----------------------------------------------------------------------===// |
150 | | // ChainedASTReaderListener implementation |
151 | | //===----------------------------------------------------------------------===// |
152 | | |
153 | | bool |
154 | 0 | ChainedASTReaderListener::ReadFullVersionInformation(StringRef FullVersion) { |
155 | 0 | return First->ReadFullVersionInformation(FullVersion) || |
156 | 0 | Second->ReadFullVersionInformation(FullVersion); |
157 | 0 | } |
158 | | |
159 | 1.78k | void ChainedASTReaderListener::ReadModuleName(StringRef ModuleName) { |
160 | 1.78k | First->ReadModuleName(ModuleName); |
161 | 1.78k | Second->ReadModuleName(ModuleName); |
162 | 1.78k | } |
163 | | |
164 | 1.68k | void ChainedASTReaderListener::ReadModuleMapFile(StringRef ModuleMapPath) { |
165 | 1.68k | First->ReadModuleMapFile(ModuleMapPath); |
166 | 1.68k | Second->ReadModuleMapFile(ModuleMapPath); |
167 | 1.68k | } |
168 | | |
169 | | bool |
170 | | ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts, |
171 | | bool Complain, |
172 | 4.52k | bool AllowCompatibleDifferences) { |
173 | 4.52k | return First->ReadLanguageOptions(LangOpts, Complain, |
174 | 4.52k | AllowCompatibleDifferences) || |
175 | 4.52k | Second->ReadLanguageOptions(LangOpts, Complain, |
176 | 4.52k | AllowCompatibleDifferences); |
177 | 4.52k | } |
178 | | |
179 | | bool ChainedASTReaderListener::ReadTargetOptions( |
180 | | const TargetOptions &TargetOpts, bool Complain, |
181 | 4.52k | bool AllowCompatibleDifferences) { |
182 | 4.52k | return First->ReadTargetOptions(TargetOpts, Complain, |
183 | 4.52k | AllowCompatibleDifferences) || |
184 | 4.52k | Second->ReadTargetOptions(TargetOpts, Complain, |
185 | 4.52k | AllowCompatibleDifferences); |
186 | 4.52k | } |
187 | | |
188 | | bool ChainedASTReaderListener::ReadDiagnosticOptions( |
189 | 4.08k | IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) { |
190 | 4.08k | return First->ReadDiagnosticOptions(DiagOpts, Complain) || |
191 | 4.08k | Second->ReadDiagnosticOptions(DiagOpts, Complain); |
192 | 4.08k | } |
193 | | |
194 | | bool |
195 | | ChainedASTReaderListener::ReadFileSystemOptions(const FileSystemOptions &FSOpts, |
196 | 4.08k | bool Complain) { |
197 | 4.08k | return First->ReadFileSystemOptions(FSOpts, Complain) || |
198 | 4.08k | Second->ReadFileSystemOptions(FSOpts, Complain); |
199 | 4.08k | } |
200 | | |
201 | | bool ChainedASTReaderListener::ReadHeaderSearchOptions( |
202 | | const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath, |
203 | 4.08k | bool Complain) { |
204 | 4.08k | return First->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath, |
205 | 4.08k | Complain) || |
206 | 4.08k | Second->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath, |
207 | 4.08k | Complain); |
208 | 4.08k | } |
209 | | |
210 | | bool ChainedASTReaderListener::ReadPreprocessorOptions( |
211 | | const PreprocessorOptions &PPOpts, bool ReadMacros, bool Complain, |
212 | 4.08k | std::string &SuggestedPredefines) { |
213 | 4.08k | return First->ReadPreprocessorOptions(PPOpts, ReadMacros, Complain, |
214 | 4.08k | SuggestedPredefines) || |
215 | 4.08k | Second->ReadPreprocessorOptions(PPOpts, ReadMacros, Complain, |
216 | 4.08k | SuggestedPredefines); |
217 | 4.08k | } |
218 | | |
219 | | void ChainedASTReaderListener::ReadCounter(const serialization::ModuleFile &M, |
220 | 5 | unsigned Value) { |
221 | 5 | First->ReadCounter(M, Value); |
222 | 5 | Second->ReadCounter(M, Value); |
223 | 5 | } |
224 | | |
225 | 5.91k | bool ChainedASTReaderListener::needsInputFileVisitation() { |
226 | 5.91k | return First->needsInputFileVisitation() || |
227 | 5.91k | Second->needsInputFileVisitation()5.39k ; |
228 | 5.91k | } |
229 | | |
230 | 474 | bool ChainedASTReaderListener::needsSystemInputFileVisitation() { |
231 | 474 | return First->needsSystemInputFileVisitation() || |
232 | 474 | Second->needsSystemInputFileVisitation()42 ; |
233 | 474 | } |
234 | | |
235 | | void ChainedASTReaderListener::visitModuleFile(StringRef Filename, |
236 | 5.83k | ModuleKind Kind) { |
237 | 5.83k | First->visitModuleFile(Filename, Kind); |
238 | 5.83k | Second->visitModuleFile(Filename, Kind); |
239 | 5.83k | } |
240 | | |
241 | | bool ChainedASTReaderListener::visitInputFile(StringRef Filename, |
242 | | bool isSystem, |
243 | | bool isOverridden, |
244 | 12.3k | bool isExplicitModule) { |
245 | 12.3k | bool Continue = false; |
246 | 12.3k | if (First->needsInputFileVisitation() && |
247 | 12.3k | (12.2k !isSystem12.2k || First->needsSystemInputFileVisitation()11.9k )) |
248 | 12.2k | Continue |= First->visitInputFile(Filename, isSystem, isOverridden, |
249 | 12.2k | isExplicitModule); |
250 | 12.3k | if (Second->needsInputFileVisitation() && |
251 | 12.3k | (71 !isSystem71 || Second->needsSystemInputFileVisitation()0 )) |
252 | 71 | Continue |= Second->visitInputFile(Filename, isSystem, isOverridden, |
253 | 71 | isExplicitModule); |
254 | 12.3k | return Continue; |
255 | 12.3k | } |
256 | | |
257 | | void ChainedASTReaderListener::readModuleFileExtension( |
258 | 0 | const ModuleFileExtensionMetadata &Metadata) { |
259 | 0 | First->readModuleFileExtension(Metadata); |
260 | 0 | Second->readModuleFileExtension(Metadata); |
261 | 0 | } |
262 | | |
263 | | //===----------------------------------------------------------------------===// |
264 | | // PCH validator implementation |
265 | | //===----------------------------------------------------------------------===// |
266 | | |
267 | 24.2k | ASTReaderListener::~ASTReaderListener() = default; |
268 | | |
269 | | /// Compare the given set of language options against an existing set of |
270 | | /// language options. |
271 | | /// |
272 | | /// \param Diags If non-NULL, diagnostics will be emitted via this engine. |
273 | | /// \param AllowCompatibleDifferences If true, differences between compatible |
274 | | /// language options will be permitted. |
275 | | /// |
276 | | /// \returns true if the languagae options mis-match, false otherwise. |
277 | | static bool checkLanguageOptions(const LangOptions &LangOpts, |
278 | | const LangOptions &ExistingLangOpts, |
279 | | DiagnosticsEngine *Diags, |
280 | 11.9k | bool AllowCompatibleDifferences = true) { |
281 | 11.9k | #define LANGOPT(Name, Bits, Default, Description) \ |
282 | 2.12M | if (ExistingLangOpts.Name != LangOpts.Name) { \ |
283 | 25 | if (Diags) { \ |
284 | 9 | if (Bits == 1) \ |
285 | 9 | Diags->Report(diag::err_pch_langopt_mismatch) \ |
286 | 7 | << Description << LangOpts.Name << ExistingLangOpts.Name; \ |
287 | 9 | else \ |
288 | 9 | Diags->Report(diag::err_pch_langopt_value_mismatch) \ |
289 | 2 | << Description; \ |
290 | 9 | } \ |
291 | 25 | return true; \ |
292 | 25 | } |
293 | | |
294 | 11.9k | #define VALUE_LANGOPT(Name, Bits, Default, Description) \ |
295 | 162k | if (ExistingLangOpts.Name != LangOpts.Name) { \ |
296 | 2 | if (Diags) \ |
297 | 2 | Diags->Report(diag::err_pch_langopt_value_mismatch) \ |
298 | 0 | << Description; \ |
299 | 2 | return true; \ |
300 | 2 | } |
301 | | |
302 | 11.9k | #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ |
303 | 321k | if (ExistingLangOpts.get##Name() != LangOpts.get##Name()) { \ |
304 | 0 | if (Diags) \ |
305 | 0 | Diags->Report(diag::err_pch_langopt_value_mismatch) \ |
306 | 0 | << Description; \ |
307 | 0 | return true; \ |
308 | 0 | } |
309 | | |
310 | 11.9k | #define COMPATIBLE_LANGOPT(Name, Bits, Default, Description) \ |
311 | 238k | if (!AllowCompatibleDifferences) \ |
312 | 238k | LANGOPT219k (Name, Bits, Default, Description) |
313 | | |
314 | 11.9k | #define COMPATIBLE_ENUM_LANGOPT(Name, Bits, Default, Description) \ |
315 | 11.9k | if (!AllowCompatibleDifferences) \ |
316 | 11.9k | ENUM_LANGOPT(Name, Bits, Default, Description) |
317 | | |
318 | 11.9k | #define COMPATIBLE_VALUE_LANGOPT(Name, Bits, Default, Description) \ |
319 | 59.5k | if (!AllowCompatibleDifferences) \ |
320 | 59.5k | VALUE_LANGOPT54.9k (Name, Bits, Default, Description) |
321 | | |
322 | 11.9k | #define BENIGN_LANGOPT(Name, Bits, Default, Description) |
323 | 11.9k | #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) |
324 | 11.9k | #define BENIGN_VALUE_LANGOPT(Name, Bits, Default, Description) |
325 | 11.9k | #include "clang/Basic/LangOptions.def" |
326 | | |
327 | 11.9k | if (ExistingLangOpts.ModuleFeatures != LangOpts.ModuleFeatures) { |
328 | 1 | if (Diags) |
329 | 1 | Diags->Report(diag::err_pch_langopt_value_mismatch) << "module features"; |
330 | 1 | return true; |
331 | 1 | } |
332 | | |
333 | 11.9k | if (ExistingLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) { |
334 | 0 | if (Diags) |
335 | 0 | Diags->Report(diag::err_pch_langopt_value_mismatch) |
336 | 0 | << "target Objective-C runtime"; |
337 | 0 | return true; |
338 | 0 | } |
339 | | |
340 | 11.9k | if (ExistingLangOpts.CommentOpts.BlockCommandNames != |
341 | 11.9k | LangOpts.CommentOpts.BlockCommandNames) { |
342 | 0 | if (Diags) |
343 | 0 | Diags->Report(diag::err_pch_langopt_value_mismatch) |
344 | 0 | << "block command names"; |
345 | 0 | return true; |
346 | 0 | } |
347 | | |
348 | | // Sanitizer feature mismatches are treated as compatible differences. If |
349 | | // compatible differences aren't allowed, we still only want to check for |
350 | | // mismatches of non-modular sanitizers (the only ones which can affect AST |
351 | | // generation). |
352 | 11.9k | if (!AllowCompatibleDifferences) { |
353 | 10.9k | SanitizerMask ModularSanitizers = getPPTransparentSanitizers(); |
354 | 10.9k | SanitizerSet ExistingSanitizers = ExistingLangOpts.Sanitize; |
355 | 10.9k | SanitizerSet ImportedSanitizers = LangOpts.Sanitize; |
356 | 10.9k | ExistingSanitizers.clear(ModularSanitizers); |
357 | 10.9k | ImportedSanitizers.clear(ModularSanitizers); |
358 | 10.9k | if (ExistingSanitizers.Mask != ImportedSanitizers.Mask) { |
359 | 1 | const std::string Flag = "-fsanitize="; |
360 | 1 | if (Diags) { |
361 | 1 | #define SANITIZER(NAME, ID) \ |
362 | 58 | { \ |
363 | 58 | bool InExistingModule = ExistingSanitizers.has(SanitizerKind::ID); \ |
364 | 58 | bool InImportedModule = ImportedSanitizers.has(SanitizerKind::ID); \ |
365 | 58 | if (InExistingModule != InImportedModule) \ |
366 | 58 | Diags->Report(diag::err_pch_targetopt_feature_mismatch) \ |
367 | 1 | << InExistingModule << (Flag + NAME); \ |
368 | 58 | } |
369 | 1 | #include "clang/Basic/Sanitizers.def" |
370 | 1 | } |
371 | 1 | return true; |
372 | 1 | } |
373 | 10.9k | } |
374 | | |
375 | 11.9k | return false; |
376 | 11.9k | } |
377 | | |
378 | | /// Compare the given set of target options against an existing set of |
379 | | /// target options. |
380 | | /// |
381 | | /// \param Diags If non-NULL, diagnostics will be emitted via this engine. |
382 | | /// |
383 | | /// \returns true if the target options mis-match, false otherwise. |
384 | | static bool checkTargetOptions(const TargetOptions &TargetOpts, |
385 | | const TargetOptions &ExistingTargetOpts, |
386 | | DiagnosticsEngine *Diags, |
387 | 11.9k | bool AllowCompatibleDifferences = true) { |
388 | 11.9k | #define CHECK_TARGET_OPT(Field, Name) \ |
389 | 45.8k | if (TargetOpts.Field != ExistingTargetOpts.Field) { \ |
390 | 5 | if (Diags) \ |
391 | 5 | Diags->Report(diag::err_pch_targetopt_mismatch) \ |
392 | 2 | << Name << TargetOpts.Field << ExistingTargetOpts.Field; \ |
393 | 5 | return true; \ |
394 | 5 | } |
395 | | |
396 | | // The triple and ABI must match exactly. |
397 | 11.9k | CHECK_TARGET_OPT(Triple, "target"); |
398 | 11.9k | CHECK_TARGET_OPT(ABI, "target ABI"); |
399 | | |
400 | | // We can tolerate different CPUs in many cases, notably when one CPU |
401 | | // supports a strict superset of another. When allowing compatible |
402 | | // differences skip this check. |
403 | 11.9k | if (!AllowCompatibleDifferences) { |
404 | 10.9k | CHECK_TARGET_OPT(CPU, "target CPU"); |
405 | 10.9k | CHECK_TARGET_OPT(TuneCPU, "tune CPU"); |
406 | 10.9k | } |
407 | | |
408 | 11.9k | #undef CHECK_TARGET_OPT |
409 | | |
410 | | // Compare feature sets. |
411 | 11.9k | SmallVector<StringRef, 4> ExistingFeatures( |
412 | 11.9k | ExistingTargetOpts.FeaturesAsWritten.begin(), |
413 | 11.9k | ExistingTargetOpts.FeaturesAsWritten.end()); |
414 | 11.9k | SmallVector<StringRef, 4> ReadFeatures(TargetOpts.FeaturesAsWritten.begin(), |
415 | 11.9k | TargetOpts.FeaturesAsWritten.end()); |
416 | 11.9k | llvm::sort(ExistingFeatures); |
417 | 11.9k | llvm::sort(ReadFeatures); |
418 | | |
419 | | // We compute the set difference in both directions explicitly so that we can |
420 | | // diagnose the differences differently. |
421 | 11.9k | SmallVector<StringRef, 4> UnmatchedExistingFeatures, UnmatchedReadFeatures; |
422 | 11.9k | std::set_difference( |
423 | 11.9k | ExistingFeatures.begin(), ExistingFeatures.end(), ReadFeatures.begin(), |
424 | 11.9k | ReadFeatures.end(), std::back_inserter(UnmatchedExistingFeatures)); |
425 | 11.9k | std::set_difference(ReadFeatures.begin(), ReadFeatures.end(), |
426 | 11.9k | ExistingFeatures.begin(), ExistingFeatures.end(), |
427 | 11.9k | std::back_inserter(UnmatchedReadFeatures)); |
428 | | |
429 | | // If we are allowing compatible differences and the read feature set is |
430 | | // a strict subset of the existing feature set, there is nothing to diagnose. |
431 | 11.9k | if (AllowCompatibleDifferences && UnmatchedReadFeatures.empty()928 ) |
432 | 926 | return false; |
433 | | |
434 | 11.0k | if (Diags) { |
435 | 10.9k | for (StringRef Feature : UnmatchedReadFeatures) |
436 | 2 | Diags->Report(diag::err_pch_targetopt_feature_mismatch) |
437 | 2 | << /* is-existing-feature */ false << Feature; |
438 | 10.9k | for (StringRef Feature : UnmatchedExistingFeatures) |
439 | 1 | Diags->Report(diag::err_pch_targetopt_feature_mismatch) |
440 | 1 | << /* is-existing-feature */ true << Feature; |
441 | 10.9k | } |
442 | | |
443 | 11.0k | return !UnmatchedReadFeatures.empty() || !UnmatchedExistingFeatures.empty()10.9k ; |
444 | 11.9k | } |
445 | | |
446 | | bool |
447 | | PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts, |
448 | | bool Complain, |
449 | 11.9k | bool AllowCompatibleDifferences) { |
450 | 11.9k | const LangOptions &ExistingLangOpts = PP.getLangOpts(); |
451 | 11.9k | return checkLanguageOptions(LangOpts, ExistingLangOpts, |
452 | 11.9k | Complain ? &Reader.Diags11.8k : nullptr96 , |
453 | 11.9k | AllowCompatibleDifferences); |
454 | 11.9k | } |
455 | | |
456 | | bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts, |
457 | | bool Complain, |
458 | 11.9k | bool AllowCompatibleDifferences) { |
459 | 11.9k | const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts(); |
460 | 11.9k | return checkTargetOptions(TargetOpts, ExistingTargetOpts, |
461 | 11.9k | Complain ? &Reader.Diags11.8k : nullptr96 , |
462 | 11.9k | AllowCompatibleDifferences); |
463 | 11.9k | } |
464 | | |
465 | | namespace { |
466 | | |
467 | | using MacroDefinitionsMap = |
468 | | llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>; |
469 | | using DeclsMap = llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8>>; |
470 | | |
471 | | } // namespace |
472 | | |
473 | | static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags, |
474 | | DiagnosticsEngine &Diags, |
475 | 2.02k | bool Complain) { |
476 | 2.02k | using Level = DiagnosticsEngine::Level; |
477 | | |
478 | | // Check current mappings for new -Werror mappings, and the stored mappings |
479 | | // for cases that were explicitly mapped to *not* be errors that are now |
480 | | // errors because of options like -Werror. |
481 | 2.02k | DiagnosticsEngine *MappingSources[] = { &Diags, &StoredDiags }; |
482 | | |
483 | 4.04k | for (DiagnosticsEngine *MappingSource : MappingSources) { |
484 | 39.4k | for (auto DiagIDMappingPair : MappingSource->getDiagnosticMappings()) { |
485 | 39.4k | diag::kind DiagID = DiagIDMappingPair.first; |
486 | 39.4k | Level CurLevel = Diags.getDiagnosticLevel(DiagID, SourceLocation()); |
487 | 39.4k | if (CurLevel < DiagnosticsEngine::Error) |
488 | 36.9k | continue; // not significant |
489 | 2.47k | Level StoredLevel = |
490 | 2.47k | StoredDiags.getDiagnosticLevel(DiagID, SourceLocation()); |
491 | 2.47k | if (StoredLevel < DiagnosticsEngine::Error) { |
492 | 5 | if (Complain) |
493 | 0 | Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror=" + |
494 | 0 | Diags.getDiagnosticIDs()->getWarningOptionForDiag(DiagID).str(); |
495 | 5 | return true; |
496 | 5 | } |
497 | 2.47k | } |
498 | 4.04k | } |
499 | | |
500 | 2.02k | return false; |
501 | 2.02k | } |
502 | | |
503 | 2.03k | static bool isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) { |
504 | 2.03k | diag::Severity Ext = Diags.getExtensionHandlingBehavior(); |
505 | 2.03k | if (Ext == diag::Severity::Warning && Diags.getWarningsAsErrors()5 ) |
506 | 5 | return true; |
507 | 2.02k | return Ext >= diag::Severity::Error; |
508 | 2.03k | } |
509 | | |
510 | | static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags, |
511 | | DiagnosticsEngine &Diags, bool IsSystem, |
512 | | bool SystemHeaderWarningsInModule, |
513 | 7.42k | bool Complain) { |
514 | | // Top-level options |
515 | 7.42k | if (IsSystem) { |
516 | 5.38k | if (Diags.getSuppressSystemWarnings()) |
517 | 5.38k | return false; |
518 | | // If -Wsystem-headers was not enabled before, and it was not explicit, |
519 | | // be conservative |
520 | 6 | if (StoredDiags.getSuppressSystemWarnings() && |
521 | 6 | !SystemHeaderWarningsInModule4 ) { |
522 | 2 | if (Complain) |
523 | 0 | Diags.Report(diag::err_pch_diagopt_mismatch) << "-Wsystem-headers"; |
524 | 2 | return true; |
525 | 2 | } |
526 | 6 | } |
527 | | |
528 | 2.03k | if (Diags.getWarningsAsErrors() && !StoredDiags.getWarningsAsErrors()54 ) { |
529 | 5 | if (Complain) |
530 | 0 | Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror"; |
531 | 5 | return true; |
532 | 5 | } |
533 | | |
534 | 2.03k | if (Diags.getWarningsAsErrors() && Diags.getEnableAllWarnings()49 && |
535 | 2.03k | !StoredDiags.getEnableAllWarnings()0 ) { |
536 | 0 | if (Complain) |
537 | 0 | Diags.Report(diag::err_pch_diagopt_mismatch) << "-Weverything -Werror"; |
538 | 0 | return true; |
539 | 0 | } |
540 | | |
541 | 2.03k | if (isExtHandlingFromDiagsError(Diags) && |
542 | 2.03k | !isExtHandlingFromDiagsError(StoredDiags)4 ) { |
543 | 1 | if (Complain) |
544 | 0 | Diags.Report(diag::err_pch_diagopt_mismatch) << "-pedantic-errors"; |
545 | 1 | return true; |
546 | 1 | } |
547 | | |
548 | 2.03k | return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain); |
549 | 2.03k | } |
550 | | |
551 | | /// Return the top import module if it is implicit, nullptr otherwise. |
552 | | static Module *getTopImportImplicitModule(ModuleManager &ModuleMgr, |
553 | 11.0k | Preprocessor &PP) { |
554 | | // If the original import came from a file explicitly generated by the user, |
555 | | // don't check the diagnostic mappings. |
556 | | // FIXME: currently this is approximated by checking whether this is not a |
557 | | // module import of an implicitly-loaded module file. |
558 | | // Note: ModuleMgr.rbegin() may not be the current module, but it must be in |
559 | | // the transitive closure of its imports, since unrelated modules cannot be |
560 | | // imported until after this module finishes validation. |
561 | 11.0k | ModuleFile *TopImport = &*ModuleMgr.rbegin(); |
562 | 11.0k | while (!TopImport->ImportedBy.empty()) |
563 | 0 | TopImport = TopImport->ImportedBy[0]; |
564 | 11.0k | if (TopImport->Kind != MK_ImplicitModule) |
565 | 3.59k | return nullptr; |
566 | | |
567 | 7.41k | StringRef ModuleName = TopImport->ModuleName; |
568 | 7.41k | assert(!ModuleName.empty() && "diagnostic options read before module name"); |
569 | | |
570 | 7.41k | Module *M = |
571 | 7.41k | PP.getHeaderSearchInfo().lookupModule(ModuleName, TopImport->ImportLoc); |
572 | 7.41k | assert(M && "missing module"); |
573 | 7.41k | return M; |
574 | 7.41k | } |
575 | | |
576 | | bool PCHValidator::ReadDiagnosticOptions( |
577 | 11.0k | IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) { |
578 | 11.0k | DiagnosticsEngine &ExistingDiags = PP.getDiagnostics(); |
579 | 11.0k | IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs()); |
580 | 11.0k | IntrusiveRefCntPtr<DiagnosticsEngine> Diags( |
581 | 11.0k | new DiagnosticsEngine(DiagIDs, DiagOpts.get())); |
582 | | // This should never fail, because we would have processed these options |
583 | | // before writing them to an ASTFile. |
584 | 11.0k | ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false); |
585 | | |
586 | 11.0k | ModuleManager &ModuleMgr = Reader.getModuleManager(); |
587 | 11.0k | assert(ModuleMgr.size() >= 1 && "what ASTFile is this then"); |
588 | | |
589 | 11.0k | Module *TopM = getTopImportImplicitModule(ModuleMgr, PP); |
590 | 11.0k | if (!TopM) |
591 | 3.59k | return false; |
592 | | |
593 | 7.42k | Module *Importer = PP.getCurrentModule(); |
594 | | |
595 | 7.42k | DiagnosticOptions &ExistingOpts = ExistingDiags.getDiagnosticOptions(); |
596 | 7.42k | bool SystemHeaderWarningsInModule = |
597 | 7.42k | Importer && llvm::is_contained(ExistingOpts.SystemHeaderWarningsModules, |
598 | 5.53k | Importer->Name); |
599 | | |
600 | | // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that |
601 | | // contains the union of their flags. |
602 | 7.42k | return checkDiagnosticMappings(*Diags, ExistingDiags, TopM->IsSystem, |
603 | 7.42k | SystemHeaderWarningsInModule, Complain); |
604 | 11.0k | } |
605 | | |
606 | | /// Collect the macro definitions provided by the given preprocessor |
607 | | /// options. |
608 | | static void |
609 | | collectMacroDefinitions(const PreprocessorOptions &PPOpts, |
610 | | MacroDefinitionsMap &Macros, |
611 | 8.51k | SmallVectorImpl<StringRef> *MacroNames = nullptr) { |
612 | 12.2k | for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I3.76k ) { |
613 | 3.76k | StringRef Macro = PPOpts.Macros[I].first; |
614 | 3.76k | bool IsUndef = PPOpts.Macros[I].second; |
615 | | |
616 | 3.76k | std::pair<StringRef, StringRef> MacroPair = Macro.split('='); |
617 | 3.76k | StringRef MacroName = MacroPair.first; |
618 | 3.76k | StringRef MacroBody = MacroPair.second; |
619 | | |
620 | | // For an #undef'd macro, we only care about the name. |
621 | 3.76k | if (IsUndef) { |
622 | 4 | if (MacroNames && !Macros.count(MacroName)) |
623 | 4 | MacroNames->push_back(MacroName); |
624 | | |
625 | 4 | Macros[MacroName] = std::make_pair("", true); |
626 | 4 | continue; |
627 | 4 | } |
628 | | |
629 | | // For a #define'd macro, figure out the actual definition. |
630 | 3.75k | if (MacroName.size() == Macro.size()) |
631 | 2.61k | MacroBody = "1"; |
632 | 1.13k | else { |
633 | | // Note: GCC drops anything following an end-of-line character. |
634 | 1.13k | StringRef::size_type End = MacroBody.find_first_of("\n\r"); |
635 | 1.13k | MacroBody = MacroBody.substr(0, End); |
636 | 1.13k | } |
637 | | |
638 | 3.75k | if (MacroNames && !Macros.count(MacroName)1.58k ) |
639 | 1.58k | MacroNames->push_back(MacroName); |
640 | 3.75k | Macros[MacroName] = std::make_pair(MacroBody, false); |
641 | 3.75k | } |
642 | 8.51k | } |
643 | | |
644 | | enum OptionValidation { |
645 | | OptionValidateNone, |
646 | | OptionValidateContradictions, |
647 | | OptionValidateStrictMatches, |
648 | | }; |
649 | | |
650 | | /// Check the preprocessor options deserialized from the control block |
651 | | /// against the preprocessor options in an existing preprocessor. |
652 | | /// |
653 | | /// \param Diags If non-null, produce diagnostics for any mismatches incurred. |
654 | | /// \param Validation If set to OptionValidateNone, ignore differences in |
655 | | /// preprocessor options. If set to OptionValidateContradictions, |
656 | | /// require that options passed both in the AST file and on the command |
657 | | /// line (-D or -U) match, but tolerate options missing in one or the |
658 | | /// other. If set to OptionValidateContradictions, require that there |
659 | | /// are no differences in the options between the two. |
660 | | static bool checkPreprocessorOptions( |
661 | | const PreprocessorOptions &PPOpts, |
662 | | const PreprocessorOptions &ExistingPPOpts, bool ReadMacros, |
663 | | DiagnosticsEngine *Diags, FileManager &FileMgr, |
664 | | std::string &SuggestedPredefines, const LangOptions &LangOpts, |
665 | 11.4k | OptionValidation Validation = OptionValidateContradictions) { |
666 | 11.4k | if (ReadMacros) { |
667 | | // Check macro definitions. |
668 | 4.25k | MacroDefinitionsMap ASTFileMacros; |
669 | 4.25k | collectMacroDefinitions(PPOpts, ASTFileMacros); |
670 | 4.25k | MacroDefinitionsMap ExistingMacros; |
671 | 4.25k | SmallVector<StringRef, 4> ExistingMacroNames; |
672 | 4.25k | collectMacroDefinitions(ExistingPPOpts, ExistingMacros, |
673 | 4.25k | &ExistingMacroNames); |
674 | | |
675 | | // Use a line marker to enter the <command line> file, as the defines and |
676 | | // undefines here will have come from the command line. |
677 | 4.25k | SuggestedPredefines += "# 1 \"<command line>\" 1\n"; |
678 | | |
679 | 5.82k | for (unsigned I = 0, N = ExistingMacroNames.size(); I != N; ++I1.56k ) { |
680 | | // Dig out the macro definition in the existing preprocessor options. |
681 | 1.57k | StringRef MacroName = ExistingMacroNames[I]; |
682 | 1.57k | std::pair<StringRef, bool> Existing = ExistingMacros[MacroName]; |
683 | | |
684 | | // Check whether we know anything about this macro name or not. |
685 | 1.57k | llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>::iterator Known = |
686 | 1.57k | ASTFileMacros.find(MacroName); |
687 | 1.57k | if (Validation == OptionValidateNone || Known == ASTFileMacros.end()1.24k ) { |
688 | 406 | if (Validation == OptionValidateStrictMatches) { |
689 | | // If strict matches are requested, don't tolerate any extra defines |
690 | | // on the command line that are missing in the AST file. |
691 | 3 | if (Diags) { |
692 | 0 | Diags->Report(diag::err_pch_macro_def_undef) << MacroName << true; |
693 | 0 | } |
694 | 3 | return true; |
695 | 3 | } |
696 | | // FIXME: Check whether this identifier was referenced anywhere in the |
697 | | // AST file. If so, we should reject the AST file. Unfortunately, this |
698 | | // information isn't in the control block. What shall we do about it? |
699 | | |
700 | 403 | if (Existing.second) { |
701 | 2 | SuggestedPredefines += "#undef "; |
702 | 2 | SuggestedPredefines += MacroName.str(); |
703 | 2 | SuggestedPredefines += '\n'; |
704 | 401 | } else { |
705 | 401 | SuggestedPredefines += "#define "; |
706 | 401 | SuggestedPredefines += MacroName.str(); |
707 | 401 | SuggestedPredefines += ' '; |
708 | 401 | SuggestedPredefines += Existing.first.str(); |
709 | 401 | SuggestedPredefines += '\n'; |
710 | 401 | } |
711 | 403 | continue; |
712 | 406 | } |
713 | | |
714 | | // If the macro was defined in one but undef'd in the other, we have a |
715 | | // conflict. |
716 | 1.17k | if (Existing.second != Known->second.second) { |
717 | 2 | if (Diags) { |
718 | 2 | Diags->Report(diag::err_pch_macro_def_undef) |
719 | 2 | << MacroName << Known->second.second; |
720 | 2 | } |
721 | 2 | return true; |
722 | 2 | } |
723 | | |
724 | | // If the macro was #undef'd in both, or if the macro bodies are |
725 | | // identical, it's fine. |
726 | 1.17k | if (Existing.second || Existing.first == Known->second.first) { |
727 | 1.16k | ASTFileMacros.erase(Known); |
728 | 1.16k | continue; |
729 | 1.16k | } |
730 | | |
731 | | // The macro bodies differ; complain. |
732 | 7 | if (Diags) { |
733 | 3 | Diags->Report(diag::err_pch_macro_def_conflict) |
734 | 3 | << MacroName << Known->second.first << Existing.first; |
735 | 3 | } |
736 | 7 | return true; |
737 | 1.17k | } |
738 | | |
739 | | // Leave the <command line> file and return to <built-in>. |
740 | 4.24k | SuggestedPredefines += "# 1 \"<built-in>\" 2\n"; |
741 | | |
742 | 4.24k | if (Validation == OptionValidateStrictMatches) { |
743 | | // If strict matches are requested, don't tolerate any extra defines in |
744 | | // the AST file that are missing on the command line. |
745 | 11 | for (const auto &MacroName : ASTFileMacros.keys()) { |
746 | 6 | if (Diags) { |
747 | 0 | Diags->Report(diag::err_pch_macro_def_undef) << MacroName << false; |
748 | 0 | } |
749 | 6 | return true; |
750 | 6 | } |
751 | 11 | } |
752 | 4.24k | } |
753 | | |
754 | | // Check whether we're using predefines. |
755 | 11.4k | if (PPOpts.UsePredefines != ExistingPPOpts.UsePredefines && |
756 | 11.4k | Validation != OptionValidateNone348 ) { |
757 | 1 | if (Diags) { |
758 | 1 | Diags->Report(diag::err_pch_undef) << ExistingPPOpts.UsePredefines; |
759 | 1 | } |
760 | 1 | return true; |
761 | 1 | } |
762 | | |
763 | | // Detailed record is important since it is used for the module cache hash. |
764 | 11.4k | if (LangOpts.Modules && |
765 | 11.4k | PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord7.52k && |
766 | 11.4k | Validation != OptionValidateNone0 ) { |
767 | 0 | if (Diags) { |
768 | 0 | Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord; |
769 | 0 | } |
770 | 0 | return true; |
771 | 0 | } |
772 | | |
773 | | // Compute the #include and #include_macros lines we need. |
774 | 11.4k | for (unsigned I = 0, N = ExistingPPOpts.Includes.size(); 11.4k I != N; ++I85 ) { |
775 | 85 | StringRef File = ExistingPPOpts.Includes[I]; |
776 | | |
777 | 85 | if (!ExistingPPOpts.ImplicitPCHInclude.empty() && |
778 | 85 | !ExistingPPOpts.PCHThroughHeader.empty()19 ) { |
779 | | // In case the through header is an include, we must add all the includes |
780 | | // to the predefines so the start point can be determined. |
781 | 13 | SuggestedPredefines += "#include \""; |
782 | 13 | SuggestedPredefines += File; |
783 | 13 | SuggestedPredefines += "\"\n"; |
784 | 13 | continue; |
785 | 13 | } |
786 | | |
787 | 72 | if (File == ExistingPPOpts.ImplicitPCHInclude) |
788 | 0 | continue; |
789 | | |
790 | 72 | if (llvm::is_contained(PPOpts.Includes, File)) |
791 | 4 | continue; |
792 | | |
793 | 68 | SuggestedPredefines += "#include \""; |
794 | 68 | SuggestedPredefines += File; |
795 | 68 | SuggestedPredefines += "\"\n"; |
796 | 68 | } |
797 | | |
798 | 11.4k | for (unsigned I = 0, N = ExistingPPOpts.MacroIncludes.size(); I != N; ++I0 ) { |
799 | 0 | StringRef File = ExistingPPOpts.MacroIncludes[I]; |
800 | 0 | if (llvm::is_contained(PPOpts.MacroIncludes, File)) |
801 | 0 | continue; |
802 | | |
803 | 0 | SuggestedPredefines += "#__include_macros \""; |
804 | 0 | SuggestedPredefines += File; |
805 | 0 | SuggestedPredefines += "\"\n##\n"; |
806 | 0 | } |
807 | | |
808 | 11.4k | return false; |
809 | 11.4k | } |
810 | | |
811 | | bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, |
812 | | bool ReadMacros, bool Complain, |
813 | 10.9k | std::string &SuggestedPredefines) { |
814 | 10.9k | const PreprocessorOptions &ExistingPPOpts = PP.getPreprocessorOpts(); |
815 | | |
816 | 10.9k | return checkPreprocessorOptions( |
817 | 10.9k | PPOpts, ExistingPPOpts, ReadMacros, Complain ? &Reader.Diags10.9k : nullptr6 , |
818 | 10.9k | PP.getFileManager(), SuggestedPredefines, PP.getLangOpts()); |
819 | 10.9k | } |
820 | | |
821 | | bool SimpleASTReaderListener::ReadPreprocessorOptions( |
822 | | const PreprocessorOptions &PPOpts, bool ReadMacros, bool Complain, |
823 | 417 | std::string &SuggestedPredefines) { |
824 | 417 | return checkPreprocessorOptions(PPOpts, PP.getPreprocessorOpts(), ReadMacros, |
825 | 417 | nullptr, PP.getFileManager(), |
826 | 417 | SuggestedPredefines, PP.getLangOpts(), |
827 | 417 | OptionValidateNone); |
828 | 417 | } |
829 | | |
830 | | /// Check the header search options deserialized from the control block |
831 | | /// against the header search options in an existing preprocessor. |
832 | | /// |
833 | | /// \param Diags If non-null, produce diagnostics for any mismatches incurred. |
834 | | static bool checkHeaderSearchOptions(const HeaderSearchOptions &HSOpts, |
835 | | StringRef SpecificModuleCachePath, |
836 | | StringRef ExistingModuleCachePath, |
837 | | DiagnosticsEngine *Diags, |
838 | | const LangOptions &LangOpts, |
839 | 11.0k | const PreprocessorOptions &PPOpts) { |
840 | 11.0k | if (LangOpts.Modules) { |
841 | 7.49k | if (SpecificModuleCachePath != ExistingModuleCachePath && |
842 | 7.49k | !PPOpts.AllowPCHWithDifferentModulesCachePath12 ) { |
843 | 3 | if (Diags) |
844 | 3 | Diags->Report(diag::err_pch_modulecache_mismatch) |
845 | 3 | << SpecificModuleCachePath << ExistingModuleCachePath; |
846 | 3 | return true; |
847 | 3 | } |
848 | 7.49k | } |
849 | | |
850 | 11.0k | return false; |
851 | 11.0k | } |
852 | | |
853 | | bool PCHValidator::ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, |
854 | | StringRef SpecificModuleCachePath, |
855 | 10.9k | bool Complain) { |
856 | 10.9k | return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath, |
857 | 10.9k | PP.getHeaderSearchInfo().getModuleCachePath(), |
858 | 10.9k | Complain ? &Reader.Diags10.9k : nullptr6 , |
859 | 10.9k | PP.getLangOpts(), PP.getPreprocessorOpts()); |
860 | 10.9k | } |
861 | | |
862 | 5 | void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) { |
863 | 5 | PP.setCounterValue(Value); |
864 | 5 | } |
865 | | |
866 | | //===----------------------------------------------------------------------===// |
867 | | // AST reader implementation |
868 | | //===----------------------------------------------------------------------===// |
869 | | |
870 | 702M | static uint64_t readULEB(const unsigned char *&P) { |
871 | 702M | unsigned Length = 0; |
872 | 702M | const char *Error = nullptr; |
873 | | |
874 | 702M | uint64_t Val = llvm::decodeULEB128(P, &Length, nullptr, &Error); |
875 | 702M | if (Error) |
876 | 0 | llvm::report_fatal_error(Error); |
877 | 702M | P += Length; |
878 | 702M | return Val; |
879 | 702M | } |
880 | | |
881 | | /// Read ULEB-encoded key length and data length. |
882 | | static std::pair<unsigned, unsigned> |
883 | 351M | readULEBKeyDataLength(const unsigned char *&P) { |
884 | 351M | unsigned KeyLen = readULEB(P); |
885 | 351M | if ((unsigned)KeyLen != KeyLen) |
886 | 0 | llvm::report_fatal_error("key too large"); |
887 | | |
888 | 351M | unsigned DataLen = readULEB(P); |
889 | 351M | if ((unsigned)DataLen != DataLen) |
890 | 0 | llvm::report_fatal_error("data too large"); |
891 | | |
892 | 351M | return std::make_pair(KeyLen, DataLen); |
893 | 351M | } |
894 | | |
895 | | void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener, |
896 | 15.0k | bool TakeOwnership) { |
897 | 15.0k | DeserializationListener = Listener; |
898 | 15.0k | OwnsDeserializationListener = TakeOwnership; |
899 | 15.0k | } |
900 | | |
901 | 247k | unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) { |
902 | 247k | return serialization::ComputeHash(Sel); |
903 | 247k | } |
904 | | |
905 | | std::pair<unsigned, unsigned> |
906 | 162k | ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) { |
907 | 162k | return readULEBKeyDataLength(d); |
908 | 162k | } |
909 | | |
910 | | ASTSelectorLookupTrait::internal_key_type |
911 | 6.16k | ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) { |
912 | 6.16k | using namespace llvm::support; |
913 | | |
914 | 6.16k | SelectorTable &SelTable = Reader.getContext().Selectors; |
915 | 6.16k | unsigned N = endian::readNext<uint16_t, little, unaligned>(d); |
916 | 6.16k | IdentifierInfo *FirstII = Reader.getLocalIdentifier( |
917 | 6.16k | F, endian::readNext<uint32_t, little, unaligned>(d)); |
918 | 6.16k | if (N == 0) |
919 | 3.11k | return SelTable.getNullarySelector(FirstII); |
920 | 3.05k | else if (N == 1) |
921 | 2.69k | return SelTable.getUnarySelector(FirstII); |
922 | | |
923 | 364 | SmallVector<IdentifierInfo *, 16> Args; |
924 | 364 | Args.push_back(FirstII); |
925 | 924 | for (unsigned I = 1; I != N; ++I560 ) |
926 | 560 | Args.push_back(Reader.getLocalIdentifier( |
927 | 560 | F, endian::readNext<uint32_t, little, unaligned>(d))); |
928 | | |
929 | 364 | return SelTable.getSelector(N, Args.data()); |
930 | 6.16k | } |
931 | | |
932 | | ASTSelectorLookupTrait::data_type |
933 | | ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, |
934 | 1.86k | unsigned DataLen) { |
935 | 1.86k | using namespace llvm::support; |
936 | | |
937 | 1.86k | data_type Result; |
938 | | |
939 | 1.86k | Result.ID = Reader.getGlobalSelectorID( |
940 | 1.86k | F, endian::readNext<uint32_t, little, unaligned>(d)); |
941 | 1.86k | unsigned FullInstanceBits = endian::readNext<uint16_t, little, unaligned>(d); |
942 | 1.86k | unsigned FullFactoryBits = endian::readNext<uint16_t, little, unaligned>(d); |
943 | 1.86k | Result.InstanceBits = FullInstanceBits & 0x3; |
944 | 1.86k | Result.InstanceHasMoreThanOneDecl = (FullInstanceBits >> 2) & 0x1; |
945 | 1.86k | Result.FactoryBits = FullFactoryBits & 0x3; |
946 | 1.86k | Result.FactoryHasMoreThanOneDecl = (FullFactoryBits >> 2) & 0x1; |
947 | 1.86k | unsigned NumInstanceMethods = FullInstanceBits >> 3; |
948 | 1.86k | unsigned NumFactoryMethods = FullFactoryBits >> 3; |
949 | | |
950 | | // Load instance methods |
951 | 6.72k | for (unsigned I = 0; I != NumInstanceMethods; ++I4.85k ) { |
952 | 4.85k | if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>( |
953 | 4.85k | F, endian::readNext<uint32_t, little, unaligned>(d))) |
954 | 4.85k | Result.Instance.push_back(Method); |
955 | 4.85k | } |
956 | | |
957 | | // Load factory methods |
958 | 2.13k | for (unsigned I = 0; I != NumFactoryMethods; ++I265 ) { |
959 | 265 | if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>( |
960 | 265 | F, endian::readNext<uint32_t, little, unaligned>(d))) |
961 | 265 | Result.Factory.push_back(Method); |
962 | 265 | } |
963 | | |
964 | 1.86k | return Result; |
965 | 1.86k | } |
966 | | |
967 | 5.32M | unsigned ASTIdentifierLookupTraitBase::ComputeHash(const internal_key_type& a) { |
968 | 5.32M | return llvm::djbHash(a); |
969 | 5.32M | } |
970 | | |
971 | | std::pair<unsigned, unsigned> |
972 | 63.9M | ASTIdentifierLookupTraitBase::ReadKeyDataLength(const unsigned char*& d) { |
973 | 63.9M | return readULEBKeyDataLength(d); |
974 | 63.9M | } |
975 | | |
976 | | ASTIdentifierLookupTraitBase::internal_key_type |
977 | 59.2M | ASTIdentifierLookupTraitBase::ReadKey(const unsigned char* d, unsigned n) { |
978 | 59.2M | assert(n >= 2 && d[n-1] == '\0'); |
979 | 59.2M | return StringRef((const char*) d, n-1); |
980 | 59.2M | } |
981 | | |
982 | | /// Whether the given identifier is "interesting". |
983 | | static bool isInterestingIdentifier(ASTReader &Reader, IdentifierInfo &II, |
984 | 14.4M | bool IsModule) { |
985 | 14.4M | return II.hadMacroDefinition() || II.isPoisoned()14.3M || |
986 | 14.4M | (14.3M !IsModule14.3M && II.getObjCOrBuiltinID()5.76M ) || |
987 | 14.4M | II.hasRevertedTokenIDToIdentifier()14.2M || |
988 | 14.4M | (14.2M !(14.2M IsModule14.2M && Reader.getPreprocessor().getLangOpts().CPlusPlus8.55M ) && |
989 | 14.2M | II.getFETokenInfo()5.79M ); |
990 | 14.4M | } |
991 | | |
992 | 8.84M | static bool readBit(unsigned &Bits) { |
993 | 8.84M | bool Value = Bits & 0x1; |
994 | 8.84M | Bits >>= 1; |
995 | 8.84M | return Value; |
996 | 8.84M | } |
997 | | |
998 | 50.9M | IdentID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) { |
999 | 50.9M | using namespace llvm::support; |
1000 | | |
1001 | 50.9M | unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d); |
1002 | 50.9M | return Reader.getGlobalIdentifierID(F, RawID >> 1); |
1003 | 50.9M | } |
1004 | | |
1005 | 56.4M | static void markIdentifierFromAST(ASTReader &Reader, IdentifierInfo &II) { |
1006 | 56.4M | if (!II.isFromAST()) { |
1007 | 14.4M | II.setIsFromAST(); |
1008 | 14.4M | bool IsModule = Reader.getPreprocessor().getCurrentModule() != nullptr; |
1009 | 14.4M | if (isInterestingIdentifier(Reader, II, IsModule)) |
1010 | 133k | II.setChangedSinceDeserialization(); |
1011 | 14.4M | } |
1012 | 56.4M | } |
1013 | | |
1014 | | IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, |
1015 | | const unsigned char* d, |
1016 | 1.84M | unsigned DataLen) { |
1017 | 1.84M | using namespace llvm::support; |
1018 | | |
1019 | 1.84M | unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d); |
1020 | 1.84M | bool IsInteresting = RawID & 0x01; |
1021 | | |
1022 | | // Wipe out the "is interesting" bit. |
1023 | 1.84M | RawID = RawID >> 1; |
1024 | | |
1025 | | // Build the IdentifierInfo and link the identifier ID with it. |
1026 | 1.84M | IdentifierInfo *II = KnownII; |
1027 | 1.84M | if (!II) { |
1028 | 1.12M | II = &Reader.getIdentifierTable().getOwn(k); |
1029 | 1.12M | KnownII = II; |
1030 | 1.12M | } |
1031 | 1.84M | markIdentifierFromAST(Reader, *II); |
1032 | 1.84M | Reader.markIdentifierUpToDate(II); |
1033 | | |
1034 | 1.84M | IdentID ID = Reader.getGlobalIdentifierID(F, RawID); |
1035 | 1.84M | if (!IsInteresting) { |
1036 | | // For uninteresting identifiers, there's nothing else to do. Just notify |
1037 | | // the reader that we've finished loading this identifier. |
1038 | 75.8k | Reader.SetIdentifierInfo(ID, II); |
1039 | 75.8k | return II; |
1040 | 75.8k | } |
1041 | | |
1042 | 1.76M | unsigned ObjCOrBuiltinID = endian::readNext<uint16_t, little, unaligned>(d); |
1043 | 1.76M | unsigned Bits = endian::readNext<uint16_t, little, unaligned>(d); |
1044 | 1.76M | bool CPlusPlusOperatorKeyword = readBit(Bits); |
1045 | 1.76M | bool HasRevertedTokenIDToIdentifier = readBit(Bits); |
1046 | 1.76M | bool Poisoned = readBit(Bits); |
1047 | 1.76M | bool ExtensionToken = readBit(Bits); |
1048 | 1.76M | bool HadMacroDefinition = readBit(Bits); |
1049 | | |
1050 | 1.76M | assert(Bits == 0 && "Extra bits in the identifier?"); |
1051 | 1.76M | DataLen -= 8; |
1052 | | |
1053 | | // Set or check the various bits in the IdentifierInfo structure. |
1054 | | // Token IDs are read-only. |
1055 | 1.76M | if (HasRevertedTokenIDToIdentifier && II->getTokenID() != tok::identifier51 ) |
1056 | 51 | II->revertTokenIDToIdentifier(); |
1057 | 1.76M | if (!F.isModule()) |
1058 | 687k | II->setObjCOrBuiltinID(ObjCOrBuiltinID); |
1059 | 1.76M | assert(II->isExtensionToken() == ExtensionToken && |
1060 | 1.76M | "Incorrect extension token flag"); |
1061 | 1.76M | (void)ExtensionToken; |
1062 | 1.76M | if (Poisoned) |
1063 | 1.31k | II->setIsPoisoned(true); |
1064 | 1.76M | assert(II->isCPlusPlusOperatorKeyword() == CPlusPlusOperatorKeyword && |
1065 | 1.76M | "Incorrect C++ operator keyword flag"); |
1066 | 1.76M | (void)CPlusPlusOperatorKeyword; |
1067 | | |
1068 | | // If this identifier is a macro, deserialize the macro |
1069 | | // definition. |
1070 | 1.76M | if (HadMacroDefinition) { |
1071 | 1.11M | uint32_t MacroDirectivesOffset = |
1072 | 1.11M | endian::readNext<uint32_t, little, unaligned>(d); |
1073 | 1.11M | DataLen -= 4; |
1074 | | |
1075 | 1.11M | Reader.addPendingMacro(II, &F, MacroDirectivesOffset); |
1076 | 1.11M | } |
1077 | | |
1078 | 1.76M | Reader.SetIdentifierInfo(ID, II); |
1079 | | |
1080 | | // Read all of the declarations visible at global scope with this |
1081 | | // name. |
1082 | 1.76M | if (DataLen > 0) { |
1083 | 58.4k | SmallVector<uint32_t, 4> DeclIDs; |
1084 | 117k | for (; DataLen > 0; DataLen -= 459.5k ) |
1085 | 59.5k | DeclIDs.push_back(Reader.getGlobalDeclID( |
1086 | 59.5k | F, endian::readNext<uint32_t, little, unaligned>(d))); |
1087 | 58.4k | Reader.SetGloballyVisibleDecls(II, DeclIDs); |
1088 | 58.4k | } |
1089 | | |
1090 | 1.76M | return II; |
1091 | 1.76M | } |
1092 | | |
1093 | | DeclarationNameKey::DeclarationNameKey(DeclarationName Name) |
1094 | 1.36M | : Kind(Name.getNameKind()) { |
1095 | 1.36M | switch (Kind) { |
1096 | 962k | case DeclarationName::Identifier: |
1097 | 962k | Data = (uint64_t)Name.getAsIdentifierInfo(); |
1098 | 962k | break; |
1099 | 200k | case DeclarationName::ObjCZeroArgSelector: |
1100 | 328k | case DeclarationName::ObjCOneArgSelector: |
1101 | 343k | case DeclarationName::ObjCMultiArgSelector: |
1102 | 343k | Data = (uint64_t)Name.getObjCSelector().getAsOpaquePtr(); |
1103 | 343k | break; |
1104 | 21.2k | case DeclarationName::CXXOperatorName: |
1105 | 21.2k | Data = Name.getCXXOverloadedOperator(); |
1106 | 21.2k | break; |
1107 | 55 | case DeclarationName::CXXLiteralOperatorName: |
1108 | 55 | Data = (uint64_t)Name.getCXXLiteralIdentifier(); |
1109 | 55 | break; |
1110 | 127 | case DeclarationName::CXXDeductionGuideName: |
1111 | 127 | Data = (uint64_t)Name.getCXXDeductionGuideTemplate() |
1112 | 127 | ->getDeclName().getAsIdentifierInfo(); |
1113 | 127 | break; |
1114 | 17.7k | case DeclarationName::CXXConstructorName: |
1115 | 30.9k | case DeclarationName::CXXDestructorName: |
1116 | 32.8k | case DeclarationName::CXXConversionFunctionName: |
1117 | 37.6k | case DeclarationName::CXXUsingDirective: |
1118 | 37.6k | Data = 0; |
1119 | 37.6k | break; |
1120 | 1.36M | } |
1121 | 1.36M | } |
1122 | | |
1123 | 29.6M | unsigned DeclarationNameKey::getHash() const { |
1124 | 29.6M | llvm::FoldingSetNodeID ID; |
1125 | 29.6M | ID.AddInteger(Kind); |
1126 | | |
1127 | 29.6M | switch (Kind) { |
1128 | 29.1M | case DeclarationName::Identifier: |
1129 | 29.1M | case DeclarationName::CXXLiteralOperatorName: |
1130 | 29.1M | case DeclarationName::CXXDeductionGuideName: |
1131 | 29.1M | ID.AddString(((IdentifierInfo*)Data)->getName()); |
1132 | 29.1M | break; |
1133 | 200k | case DeclarationName::ObjCZeroArgSelector: |
1134 | 328k | case DeclarationName::ObjCOneArgSelector: |
1135 | 343k | case DeclarationName::ObjCMultiArgSelector: |
1136 | 343k | ID.AddInteger(serialization::ComputeHash(Selector(Data))); |
1137 | 343k | break; |
1138 | 161k | case DeclarationName::CXXOperatorName: |
1139 | 161k | ID.AddInteger((OverloadedOperatorKind)Data); |
1140 | 161k | break; |
1141 | 22.7k | case DeclarationName::CXXConstructorName: |
1142 | 41.2k | case DeclarationName::CXXDestructorName: |
1143 | 48.8k | case DeclarationName::CXXConversionFunctionName: |
1144 | 65.1k | case DeclarationName::CXXUsingDirective: |
1145 | 65.1k | break; |
1146 | 29.6M | } |
1147 | | |
1148 | 29.6M | return ID.ComputeHash(); |
1149 | 29.6M | } |
1150 | | |
1151 | | ModuleFile * |
1152 | 4.05M | ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) { |
1153 | 4.05M | using namespace llvm::support; |
1154 | | |
1155 | 4.05M | uint32_t ModuleFileID = endian::readNext<uint32_t, little, unaligned>(d); |
1156 | 4.05M | return Reader.getLocalModuleFile(F, ModuleFileID); |
1157 | 4.05M | } |
1158 | | |
1159 | | std::pair<unsigned, unsigned> |
1160 | 40.6M | ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char *&d) { |
1161 | 40.6M | return readULEBKeyDataLength(d); |
1162 | 40.6M | } |
1163 | | |
1164 | | ASTDeclContextNameLookupTrait::internal_key_type |
1165 | 20.1M | ASTDeclContextNameLookupTrait::ReadKey(const unsigned char *d, unsigned) { |
1166 | 20.1M | using namespace llvm::support; |
1167 | | |
1168 | 20.1M | auto Kind = (DeclarationName::NameKind)*d++; |
1169 | 20.1M | uint64_t Data; |
1170 | 20.1M | switch (Kind) { |
1171 | 19.9M | case DeclarationName::Identifier: |
1172 | 19.9M | case DeclarationName::CXXLiteralOperatorName: |
1173 | 19.9M | case DeclarationName::CXXDeductionGuideName: |
1174 | 19.9M | Data = (uint64_t)Reader.getLocalIdentifier( |
1175 | 19.9M | F, endian::readNext<uint32_t, little, unaligned>(d)); |
1176 | 19.9M | break; |
1177 | 280 | case DeclarationName::ObjCZeroArgSelector: |
1178 | 356 | case DeclarationName::ObjCOneArgSelector: |
1179 | 372 | case DeclarationName::ObjCMultiArgSelector: |
1180 | 372 | Data = |
1181 | 372 | (uint64_t)Reader.getLocalSelector( |
1182 | 372 | F, endian::readNext<uint32_t, little, unaligned>( |
1183 | 372 | d)).getAsOpaquePtr(); |
1184 | 372 | break; |
1185 | 125k | case DeclarationName::CXXOperatorName: |
1186 | 125k | Data = *d++; // OverloadedOperatorKind |
1187 | 125k | break; |
1188 | 13.3k | case DeclarationName::CXXConstructorName: |
1189 | 22.8k | case DeclarationName::CXXDestructorName: |
1190 | 28.7k | case DeclarationName::CXXConversionFunctionName: |
1191 | 39.2k | case DeclarationName::CXXUsingDirective: |
1192 | 39.2k | Data = 0; |
1193 | 39.2k | break; |
1194 | 20.1M | } |
1195 | | |
1196 | 20.1M | return DeclarationNameKey(Kind, Data); |
1197 | 20.1M | } |
1198 | | |
1199 | | void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type, |
1200 | | const unsigned char *d, |
1201 | | unsigned DataLen, |
1202 | 20.1M | data_type_builder &Val) { |
1203 | 20.1M | using namespace llvm::support; |
1204 | | |
1205 | 84.8M | for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls64.7M ) { |
1206 | 64.7M | uint32_t LocalID = endian::readNext<uint32_t, little, unaligned>(d); |
1207 | 64.7M | Val.insert(Reader.getGlobalDeclID(F, LocalID)); |
1208 | 64.7M | } |
1209 | 20.1M | } |
1210 | | |
1211 | | bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M, |
1212 | | BitstreamCursor &Cursor, |
1213 | | uint64_t Offset, |
1214 | 1.37M | DeclContext *DC) { |
1215 | 1.37M | assert(Offset != 0); |
1216 | | |
1217 | 1.37M | SavedStreamPosition SavedPosition(Cursor); |
1218 | 1.37M | if (llvm::Error Err = Cursor.JumpToBit(Offset)) { |
1219 | 0 | Error(std::move(Err)); |
1220 | 0 | return true; |
1221 | 0 | } |
1222 | | |
1223 | 1.37M | RecordData Record; |
1224 | 1.37M | StringRef Blob; |
1225 | 1.37M | Expected<unsigned> MaybeCode = Cursor.ReadCode(); |
1226 | 1.37M | if (!MaybeCode) { |
1227 | 0 | Error(MaybeCode.takeError()); |
1228 | 0 | return true; |
1229 | 0 | } |
1230 | 1.37M | unsigned Code = MaybeCode.get(); |
1231 | | |
1232 | 1.37M | Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record, &Blob); |
1233 | 1.37M | if (!MaybeRecCode) { |
1234 | 0 | Error(MaybeRecCode.takeError()); |
1235 | 0 | return true; |
1236 | 0 | } |
1237 | 1.37M | unsigned RecCode = MaybeRecCode.get(); |
1238 | 1.37M | if (RecCode != DECL_CONTEXT_LEXICAL) { |
1239 | 0 | Error("Expected lexical block"); |
1240 | 0 | return true; |
1241 | 0 | } |
1242 | | |
1243 | 1.37M | assert(!isa<TranslationUnitDecl>(DC) && |
1244 | 1.37M | "expected a TU_UPDATE_LEXICAL record for TU"); |
1245 | | // If we are handling a C++ class template instantiation, we can see multiple |
1246 | | // lexical updates for the same record. It's important that we select only one |
1247 | | // of them, so that field numbering works properly. Just pick the first one we |
1248 | | // see. |
1249 | 1.37M | auto &Lex = LexicalDecls[DC]; |
1250 | 1.37M | if (!Lex.first) { |
1251 | 1.37M | Lex = std::make_pair( |
1252 | 1.37M | &M, llvm::ArrayRef( |
1253 | 1.37M | reinterpret_cast<const llvm::support::unaligned_uint32_t *>( |
1254 | 1.37M | Blob.data()), |
1255 | 1.37M | Blob.size() / 4)); |
1256 | 1.37M | } |
1257 | 1.37M | DC->setHasExternalLexicalStorage(true); |
1258 | 1.37M | return false; |
1259 | 1.37M | } |
1260 | | |
1261 | | bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M, |
1262 | | BitstreamCursor &Cursor, |
1263 | | uint64_t Offset, |
1264 | 348k | DeclID ID) { |
1265 | 348k | assert(Offset != 0); |
1266 | | |
1267 | 348k | SavedStreamPosition SavedPosition(Cursor); |
1268 | 348k | if (llvm::Error Err = Cursor.JumpToBit(Offset)) { |
1269 | 0 | Error(std::move(Err)); |
1270 | 0 | return true; |
1271 | 0 | } |
1272 | | |
1273 | 348k | RecordData Record; |
1274 | 348k | StringRef Blob; |
1275 | 348k | Expected<unsigned> MaybeCode = Cursor.ReadCode(); |
1276 | 348k | if (!MaybeCode) { |
1277 | 0 | Error(MaybeCode.takeError()); |
1278 | 0 | return true; |
1279 | 0 | } |
1280 | 348k | unsigned Code = MaybeCode.get(); |
1281 | | |
1282 | 348k | Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record, &Blob); |
1283 | 348k | if (!MaybeRecCode) { |
1284 | 0 | Error(MaybeRecCode.takeError()); |
1285 | 0 | return true; |
1286 | 0 | } |
1287 | 348k | unsigned RecCode = MaybeRecCode.get(); |
1288 | 348k | if (RecCode != DECL_CONTEXT_VISIBLE) { |
1289 | 0 | Error("Expected visible lookup table block"); |
1290 | 0 | return true; |
1291 | 0 | } |
1292 | | |
1293 | | // We can't safely determine the primary context yet, so delay attaching the |
1294 | | // lookup table until we're done with recursive deserialization. |
1295 | 348k | auto *Data = (const unsigned char*)Blob.data(); |
1296 | 348k | PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&M, Data}); |
1297 | 348k | return false; |
1298 | 348k | } |
1299 | | |
1300 | 5 | void ASTReader::Error(StringRef Msg) const { |
1301 | 5 | Error(diag::err_fe_pch_malformed, Msg); |
1302 | 5 | if (PP.getLangOpts().Modules && !Diags.isDiagnosticInFlight()4 && |
1303 | 5 | !PP.getHeaderSearchInfo().getModuleCachePath().empty()3 ) { |
1304 | 0 | Diag(diag::note_module_cache_path) |
1305 | 0 | << PP.getHeaderSearchInfo().getModuleCachePath(); |
1306 | 0 | } |
1307 | 5 | } |
1308 | | |
1309 | | void ASTReader::Error(unsigned DiagID, StringRef Arg1, StringRef Arg2, |
1310 | 11 | StringRef Arg3) const { |
1311 | 11 | if (Diags.isDiagnosticInFlight()) |
1312 | 1 | Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2, Arg3); |
1313 | 10 | else |
1314 | 10 | Diag(DiagID) << Arg1 << Arg2 << Arg3; |
1315 | 11 | } |
1316 | | |
1317 | 5 | void ASTReader::Error(llvm::Error &&Err) const { |
1318 | 5 | llvm::Error RemainingErr = |
1319 | 5 | handleErrors(std::move(Err), [this](const DiagnosticError &E) { |
1320 | 5 | auto Diag = E.getDiagnostic().second; |
1321 | | |
1322 | | // Ideally we'd just emit it, but have to handle a possible in-flight |
1323 | | // diagnostic. Note that the location is currently ignored as well. |
1324 | 5 | auto NumArgs = Diag.getStorage()->NumDiagArgs; |
1325 | 5 | assert(NumArgs <= 3 && "Can only have up to 3 arguments"); |
1326 | 5 | StringRef Arg1, Arg2, Arg3; |
1327 | 5 | switch (NumArgs) { |
1328 | 5 | case 3: |
1329 | 5 | Arg3 = Diag.getStringArg(2); |
1330 | 5 | [[fallthrough]]; |
1331 | 5 | case 2: |
1332 | 5 | Arg2 = Diag.getStringArg(1); |
1333 | 5 | [[fallthrough]]; |
1334 | 5 | case 1: |
1335 | 5 | Arg1 = Diag.getStringArg(0); |
1336 | 5 | } |
1337 | 5 | Error(Diag.getDiagID(), Arg1, Arg2, Arg3); |
1338 | 5 | }); |
1339 | 5 | if (RemainingErr) |
1340 | 0 | Error(toString(std::move(RemainingErr))); |
1341 | 5 | } |
1342 | | |
1343 | | //===----------------------------------------------------------------------===// |
1344 | | // Source Manager Deserialization |
1345 | | //===----------------------------------------------------------------------===// |
1346 | | |
1347 | | /// Read the line table in the source manager block. |
1348 | 477k | void ASTReader::ParseLineTable(ModuleFile &F, const RecordData &Record) { |
1349 | 477k | unsigned Idx = 0; |
1350 | 477k | LineTableInfo &LineTable = SourceMgr.getLineTable(); |
1351 | | |
1352 | | // Parse the file names |
1353 | 477k | std::map<int, int> FileIDs; |
1354 | 477k | FileIDs[-1] = -1; // For unspecified filenames. |
1355 | 2.18M | for (unsigned I = 0; Record[Idx]; ++I1.71M ) { |
1356 | | // Extract the file name |
1357 | 1.71M | auto Filename = ReadPath(F, Record, Idx); |
1358 | 1.71M | FileIDs[I] = LineTable.getLineTableFilenameID(Filename); |
1359 | 1.71M | } |
1360 | 477k | ++Idx; |
1361 | | |
1362 | | // Parse the line entries |
1363 | 477k | std::vector<LineEntry> Entries; |
1364 | 1.71M | while (Idx < Record.size()) { |
1365 | 1.23M | FileID FID = ReadFileID(F, Record, Idx); |
1366 | | |
1367 | | // Extract the line entries |
1368 | 1.23M | unsigned NumEntries = Record[Idx++]; |
1369 | 1.23M | assert(NumEntries && "no line entries for file ID"); |
1370 | 1.23M | Entries.clear(); |
1371 | 1.23M | Entries.reserve(NumEntries); |
1372 | 3.42M | for (unsigned I = 0; I != NumEntries; ++I2.19M ) { |
1373 | 2.19M | unsigned FileOffset = Record[Idx++]; |
1374 | 2.19M | unsigned LineNo = Record[Idx++]; |
1375 | 2.19M | int FilenameID = FileIDs[Record[Idx++]]; |
1376 | 2.19M | SrcMgr::CharacteristicKind FileKind |
1377 | 2.19M | = (SrcMgr::CharacteristicKind)Record[Idx++]; |
1378 | 2.19M | unsigned IncludeOffset = Record[Idx++]; |
1379 | 2.19M | Entries.push_back(LineEntry::get(FileOffset, LineNo, FilenameID, |
1380 | 2.19M | FileKind, IncludeOffset)); |
1381 | 2.19M | } |
1382 | 1.23M | LineTable.AddEntry(FID, Entries); |
1383 | 1.23M | } |
1384 | 477k | } |
1385 | | |
1386 | | /// Read a source manager block |
1387 | 477k | llvm::Error ASTReader::ReadSourceManagerBlock(ModuleFile &F) { |
1388 | 477k | using namespace SrcMgr; |
1389 | | |
1390 | 477k | BitstreamCursor &SLocEntryCursor = F.SLocEntryCursor; |
1391 | | |
1392 | | // Set the source-location entry cursor to the current position in |
1393 | | // the stream. This cursor will be used to read the contents of the |
1394 | | // source manager block initially, and then lazily read |
1395 | | // source-location entries as needed. |
1396 | 477k | SLocEntryCursor = F.Stream; |
1397 | | |
1398 | | // The stream itself is going to skip over the source manager block. |
1399 | 477k | if (llvm::Error Err = F.Stream.SkipBlock()) |
1400 | 0 | return Err; |
1401 | | |
1402 | | // Enter the source manager block. |
1403 | 477k | if (llvm::Error Err = SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) |
1404 | 0 | return Err; |
1405 | 477k | F.SourceManagerBlockStartOffset = SLocEntryCursor.GetCurrentBitNo(); |
1406 | | |
1407 | 477k | RecordData Record; |
1408 | 477k | while (true) { |
1409 | 477k | Expected<llvm::BitstreamEntry> MaybeE = |
1410 | 477k | SLocEntryCursor.advanceSkippingSubblocks(); |
1411 | 477k | if (!MaybeE) |
1412 | 0 | return MaybeE.takeError(); |
1413 | 477k | llvm::BitstreamEntry E = MaybeE.get(); |
1414 | | |
1415 | 477k | switch (E.Kind) { |
1416 | 0 | case llvm::BitstreamEntry::SubBlock: // Handled for us already. |
1417 | 0 | case llvm::BitstreamEntry::Error: |
1418 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
1419 | 0 | "malformed block record in AST file"); |
1420 | 0 | case llvm::BitstreamEntry::EndBlock: |
1421 | 0 | return llvm::Error::success(); |
1422 | 477k | case llvm::BitstreamEntry::Record: |
1423 | | // The interesting case. |
1424 | 477k | break; |
1425 | 477k | } |
1426 | | |
1427 | | // Read a record. |
1428 | 477k | Record.clear(); |
1429 | 477k | StringRef Blob; |
1430 | 477k | Expected<unsigned> MaybeRecord = |
1431 | 477k | SLocEntryCursor.readRecord(E.ID, Record, &Blob); |
1432 | 477k | if (!MaybeRecord) |
1433 | 0 | return MaybeRecord.takeError(); |
1434 | 477k | switch (MaybeRecord.get()) { |
1435 | 0 | default: // Default behavior: ignore. |
1436 | 0 | break; |
1437 | | |
1438 | 477k | case SM_SLOC_FILE_ENTRY: |
1439 | 477k | case SM_SLOC_BUFFER_ENTRY: |
1440 | 477k | case SM_SLOC_EXPANSION_ENTRY: |
1441 | | // Once we hit one of the source location entries, we're done. |
1442 | 477k | return llvm::Error::success(); |
1443 | 477k | } |
1444 | 477k | } |
1445 | 477k | } |
1446 | | |
1447 | 22.7M | bool ASTReader::ReadSLocEntry(int ID) { |
1448 | 22.7M | if (ID == 0) |
1449 | 0 | return false; |
1450 | | |
1451 | 22.7M | if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) { |
1452 | 0 | Error("source location entry ID out-of-range for AST file"); |
1453 | 0 | return true; |
1454 | 0 | } |
1455 | | |
1456 | | // Local helper to read the (possibly-compressed) buffer data following the |
1457 | | // entry record. |
1458 | 22.7M | auto ReadBuffer = [this]( |
1459 | 22.7M | BitstreamCursor &SLocEntryCursor, |
1460 | 22.7M | StringRef Name) -> std::unique_ptr<llvm::MemoryBuffer> { |
1461 | 906k | RecordData Record; |
1462 | 906k | StringRef Blob; |
1463 | 906k | Expected<unsigned> MaybeCode = SLocEntryCursor.ReadCode(); |
1464 | 906k | if (!MaybeCode) { |
1465 | 0 | Error(MaybeCode.takeError()); |
1466 | 0 | return nullptr; |
1467 | 0 | } |
1468 | 906k | unsigned Code = MaybeCode.get(); |
1469 | | |
1470 | 906k | Expected<unsigned> MaybeRecCode = |
1471 | 906k | SLocEntryCursor.readRecord(Code, Record, &Blob); |
1472 | 906k | if (!MaybeRecCode) { |
1473 | 0 | Error(MaybeRecCode.takeError()); |
1474 | 0 | return nullptr; |
1475 | 0 | } |
1476 | 906k | unsigned RecCode = MaybeRecCode.get(); |
1477 | | |
1478 | 906k | if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) { |
1479 | | // Inspect the first byte to differentiate zlib (\x78) and zstd |
1480 | | // (little-endian 0xFD2FB528). |
1481 | 906k | const llvm::compression::Format F = |
1482 | 906k | Blob.size() > 0 && Blob.data()[0] == 0x78 |
1483 | 906k | ? llvm::compression::Format::Zlib |
1484 | 906k | : llvm::compression::Format::Zstd0 ; |
1485 | 906k | if (const char *Reason = llvm::compression::getReasonIfUnsupported(F)) { |
1486 | 0 | Error(Reason); |
1487 | 0 | return nullptr; |
1488 | 0 | } |
1489 | 906k | SmallVector<uint8_t, 0> Decompressed; |
1490 | 906k | if (llvm::Error E = llvm::compression::decompress( |
1491 | 906k | F, llvm::arrayRefFromStringRef(Blob), Decompressed, Record[0])) { |
1492 | 0 | Error("could not decompress embedded file contents: " + |
1493 | 0 | llvm::toString(std::move(E))); |
1494 | 0 | return nullptr; |
1495 | 0 | } |
1496 | 906k | return llvm::MemoryBuffer::getMemBufferCopy( |
1497 | 906k | llvm::toStringRef(Decompressed), Name); |
1498 | 906k | } else if (0 RecCode == SM_SLOC_BUFFER_BLOB0 ) { |
1499 | 0 | return llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name, true); |
1500 | 0 | } else { |
1501 | 0 | Error("AST record has invalid code"); |
1502 | 0 | return nullptr; |
1503 | 0 | } |
1504 | 906k | }; |
1505 | | |
1506 | 22.7M | ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second; |
1507 | 22.7M | if (llvm::Error Err = F->SLocEntryCursor.JumpToBit( |
1508 | 22.7M | F->SLocEntryOffsetsBase + |
1509 | 22.7M | F->SLocEntryOffsets[ID - F->SLocEntryBaseID])) { |
1510 | 0 | Error(std::move(Err)); |
1511 | 0 | return true; |
1512 | 0 | } |
1513 | | |
1514 | 22.7M | BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor; |
1515 | 22.7M | SourceLocation::UIntTy BaseOffset = F->SLocEntryBaseOffset; |
1516 | | |
1517 | 22.7M | ++NumSLocEntriesRead; |
1518 | 22.7M | Expected<llvm::BitstreamEntry> MaybeEntry = SLocEntryCursor.advance(); |
1519 | 22.7M | if (!MaybeEntry) { |
1520 | 0 | Error(MaybeEntry.takeError()); |
1521 | 0 | return true; |
1522 | 0 | } |
1523 | 22.7M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
1524 | | |
1525 | 22.7M | if (Entry.Kind != llvm::BitstreamEntry::Record) { |
1526 | 0 | Error("incorrectly-formatted source location entry in AST file"); |
1527 | 0 | return true; |
1528 | 0 | } |
1529 | | |
1530 | 22.7M | RecordData Record; |
1531 | 22.7M | StringRef Blob; |
1532 | 22.7M | Expected<unsigned> MaybeSLOC = |
1533 | 22.7M | SLocEntryCursor.readRecord(Entry.ID, Record, &Blob); |
1534 | 22.7M | if (!MaybeSLOC) { |
1535 | 0 | Error(MaybeSLOC.takeError()); |
1536 | 0 | return true; |
1537 | 0 | } |
1538 | 22.7M | switch (MaybeSLOC.get()) { |
1539 | 0 | default: |
1540 | 0 | Error("incorrectly-formatted source location entry in AST file"); |
1541 | 0 | return true; |
1542 | | |
1543 | 1.47M | case SM_SLOC_FILE_ENTRY: { |
1544 | | // We will detect whether a file changed and return 'Failure' for it, but |
1545 | | // we will also try to fail gracefully by setting up the SLocEntry. |
1546 | 1.47M | unsigned InputID = Record[4]; |
1547 | 1.47M | InputFile IF = getInputFile(*F, InputID); |
1548 | 1.47M | OptionalFileEntryRef File = IF.getFile(); |
1549 | 1.47M | bool OverriddenBuffer = IF.isOverridden(); |
1550 | | |
1551 | | // Note that we only check if a File was returned. If it was out-of-date |
1552 | | // we have complained but we will continue creating a FileID to recover |
1553 | | // gracefully. |
1554 | 1.47M | if (!File) |
1555 | 25 | return true; |
1556 | | |
1557 | 1.47M | SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]); |
1558 | 1.47M | if (IncludeLoc.isInvalid() && F->Kind != MK_MainFile322k ) { |
1559 | | // This is the module's main file. |
1560 | 322k | IncludeLoc = getImportLocation(F); |
1561 | 322k | } |
1562 | 1.47M | SrcMgr::CharacteristicKind |
1563 | 1.47M | FileCharacter = (SrcMgr::CharacteristicKind)Record[2]; |
1564 | 1.47M | FileID FID = SourceMgr.createFileID(*File, IncludeLoc, FileCharacter, ID, |
1565 | 1.47M | BaseOffset + Record[0]); |
1566 | 1.47M | SrcMgr::FileInfo &FileInfo = |
1567 | 1.47M | const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile()); |
1568 | 1.47M | FileInfo.NumCreatedFIDs = Record[5]; |
1569 | 1.47M | if (Record[3]) |
1570 | 608k | FileInfo.setHasLineDirectives(); |
1571 | | |
1572 | 1.47M | unsigned NumFileDecls = Record[7]; |
1573 | 1.47M | if (NumFileDecls && ContextObj802k ) { |
1574 | 801k | const DeclID *FirstDecl = F->FileSortedDecls + Record[6]; |
1575 | 801k | assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?"); |
1576 | 801k | FileDeclIDs[FID] = |
1577 | 801k | FileDeclsInfo(F, llvm::ArrayRef(FirstDecl, NumFileDecls)); |
1578 | 801k | } |
1579 | | |
1580 | 1.47M | const SrcMgr::ContentCache &ContentCache = |
1581 | 1.47M | SourceMgr.getOrCreateContentCache(*File, isSystem(FileCharacter)); |
1582 | 1.47M | if (OverriddenBuffer && !ContentCache.BufferOverridden341 && |
1583 | 1.47M | ContentCache.ContentsEntry == ContentCache.OrigEntry126 && |
1584 | 1.47M | !ContentCache.getBufferIfLoaded()126 ) { |
1585 | 124 | auto Buffer = ReadBuffer(SLocEntryCursor, File->getName()); |
1586 | 124 | if (!Buffer) |
1587 | 0 | return true; |
1588 | 124 | SourceMgr.overrideFileContents(*File, std::move(Buffer)); |
1589 | 124 | } |
1590 | | |
1591 | 1.47M | break; |
1592 | 1.47M | } |
1593 | | |
1594 | 1.47M | case SM_SLOC_BUFFER_ENTRY: { |
1595 | 906k | const char *Name = Blob.data(); |
1596 | 906k | unsigned Offset = Record[0]; |
1597 | 906k | SrcMgr::CharacteristicKind |
1598 | 906k | FileCharacter = (SrcMgr::CharacteristicKind)Record[2]; |
1599 | 906k | SourceLocation IncludeLoc = ReadSourceLocation(*F, Record[1]); |
1600 | 906k | if (IncludeLoc.isInvalid() && F->isModule()906k ) { |
1601 | 901k | IncludeLoc = getImportLocation(F); |
1602 | 901k | } |
1603 | | |
1604 | 906k | auto Buffer = ReadBuffer(SLocEntryCursor, Name); |
1605 | 906k | if (!Buffer) |
1606 | 0 | return true; |
1607 | 906k | FileID FID = SourceMgr.createFileID(std::move(Buffer), FileCharacter, ID, |
1608 | 906k | BaseOffset + Offset, IncludeLoc); |
1609 | 906k | if (Record[3]) { |
1610 | 477k | auto &FileInfo = |
1611 | 477k | const_cast<SrcMgr::FileInfo &>(SourceMgr.getSLocEntry(FID).getFile()); |
1612 | 477k | FileInfo.setHasLineDirectives(); |
1613 | 477k | } |
1614 | 906k | break; |
1615 | 906k | } |
1616 | | |
1617 | 20.3M | case SM_SLOC_EXPANSION_ENTRY: { |
1618 | 20.3M | LocSeq::State Seq; |
1619 | 20.3M | SourceLocation SpellingLoc = ReadSourceLocation(*F, Record[1], Seq); |
1620 | 20.3M | SourceLocation ExpansionBegin = ReadSourceLocation(*F, Record[2], Seq); |
1621 | 20.3M | SourceLocation ExpansionEnd = ReadSourceLocation(*F, Record[3], Seq); |
1622 | 20.3M | SourceMgr.createExpansionLoc(SpellingLoc, ExpansionBegin, ExpansionEnd, |
1623 | 20.3M | Record[5], Record[4], ID, |
1624 | 20.3M | BaseOffset + Record[0]); |
1625 | 20.3M | break; |
1626 | 906k | } |
1627 | 22.7M | } |
1628 | | |
1629 | 22.7M | return false; |
1630 | 22.7M | } |
1631 | | |
1632 | 43 | std::pair<SourceLocation, StringRef> ASTReader::getModuleImportLoc(int ID) { |
1633 | 43 | if (ID == 0) |
1634 | 0 | return std::make_pair(SourceLocation(), ""); |
1635 | | |
1636 | 43 | if (unsigned(-ID) - 2 >= getTotalNumSLocs() || ID > 0) { |
1637 | 0 | Error("source location entry ID out-of-range for AST file"); |
1638 | 0 | return std::make_pair(SourceLocation(), ""); |
1639 | 0 | } |
1640 | | |
1641 | | // Find which module file this entry lands in. |
1642 | 43 | ModuleFile *M = GlobalSLocEntryMap.find(-ID)->second; |
1643 | 43 | if (!M->isModule()) |
1644 | 14 | return std::make_pair(SourceLocation(), ""); |
1645 | | |
1646 | | // FIXME: Can we map this down to a particular submodule? That would be |
1647 | | // ideal. |
1648 | 29 | return std::make_pair(M->ImportLoc, StringRef(M->ModuleName)); |
1649 | 43 | } |
1650 | | |
1651 | | /// Find the location where the module F is imported. |
1652 | 1.22M | SourceLocation ASTReader::getImportLocation(ModuleFile *F) { |
1653 | 1.22M | if (F->ImportLoc.isValid()) |
1654 | 1.21M | return F->ImportLoc; |
1655 | | |
1656 | | // Otherwise we have a PCH. It's considered to be "imported" at the first |
1657 | | // location of its includer. |
1658 | 4.89k | if (F->ImportedBy.empty() || !F->ImportedBy[0]1.26k ) { |
1659 | | // Main file is the importer. |
1660 | 3.62k | assert(SourceMgr.getMainFileID().isValid() && "missing main file"); |
1661 | 3.62k | return SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); |
1662 | 3.62k | } |
1663 | 1.26k | return F->ImportedBy[0]->FirstLoc; |
1664 | 4.89k | } |
1665 | | |
1666 | | /// Enter a subblock of the specified BlockID with the specified cursor. Read |
1667 | | /// the abbreviations that are at the top of the block and then leave the cursor |
1668 | | /// pointing into the block. |
1669 | | llvm::Error ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, |
1670 | | unsigned BlockID, |
1671 | 1.91M | uint64_t *StartOfBlockOffset) { |
1672 | 1.91M | if (llvm::Error Err = Cursor.EnterSubBlock(BlockID)) |
1673 | 0 | return Err; |
1674 | | |
1675 | 1.91M | if (StartOfBlockOffset) |
1676 | 477k | *StartOfBlockOffset = Cursor.GetCurrentBitNo(); |
1677 | | |
1678 | 10.0M | while (true) { |
1679 | 10.0M | uint64_t Offset = Cursor.GetCurrentBitNo(); |
1680 | 10.0M | Expected<unsigned> MaybeCode = Cursor.ReadCode(); |
1681 | 10.0M | if (!MaybeCode) |
1682 | 0 | return MaybeCode.takeError(); |
1683 | 10.0M | unsigned Code = MaybeCode.get(); |
1684 | | |
1685 | | // We expect all abbrevs to be at the start of the block. |
1686 | 10.0M | if (Code != llvm::bitc::DEFINE_ABBREV) { |
1687 | 1.91M | if (llvm::Error Err = Cursor.JumpToBit(Offset)) |
1688 | 0 | return Err; |
1689 | 1.91M | return llvm::Error::success(); |
1690 | 1.91M | } |
1691 | 8.11M | if (llvm::Error Err = Cursor.ReadAbbrevRecord()) |
1692 | 0 | return Err; |
1693 | 8.11M | } |
1694 | 1.91M | } |
1695 | | |
1696 | | Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record, |
1697 | 21.3M | unsigned &Idx) { |
1698 | 21.3M | Token Tok; |
1699 | 21.3M | Tok.startToken(); |
1700 | 21.3M | Tok.setLocation(ReadSourceLocation(F, Record, Idx)); |
1701 | 21.3M | Tok.setKind((tok::TokenKind)Record[Idx++]); |
1702 | 21.3M | Tok.setFlag((Token::TokenFlags)Record[Idx++]); |
1703 | | |
1704 | 21.3M | if (Tok.isAnnotation()) { |
1705 | 12 | Tok.setAnnotationEndLoc(ReadSourceLocation(F, Record, Idx)); |
1706 | 12 | switch (Tok.getKind()) { |
1707 | 1 | case tok::annot_pragma_loop_hint: { |
1708 | 1 | auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; |
1709 | 1 | Info->PragmaName = ReadToken(F, Record, Idx); |
1710 | 1 | Info->Option = ReadToken(F, Record, Idx); |
1711 | 1 | unsigned NumTokens = Record[Idx++]; |
1712 | 1 | SmallVector<Token, 4> Toks; |
1713 | 1 | Toks.reserve(NumTokens); |
1714 | 3 | for (unsigned I = 0; I < NumTokens; ++I2 ) |
1715 | 2 | Toks.push_back(ReadToken(F, Record, Idx)); |
1716 | 1 | Info->Toks = llvm::ArrayRef(Toks).copy(PP.getPreprocessorAllocator()); |
1717 | 1 | Tok.setAnnotationValue(static_cast<void *>(Info)); |
1718 | 1 | break; |
1719 | 0 | } |
1720 | 6 | case tok::annot_pragma_pack: { |
1721 | 6 | auto *Info = new (PP.getPreprocessorAllocator()) Sema::PragmaPackInfo; |
1722 | 6 | Info->Action = static_cast<Sema::PragmaMsStackAction>(Record[Idx++]); |
1723 | 6 | auto SlotLabel = ReadString(Record, Idx); |
1724 | 6 | Info->SlotLabel = |
1725 | 6 | llvm::StringRef(SlotLabel).copy(PP.getPreprocessorAllocator()); |
1726 | 6 | Info->Alignment = ReadToken(F, Record, Idx); |
1727 | 6 | Tok.setAnnotationValue(static_cast<void *>(Info)); |
1728 | 6 | break; |
1729 | 0 | } |
1730 | | // Some annotation tokens do not use the PtrData field. |
1731 | 1 | case tok::annot_pragma_openmp: |
1732 | 2 | case tok::annot_pragma_openmp_end: |
1733 | 5 | case tok::annot_pragma_unused: |
1734 | 5 | break; |
1735 | 0 | default: |
1736 | 0 | llvm_unreachable("missing deserialization code for annotation token"); |
1737 | 12 | } |
1738 | 21.3M | } else { |
1739 | 21.3M | Tok.setLength(Record[Idx++]); |
1740 | 21.3M | if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++])) |
1741 | 7.88M | Tok.setIdentifierInfo(II); |
1742 | 21.3M | } |
1743 | 21.3M | return Tok; |
1744 | 21.3M | } |
1745 | | |
1746 | 6.00M | MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { |
1747 | 6.00M | BitstreamCursor &Stream = F.MacroCursor; |
1748 | | |
1749 | | // Keep track of where we are in the stream, then jump back there |
1750 | | // after reading this macro. |
1751 | 6.00M | SavedStreamPosition SavedPosition(Stream); |
1752 | | |
1753 | 6.00M | if (llvm::Error Err = Stream.JumpToBit(Offset)) { |
1754 | | // FIXME this drops errors on the floor. |
1755 | 0 | consumeError(std::move(Err)); |
1756 | 0 | return nullptr; |
1757 | 0 | } |
1758 | 6.00M | RecordData Record; |
1759 | 6.00M | SmallVector<IdentifierInfo*, 16> MacroParams; |
1760 | 6.00M | MacroInfo *Macro = nullptr; |
1761 | 6.00M | llvm::MutableArrayRef<Token> MacroTokens; |
1762 | | |
1763 | 33.3M | while (true) { |
1764 | | // Advance to the next record, but if we get to the end of the block, don't |
1765 | | // pop it (removing all the abbreviations from the cursor) since we want to |
1766 | | // be able to reseek within the block and read entries. |
1767 | 33.3M | unsigned Flags = BitstreamCursor::AF_DontPopBlockAtEnd; |
1768 | 33.3M | Expected<llvm::BitstreamEntry> MaybeEntry = |
1769 | 33.3M | Stream.advanceSkippingSubblocks(Flags); |
1770 | 33.3M | if (!MaybeEntry) { |
1771 | 0 | Error(MaybeEntry.takeError()); |
1772 | 0 | return Macro; |
1773 | 0 | } |
1774 | 33.3M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
1775 | | |
1776 | 33.3M | switch (Entry.Kind) { |
1777 | 0 | case llvm::BitstreamEntry::SubBlock: // Handled for us already. |
1778 | 0 | case llvm::BitstreamEntry::Error: |
1779 | 0 | Error("malformed block record in AST file"); |
1780 | 0 | return Macro; |
1781 | 33.7k | case llvm::BitstreamEntry::EndBlock: |
1782 | 33.7k | return Macro; |
1783 | 33.3M | case llvm::BitstreamEntry::Record: |
1784 | | // The interesting case. |
1785 | 33.3M | break; |
1786 | 33.3M | } |
1787 | | |
1788 | | // Read a record. |
1789 | 33.3M | Record.clear(); |
1790 | 33.3M | PreprocessorRecordTypes RecType; |
1791 | 33.3M | if (Expected<unsigned> MaybeRecType = Stream.readRecord(Entry.ID, Record)) |
1792 | 33.3M | RecType = (PreprocessorRecordTypes)MaybeRecType.get(); |
1793 | 0 | else { |
1794 | 0 | Error(MaybeRecType.takeError()); |
1795 | 0 | return Macro; |
1796 | 0 | } |
1797 | 33.3M | switch (RecType) { |
1798 | 0 | case PP_MODULE_MACRO: |
1799 | 0 | case PP_MACRO_DIRECTIVE_HISTORY: |
1800 | 0 | return Macro; |
1801 | | |
1802 | 9.15M | case PP_MACRO_OBJECT_LIKE: |
1803 | 11.9M | case PP_MACRO_FUNCTION_LIKE: { |
1804 | | // If we already have a macro, that means that we've hit the end |
1805 | | // of the definition of the macro we were looking for. We're |
1806 | | // done. |
1807 | 11.9M | if (Macro) |
1808 | 5.97M | return Macro; |
1809 | | |
1810 | 6.00M | unsigned NextIndex = 1; // Skip identifier ID. |
1811 | 6.00M | SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex); |
1812 | 6.00M | MacroInfo *MI = PP.AllocateMacroInfo(Loc); |
1813 | 6.00M | MI->setDefinitionEndLoc(ReadSourceLocation(F, Record, NextIndex)); |
1814 | 6.00M | MI->setIsUsed(Record[NextIndex++]); |
1815 | 6.00M | MI->setUsedForHeaderGuard(Record[NextIndex++]); |
1816 | 6.00M | MacroTokens = MI->allocateTokens(Record[NextIndex++], |
1817 | 6.00M | PP.getPreprocessorAllocator()); |
1818 | 6.00M | if (RecType == PP_MACRO_FUNCTION_LIKE) { |
1819 | | // Decode function-like macro info. |
1820 | 1.40M | bool isC99VarArgs = Record[NextIndex++]; |
1821 | 1.40M | bool isGNUVarArgs = Record[NextIndex++]; |
1822 | 1.40M | bool hasCommaPasting = Record[NextIndex++]; |
1823 | 1.40M | MacroParams.clear(); |
1824 | 1.40M | unsigned NumArgs = Record[NextIndex++]; |
1825 | 3.28M | for (unsigned i = 0; i != NumArgs; ++i1.87M ) |
1826 | 1.87M | MacroParams.push_back(getLocalIdentifier(F, Record[NextIndex++])); |
1827 | | |
1828 | | // Install function-like macro info. |
1829 | 1.40M | MI->setIsFunctionLike(); |
1830 | 1.40M | if (isC99VarArgs) MI->setIsC99Varargs()101k ; |
1831 | 1.40M | if (isGNUVarArgs) MI->setIsGNUVarargs()9 ; |
1832 | 1.40M | if (hasCommaPasting) MI->setHasCommaPasting()51 ; |
1833 | 1.40M | MI->setParameterList(MacroParams, PP.getPreprocessorAllocator()); |
1834 | 1.40M | } |
1835 | | |
1836 | | // Remember that we saw this macro last so that we add the tokens that |
1837 | | // form its body to it. |
1838 | 6.00M | Macro = MI; |
1839 | | |
1840 | 6.00M | if (NextIndex + 1 == Record.size() && PP.getPreprocessingRecord()44.2k && |
1841 | 6.00M | Record[NextIndex]44.2k ) { |
1842 | | // We have a macro definition. Register the association |
1843 | 44.2k | PreprocessedEntityID |
1844 | 44.2k | GlobalID = getGlobalPreprocessedEntityID(F, Record[NextIndex]); |
1845 | 44.2k | PreprocessingRecord &PPRec = *PP.getPreprocessingRecord(); |
1846 | 44.2k | PreprocessingRecord::PPEntityID PPID = |
1847 | 44.2k | PPRec.getPPEntityID(GlobalID - 1, /*isLoaded=*/true); |
1848 | 44.2k | MacroDefinitionRecord *PPDef = cast_or_null<MacroDefinitionRecord>( |
1849 | 44.2k | PPRec.getPreprocessedEntity(PPID)); |
1850 | 44.2k | if (PPDef) |
1851 | 44.2k | PPRec.RegisterMacroDefinition(Macro, PPDef); |
1852 | 44.2k | } |
1853 | | |
1854 | 6.00M | ++NumMacrosRead; |
1855 | 6.00M | break; |
1856 | 11.9M | } |
1857 | | |
1858 | 21.3M | case PP_TOKEN: { |
1859 | | // If we see a TOKEN before a PP_MACRO_*, then the file is |
1860 | | // erroneous, just pretend we didn't see this. |
1861 | 21.3M | if (!Macro) break0 ; |
1862 | 21.3M | if (MacroTokens.empty()) { |
1863 | 0 | Error("unexpected number of macro tokens for a macro in AST file"); |
1864 | 0 | return Macro; |
1865 | 0 | } |
1866 | | |
1867 | 21.3M | unsigned Idx = 0; |
1868 | 21.3M | MacroTokens[0] = ReadToken(F, Record, Idx); |
1869 | 21.3M | MacroTokens = MacroTokens.drop_front(); |
1870 | 21.3M | break; |
1871 | 21.3M | } |
1872 | 33.3M | } |
1873 | 33.3M | } |
1874 | 6.00M | } |
1875 | | |
1876 | | PreprocessedEntityID |
1877 | | ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M, |
1878 | 44.2k | unsigned LocalID) const { |
1879 | 44.2k | if (!M.ModuleOffsetMap.empty()) |
1880 | 0 | ReadModuleOffsetMap(M); |
1881 | | |
1882 | 44.2k | ContinuousRangeMap<uint32_t, int, 2>::const_iterator |
1883 | 44.2k | I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS); |
1884 | 44.2k | assert(I != M.PreprocessedEntityRemap.end() |
1885 | 44.2k | && "Invalid index into preprocessed entity index remap"); |
1886 | | |
1887 | 44.2k | return LocalID + I->second; |
1888 | 44.2k | } |
1889 | | |
1890 | 1.29M | const FileEntry *HeaderFileInfoTrait::getFile(const internal_key_type &Key) { |
1891 | 1.29M | FileManager &FileMgr = Reader.getFileManager(); |
1892 | 1.29M | if (!Key.Imported) { |
1893 | 456k | if (auto File = FileMgr.getFile(Key.Filename)) |
1894 | 456k | return *File; |
1895 | 1 | return nullptr; |
1896 | 456k | } |
1897 | | |
1898 | 843k | std::string Resolved = std::string(Key.Filename); |
1899 | 843k | Reader.ResolveImportedPath(M, Resolved); |
1900 | 843k | if (auto File = FileMgr.getFile(Resolved)) |
1901 | 843k | return *File; |
1902 | 18.4E | return nullptr; |
1903 | 843k | } |
1904 | | |
1905 | 332M | unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) { |
1906 | 332M | return llvm::hash_combine(ikey.Size, ikey.ModTime); |
1907 | 332M | } |
1908 | | |
1909 | | HeaderFileInfoTrait::internal_key_type |
1910 | 332M | HeaderFileInfoTrait::GetInternalKey(const FileEntry *FE) { |
1911 | 332M | internal_key_type ikey = {FE->getSize(), |
1912 | 332M | M.HasTimestamps ? FE->getModificationTime()332M : 059.0k , |
1913 | 332M | FE->getName(), /*Imported*/ false}; |
1914 | 332M | return ikey; |
1915 | 332M | } |
1916 | | |
1917 | 465k | bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { |
1918 | 465k | if (a.Size != b.Size || (a.ModTime && b.ModTime447k && a.ModTime != b.ModTime447k )) |
1919 | 0 | return false; |
1920 | | |
1921 | 465k | if (llvm::sys::path::is_absolute(a.Filename) && a.Filename == b.Filename33.0k ) |
1922 | 9.61k | return true; |
1923 | | |
1924 | | // Determine whether the actual files are equivalent. |
1925 | 456k | const FileEntry *FEA = getFile(a); |
1926 | 456k | const FileEntry *FEB = getFile(b); |
1927 | 456k | return FEA456k && FEA == FEB; |
1928 | 465k | } |
1929 | | |
1930 | | std::pair<unsigned, unsigned> |
1931 | 246M | HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) { |
1932 | 246M | return readULEBKeyDataLength(d); |
1933 | 246M | } |
1934 | | |
1935 | | HeaderFileInfoTrait::internal_key_type |
1936 | 465k | HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) { |
1937 | 465k | using namespace llvm::support; |
1938 | | |
1939 | 465k | internal_key_type ikey; |
1940 | 465k | ikey.Size = off_t(endian::readNext<uint64_t, little, unaligned>(d)); |
1941 | 465k | ikey.ModTime = time_t(endian::readNext<uint64_t, little, unaligned>(d)); |
1942 | 465k | ikey.Filename = (const char *)d; |
1943 | 465k | ikey.Imported = true; |
1944 | 465k | return ikey; |
1945 | 465k | } |
1946 | | |
1947 | | HeaderFileInfoTrait::data_type |
1948 | | HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, |
1949 | 387k | unsigned DataLen) { |
1950 | 387k | using namespace llvm::support; |
1951 | | |
1952 | 387k | const unsigned char *End = d + DataLen; |
1953 | 387k | HeaderFileInfo HFI; |
1954 | 387k | unsigned Flags = *d++; |
1955 | | |
1956 | 387k | bool Included = (Flags >> 6) & 0x01; |
1957 | 387k | if (Included) |
1958 | 387k | if (const FileEntry *FE = getFile(key)) |
1959 | | // Not using \c Preprocessor::markIncluded(), since that would attempt to |
1960 | | // deserialize this header file info again. |
1961 | 387k | Reader.getPreprocessor().getIncludedFiles().insert(FE); |
1962 | | |
1963 | | // FIXME: Refactor with mergeHeaderFileInfo in HeaderSearch.cpp. |
1964 | 387k | HFI.isImport |= (Flags >> 5) & 0x01; |
1965 | 387k | HFI.isPragmaOnce |= (Flags >> 4) & 0x01; |
1966 | 387k | HFI.DirInfo = (Flags >> 1) & 0x07; |
1967 | 387k | HFI.IndexHeaderMapHeader = Flags & 0x01; |
1968 | 387k | HFI.ControllingMacroID = Reader.getGlobalIdentifierID( |
1969 | 387k | M, endian::readNext<uint32_t, little, unaligned>(d)); |
1970 | 387k | if (unsigned FrameworkOffset = |
1971 | 387k | endian::readNext<uint32_t, little, unaligned>(d)) { |
1972 | | // The framework offset is 1 greater than the actual offset, |
1973 | | // since 0 is used as an indicator for "no framework name". |
1974 | 2.86k | StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1); |
1975 | 2.86k | HFI.Framework = HS->getUniqueFrameworkName(FrameworkName); |
1976 | 2.86k | } |
1977 | | |
1978 | 387k | assert((End - d) % 4 == 0 && |
1979 | 387k | "Wrong data length in HeaderFileInfo deserialization"); |
1980 | 765k | while (387k d != End) { |
1981 | 377k | uint32_t LocalSMID = endian::readNext<uint32_t, little, unaligned>(d); |
1982 | 377k | auto HeaderRole = static_cast<ModuleMap::ModuleHeaderRole>(LocalSMID & 7); |
1983 | 377k | LocalSMID >>= 3; |
1984 | | |
1985 | | // This header is part of a module. Associate it with the module to enable |
1986 | | // implicit module import. |
1987 | 377k | SubmoduleID GlobalSMID = Reader.getGlobalSubmoduleID(M, LocalSMID); |
1988 | 377k | Module *Mod = Reader.getSubmodule(GlobalSMID); |
1989 | 377k | FileManager &FileMgr = Reader.getFileManager(); |
1990 | 377k | ModuleMap &ModMap = |
1991 | 377k | Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap(); |
1992 | | |
1993 | 377k | std::string Filename = std::string(key.Filename); |
1994 | 377k | if (key.Imported) |
1995 | 377k | Reader.ResolveImportedPath(M, Filename); |
1996 | 377k | if (auto FE377k = FileMgr.getOptionalFileRef(Filename)) { |
1997 | | // FIXME: NameAsWritten |
1998 | 377k | Module::Header H = {std::string(key.Filename), "", *FE}; |
1999 | 377k | ModMap.addHeader(Mod, H, HeaderRole, /*Imported=*/true); |
2000 | 377k | } |
2001 | 377k | HFI.isModuleHeader |= ModuleMap::isModular(HeaderRole); |
2002 | 377k | } |
2003 | | |
2004 | | // This HeaderFileInfo was externally loaded. |
2005 | 387k | HFI.External = true; |
2006 | 387k | HFI.IsValid = true; |
2007 | 387k | return HFI; |
2008 | 387k | } |
2009 | | |
2010 | | void ASTReader::addPendingMacro(IdentifierInfo *II, ModuleFile *M, |
2011 | 1.11M | uint32_t MacroDirectivesOffset) { |
2012 | 1.11M | assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard"); |
2013 | 1.11M | PendingMacroIDs[II].push_back(PendingMacroInfo(M, MacroDirectivesOffset)); |
2014 | 1.11M | } |
2015 | | |
2016 | 173 | void ASTReader::ReadDefinedMacros() { |
2017 | | // Note that we are loading defined macros. |
2018 | 173 | Deserializing Macros(this); |
2019 | | |
2020 | 948 | for (ModuleFile &I : llvm::reverse(ModuleMgr)) { |
2021 | 948 | BitstreamCursor &MacroCursor = I.MacroCursor; |
2022 | | |
2023 | | // If there was no preprocessor block, skip this file. |
2024 | 948 | if (MacroCursor.getBitcodeBytes().empty()) |
2025 | 0 | continue; |
2026 | | |
2027 | 948 | BitstreamCursor Cursor = MacroCursor; |
2028 | 948 | if (llvm::Error Err = Cursor.JumpToBit(I.MacroStartOffset)) { |
2029 | 0 | Error(std::move(Err)); |
2030 | 0 | return; |
2031 | 0 | } |
2032 | | |
2033 | 948 | RecordData Record; |
2034 | 8.20M | while (true) { |
2035 | 8.20M | Expected<llvm::BitstreamEntry> MaybeE = Cursor.advanceSkippingSubblocks(); |
2036 | 8.20M | if (!MaybeE) { |
2037 | 0 | Error(MaybeE.takeError()); |
2038 | 0 | return; |
2039 | 0 | } |
2040 | 8.20M | llvm::BitstreamEntry E = MaybeE.get(); |
2041 | | |
2042 | 8.20M | switch (E.Kind) { |
2043 | 0 | case llvm::BitstreamEntry::SubBlock: // Handled for us already. |
2044 | 0 | case llvm::BitstreamEntry::Error: |
2045 | 0 | Error("malformed block record in AST file"); |
2046 | 0 | return; |
2047 | 948 | case llvm::BitstreamEntry::EndBlock: |
2048 | 948 | goto NextCursor; |
2049 | | |
2050 | 8.19M | case llvm::BitstreamEntry::Record: { |
2051 | 8.19M | Record.clear(); |
2052 | 8.19M | Expected<unsigned> MaybeRecord = Cursor.readRecord(E.ID, Record); |
2053 | 8.19M | if (!MaybeRecord) { |
2054 | 0 | Error(MaybeRecord.takeError()); |
2055 | 0 | return; |
2056 | 0 | } |
2057 | 8.19M | switch (MaybeRecord.get()) { |
2058 | 1.74M | default: // Default behavior: ignore. |
2059 | 1.74M | break; |
2060 | | |
2061 | 1.74M | case PP_MACRO_OBJECT_LIKE: |
2062 | 887k | case PP_MACRO_FUNCTION_LIKE: { |
2063 | 887k | IdentifierInfo *II = getLocalIdentifier(I, Record[0]); |
2064 | 887k | if (II->isOutOfDate()) |
2065 | 248k | updateOutOfDateIdentifier(*II); |
2066 | 887k | break; |
2067 | 739k | } |
2068 | | |
2069 | 5.56M | case PP_TOKEN: |
2070 | | // Ignore tokens. |
2071 | 5.56M | break; |
2072 | 8.19M | } |
2073 | 8.19M | break; |
2074 | 8.19M | } |
2075 | 8.20M | } |
2076 | 8.20M | } |
2077 | 948 | NextCursor: ; |
2078 | 948 | } |
2079 | 173 | } |
2080 | | |
2081 | | namespace { |
2082 | | |
2083 | | /// Visitor class used to look up identifirs in an AST file. |
2084 | | class IdentifierLookupVisitor { |
2085 | | StringRef Name; |
2086 | | unsigned NameHash; |
2087 | | unsigned PriorGeneration; |
2088 | | unsigned &NumIdentifierLookups; |
2089 | | unsigned &NumIdentifierLookupHits; |
2090 | | IdentifierInfo *Found = nullptr; |
2091 | | |
2092 | | public: |
2093 | | IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration, |
2094 | | unsigned &NumIdentifierLookups, |
2095 | | unsigned &NumIdentifierLookupHits) |
2096 | 5.32M | : Name(Name), NameHash(ASTIdentifierLookupTrait::ComputeHash(Name)), |
2097 | 5.32M | PriorGeneration(PriorGeneration), |
2098 | 5.32M | NumIdentifierLookups(NumIdentifierLookups), |
2099 | 5.32M | NumIdentifierLookupHits(NumIdentifierLookupHits) {} |
2100 | | |
2101 | 7.47M | bool operator()(ModuleFile &M) { |
2102 | | // If we've already searched this module file, skip it now. |
2103 | 7.47M | if (M.Generation <= PriorGeneration) |
2104 | 6.98k | return true; |
2105 | | |
2106 | 7.46M | ASTIdentifierLookupTable *IdTable |
2107 | 7.46M | = (ASTIdentifierLookupTable *)M.IdentifierLookupTable; |
2108 | 7.46M | if (!IdTable) |
2109 | 0 | return false; |
2110 | | |
2111 | 7.46M | ASTIdentifierLookupTrait Trait(IdTable->getInfoObj().getReader(), M, |
2112 | 7.46M | Found); |
2113 | 7.46M | ++NumIdentifierLookups; |
2114 | 7.46M | ASTIdentifierLookupTable::iterator Pos = |
2115 | 7.46M | IdTable->find_hashed(Name, NameHash, &Trait); |
2116 | 7.46M | if (Pos == IdTable->end()) |
2117 | 5.61M | return false; |
2118 | | |
2119 | | // Dereferencing the iterator has the effect of building the |
2120 | | // IdentifierInfo node and populating it with the various |
2121 | | // declarations it needs. |
2122 | 1.84M | ++NumIdentifierLookupHits; |
2123 | 1.84M | Found = *Pos; |
2124 | 1.84M | return true; |
2125 | 7.46M | } |
2126 | | |
2127 | | // Retrieve the identifier info found within the module |
2128 | | // files. |
2129 | 4.94M | IdentifierInfo *getIdentifierInfo() const { return Found; } |
2130 | | }; |
2131 | | |
2132 | | } // namespace |
2133 | | |
2134 | 382k | void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) { |
2135 | | // Note that we are loading an identifier. |
2136 | 382k | Deserializing AnIdentifier(this); |
2137 | | |
2138 | 382k | unsigned PriorGeneration = 0; |
2139 | 382k | if (getContext().getLangOpts().Modules) |
2140 | 355k | PriorGeneration = IdentifierGeneration[&II]; |
2141 | | |
2142 | | // If there is a global index, look there first to determine which modules |
2143 | | // provably do not have any results for this identifier. |
2144 | 382k | GlobalModuleIndex::HitSet Hits; |
2145 | 382k | GlobalModuleIndex::HitSet *HitsPtr = nullptr; |
2146 | 382k | if (!loadGlobalIndex()) { |
2147 | 23.2k | if (GlobalIndex->lookupIdentifier(II.getName(), Hits)) { |
2148 | 22.5k | HitsPtr = &Hits; |
2149 | 22.5k | } |
2150 | 23.2k | } |
2151 | | |
2152 | 382k | IdentifierLookupVisitor Visitor(II.getName(), PriorGeneration, |
2153 | 382k | NumIdentifierLookups, |
2154 | 382k | NumIdentifierLookupHits); |
2155 | 382k | ModuleMgr.visit(Visitor, HitsPtr); |
2156 | 382k | markIdentifierUpToDate(&II); |
2157 | 382k | } |
2158 | | |
2159 | 7.17M | void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) { |
2160 | 7.17M | if (!II) |
2161 | 4.17M | return; |
2162 | | |
2163 | 2.99M | II->setOutOfDate(false); |
2164 | | |
2165 | | // Update the generation for this identifier. |
2166 | 2.99M | if (getContext().getLangOpts().Modules) |
2167 | 2.30M | IdentifierGeneration[II] = getGeneration(); |
2168 | 2.99M | } |
2169 | | |
2170 | | void ASTReader::resolvePendingMacro(IdentifierInfo *II, |
2171 | 1.11M | const PendingMacroInfo &PMInfo) { |
2172 | 1.11M | ModuleFile &M = *PMInfo.M; |
2173 | | |
2174 | 1.11M | BitstreamCursor &Cursor = M.MacroCursor; |
2175 | 1.11M | SavedStreamPosition SavedPosition(Cursor); |
2176 | 1.11M | if (llvm::Error Err = |
2177 | 1.11M | Cursor.JumpToBit(M.MacroOffsetsBase + PMInfo.MacroDirectivesOffset)) { |
2178 | 0 | Error(std::move(Err)); |
2179 | 0 | return; |
2180 | 0 | } |
2181 | | |
2182 | 1.11M | struct ModuleMacroRecord { |
2183 | 1.11M | SubmoduleID SubModID; |
2184 | 1.11M | MacroInfo *MI; |
2185 | 1.11M | SmallVector<SubmoduleID, 8> Overrides; |
2186 | 1.11M | }; |
2187 | 1.11M | llvm::SmallVector<ModuleMacroRecord, 8> ModuleMacros; |
2188 | | |
2189 | | // We expect to see a sequence of PP_MODULE_MACRO records listing exported |
2190 | | // macros, followed by a PP_MACRO_DIRECTIVE_HISTORY record with the complete |
2191 | | // macro histroy. |
2192 | 1.11M | RecordData Record; |
2193 | 29.8M | while (true) { |
2194 | 29.8M | Expected<llvm::BitstreamEntry> MaybeEntry = |
2195 | 29.8M | Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd); |
2196 | 29.8M | if (!MaybeEntry) { |
2197 | 0 | Error(MaybeEntry.takeError()); |
2198 | 0 | return; |
2199 | 0 | } |
2200 | 29.8M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
2201 | | |
2202 | 29.8M | if (Entry.Kind != llvm::BitstreamEntry::Record) { |
2203 | 0 | Error("malformed block record in AST file"); |
2204 | 0 | return; |
2205 | 0 | } |
2206 | | |
2207 | 29.8M | Record.clear(); |
2208 | 29.8M | Expected<unsigned> MaybePP = Cursor.readRecord(Entry.ID, Record); |
2209 | 29.8M | if (!MaybePP) { |
2210 | 0 | Error(MaybePP.takeError()); |
2211 | 0 | return; |
2212 | 0 | } |
2213 | 29.8M | switch ((PreprocessorRecordTypes)MaybePP.get()) { |
2214 | 1.11M | case PP_MACRO_DIRECTIVE_HISTORY: |
2215 | 1.11M | break; |
2216 | | |
2217 | 28.7M | case PP_MODULE_MACRO: { |
2218 | 28.7M | ModuleMacros.push_back(ModuleMacroRecord()); |
2219 | 28.7M | auto &Info = ModuleMacros.back(); |
2220 | 28.7M | Info.SubModID = getGlobalSubmoduleID(M, Record[0]); |
2221 | 28.7M | Info.MI = getMacro(getGlobalMacroID(M, Record[1])); |
2222 | 28.7M | for (int I = 2, N = Record.size(); I != N; ++I2.09k ) |
2223 | 2.09k | Info.Overrides.push_back(getGlobalSubmoduleID(M, Record[I])); |
2224 | 28.7M | continue; |
2225 | 0 | } |
2226 | | |
2227 | 0 | default: |
2228 | 0 | Error("malformed block record in AST file"); |
2229 | 0 | return; |
2230 | 29.8M | } |
2231 | | |
2232 | | // We found the macro directive history; that's the last record |
2233 | | // for this macro. |
2234 | 1.11M | break; |
2235 | 29.8M | } |
2236 | | |
2237 | | // Module macros are listed in reverse dependency order. |
2238 | 1.11M | { |
2239 | 1.11M | std::reverse(ModuleMacros.begin(), ModuleMacros.end()); |
2240 | 1.11M | llvm::SmallVector<ModuleMacro*, 8> Overrides; |
2241 | 28.7M | for (auto &MMR : ModuleMacros) { |
2242 | 28.7M | Overrides.clear(); |
2243 | 28.7M | for (unsigned ModID : MMR.Overrides) { |
2244 | 2.09k | Module *Mod = getSubmodule(ModID); |
2245 | 2.09k | auto *Macro = PP.getModuleMacro(Mod, II); |
2246 | 2.09k | assert(Macro && "missing definition for overridden macro"); |
2247 | 2.09k | Overrides.push_back(Macro); |
2248 | 2.09k | } |
2249 | | |
2250 | 28.7M | bool Inserted = false; |
2251 | 28.7M | Module *Owner = getSubmodule(MMR.SubModID); |
2252 | 28.7M | PP.addModuleMacro(Owner, II, MMR.MI, Overrides, Inserted); |
2253 | 28.7M | } |
2254 | 1.11M | } |
2255 | | |
2256 | | // Don't read the directive history for a module; we don't have anywhere |
2257 | | // to put it. |
2258 | 1.11M | if (M.isModule()) |
2259 | 1.06M | return; |
2260 | | |
2261 | | // Deserialize the macro directives history in reverse source-order. |
2262 | 49.0k | MacroDirective *Latest = nullptr, *Earliest = nullptr; |
2263 | 49.0k | unsigned Idx = 0, N = Record.size(); |
2264 | 98.2k | while (Idx < N) { |
2265 | 49.1k | MacroDirective *MD = nullptr; |
2266 | 49.1k | SourceLocation Loc = ReadSourceLocation(M, Record, Idx); |
2267 | 49.1k | MacroDirective::Kind K = (MacroDirective::Kind)Record[Idx++]; |
2268 | 49.1k | switch (K) { |
2269 | 49.0k | case MacroDirective::MD_Define: { |
2270 | 49.0k | MacroInfo *MI = getMacro(getGlobalMacroID(M, Record[Idx++])); |
2271 | 49.0k | MD = PP.AllocateDefMacroDirective(MI, Loc); |
2272 | 49.0k | break; |
2273 | 0 | } |
2274 | 31 | case MacroDirective::MD_Undefine: |
2275 | 31 | MD = PP.AllocateUndefMacroDirective(Loc); |
2276 | 31 | break; |
2277 | 4 | case MacroDirective::MD_Visibility: |
2278 | 4 | bool isPublic = Record[Idx++]; |
2279 | 4 | MD = PP.AllocateVisibilityMacroDirective(Loc, isPublic); |
2280 | 4 | break; |
2281 | 49.1k | } |
2282 | | |
2283 | 49.1k | if (!Latest) |
2284 | 49.0k | Latest = MD; |
2285 | 49.1k | if (Earliest) |
2286 | 46 | Earliest->setPrevious(MD); |
2287 | 49.1k | Earliest = MD; |
2288 | 49.1k | } |
2289 | | |
2290 | 49.0k | if (Latest) |
2291 | 49.0k | PP.setLoadedMacroDirective(II, Earliest, Latest); |
2292 | 49.0k | } |
2293 | | |
2294 | | bool ASTReader::shouldDisableValidationForFile( |
2295 | 2.45M | const serialization::ModuleFile &M) const { |
2296 | 2.45M | if (DisableValidationKind == DisableValidationForModuleKind::None) |
2297 | 2.45M | return false; |
2298 | | |
2299 | | // If a PCH is loaded and validation is disabled for PCH then disable |
2300 | | // validation for the PCH and the modules it loads. |
2301 | 1.57k | ModuleKind K = CurrentDeserializingModuleKind.value_or(M.Kind); |
2302 | | |
2303 | 1.57k | switch (K) { |
2304 | 0 | case MK_MainFile: |
2305 | 1.12k | case MK_Preamble: |
2306 | 1.50k | case MK_PCH: |
2307 | 1.50k | return bool(DisableValidationKind & DisableValidationForModuleKind::PCH); |
2308 | 59 | case MK_ImplicitModule: |
2309 | 65 | case MK_ExplicitModule: |
2310 | 65 | case MK_PrebuiltModule: |
2311 | 65 | return bool(DisableValidationKind & DisableValidationForModuleKind::Module); |
2312 | 1.57k | } |
2313 | | |
2314 | 0 | return false; |
2315 | 1.57k | } |
2316 | | |
2317 | 1.51M | InputFileInfo ASTReader::getInputFileInfo(ModuleFile &F, unsigned ID) { |
2318 | | // If this ID is bogus, just return an empty input file. |
2319 | 1.51M | if (ID == 0 || ID > F.InputFileInfosLoaded.size()) |
2320 | 0 | return InputFileInfo(); |
2321 | | |
2322 | | // If we've already loaded this input file, return it. |
2323 | 1.51M | if (!F.InputFileInfosLoaded[ID - 1].Filename.empty()) |
2324 | 12.9k | return F.InputFileInfosLoaded[ID - 1]; |
2325 | | |
2326 | | // Go find this input file. |
2327 | 1.50M | BitstreamCursor &Cursor = F.InputFilesCursor; |
2328 | 1.50M | SavedStreamPosition SavedPosition(Cursor); |
2329 | 1.50M | if (llvm::Error Err = Cursor.JumpToBit(F.InputFilesOffsetBase + |
2330 | 1.50M | F.InputFileOffsets[ID - 1])) { |
2331 | | // FIXME this drops errors on the floor. |
2332 | 0 | consumeError(std::move(Err)); |
2333 | 0 | } |
2334 | | |
2335 | 1.50M | Expected<unsigned> MaybeCode = Cursor.ReadCode(); |
2336 | 1.50M | if (!MaybeCode) { |
2337 | | // FIXME this drops errors on the floor. |
2338 | 0 | consumeError(MaybeCode.takeError()); |
2339 | 0 | } |
2340 | 1.50M | unsigned Code = MaybeCode.get(); |
2341 | 1.50M | RecordData Record; |
2342 | 1.50M | StringRef Blob; |
2343 | | |
2344 | 1.50M | if (Expected<unsigned> Maybe = Cursor.readRecord(Code, Record, &Blob)) |
2345 | 1.50M | assert(static_cast<InputFileRecordTypes>(Maybe.get()) == INPUT_FILE && |
2346 | 1.50M | "invalid record type for input file"); |
2347 | 1 | else { |
2348 | | // FIXME this drops errors on the floor. |
2349 | 1 | consumeError(Maybe.takeError()); |
2350 | 1 | } |
2351 | | |
2352 | 1.50M | assert(Record[0] == ID && "Bogus stored ID or offset"); |
2353 | 1.50M | InputFileInfo R; |
2354 | 1.50M | R.StoredSize = static_cast<off_t>(Record[1]); |
2355 | 1.50M | R.StoredTime = static_cast<time_t>(Record[2]); |
2356 | 1.50M | R.Overridden = static_cast<bool>(Record[3]); |
2357 | 1.50M | R.Transient = static_cast<bool>(Record[4]); |
2358 | 1.50M | R.TopLevel = static_cast<bool>(Record[5]); |
2359 | 1.50M | R.ModuleMap = static_cast<bool>(Record[6]); |
2360 | 1.50M | std::tie(R.FilenameAsRequested, R.Filename) = [&]() { |
2361 | 1.50M | uint16_t AsRequestedLength = Record[7]; |
2362 | | |
2363 | 1.50M | std::string NameAsRequested = Blob.substr(0, AsRequestedLength).str(); |
2364 | 1.50M | std::string Name = Blob.substr(AsRequestedLength).str(); |
2365 | | |
2366 | 1.50M | ResolveImportedPath(F, NameAsRequested); |
2367 | 1.50M | ResolveImportedPath(F, Name); |
2368 | | |
2369 | 1.50M | if (Name.empty()) |
2370 | 1.50M | Name = NameAsRequested; |
2371 | | |
2372 | 1.50M | return std::make_pair(std::move(NameAsRequested), std::move(Name)); |
2373 | 1.50M | }(); |
2374 | | |
2375 | 1.50M | Expected<llvm::BitstreamEntry> MaybeEntry = Cursor.advance(); |
2376 | 1.50M | if (!MaybeEntry) // FIXME this drops errors on the floor. |
2377 | 0 | consumeError(MaybeEntry.takeError()); |
2378 | 1.50M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
2379 | 1.50M | assert(Entry.Kind == llvm::BitstreamEntry::Record && |
2380 | 1.50M | "expected record type for input file hash"); |
2381 | | |
2382 | 1.50M | Record.clear(); |
2383 | 1.50M | if (Expected<unsigned> Maybe = Cursor.readRecord(Entry.ID, Record)) |
2384 | 1.50M | assert(static_cast<InputFileRecordTypes>(Maybe.get()) == INPUT_FILE_HASH && |
2385 | 1.50M | "invalid record type for input file hash"); |
2386 | 0 | else { |
2387 | | // FIXME this drops errors on the floor. |
2388 | 0 | consumeError(Maybe.takeError()); |
2389 | 0 | } |
2390 | 1.50M | R.ContentHash = (static_cast<uint64_t>(Record[1]) << 32) | |
2391 | 1.50M | static_cast<uint64_t>(Record[0]); |
2392 | | |
2393 | | // Note that we've loaded this input file info. |
2394 | 1.50M | F.InputFileInfosLoaded[ID - 1] = R; |
2395 | 1.50M | return R; |
2396 | 1.50M | } |
2397 | | |
2398 | | static unsigned moduleKindForDiagnostic(ModuleKind Kind); |
2399 | 1.63M | InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { |
2400 | | // If this ID is bogus, just return an empty input file. |
2401 | 1.63M | if (ID == 0 || ID > F.InputFilesLoaded.size()) |
2402 | 0 | return InputFile(); |
2403 | | |
2404 | | // If we've already loaded this input file, return it. |
2405 | 1.63M | if (F.InputFilesLoaded[ID-1].getFile()) |
2406 | 128k | return F.InputFilesLoaded[ID-1]; |
2407 | | |
2408 | 1.50M | if (F.InputFilesLoaded[ID-1].isNotFound()) |
2409 | 21 | return InputFile(); |
2410 | | |
2411 | | // Go find this input file. |
2412 | 1.50M | BitstreamCursor &Cursor = F.InputFilesCursor; |
2413 | 1.50M | SavedStreamPosition SavedPosition(Cursor); |
2414 | 1.50M | if (llvm::Error Err = Cursor.JumpToBit(F.InputFilesOffsetBase + |
2415 | 1.50M | F.InputFileOffsets[ID - 1])) { |
2416 | | // FIXME this drops errors on the floor. |
2417 | 0 | consumeError(std::move(Err)); |
2418 | 0 | } |
2419 | | |
2420 | 1.50M | InputFileInfo FI = getInputFileInfo(F, ID); |
2421 | 1.50M | off_t StoredSize = FI.StoredSize; |
2422 | 1.50M | time_t StoredTime = FI.StoredTime; |
2423 | 1.50M | bool Overridden = FI.Overridden; |
2424 | 1.50M | bool Transient = FI.Transient; |
2425 | 1.50M | StringRef Filename = FI.FilenameAsRequested; |
2426 | 1.50M | uint64_t StoredContentHash = FI.ContentHash; |
2427 | | |
2428 | | // For standard C++ modules, we don't need to check the inputs. |
2429 | 1.50M | bool SkipChecks = F.StandardCXXModule; |
2430 | | |
2431 | 1.50M | const HeaderSearchOptions &HSOpts = |
2432 | 1.50M | PP.getHeaderSearchInfo().getHeaderSearchOpts(); |
2433 | | |
2434 | | // The option ForceCheckCXX20ModulesInputFiles is only meaningful for C++20 |
2435 | | // modules. |
2436 | 1.50M | if (F.StandardCXXModule && HSOpts.ForceCheckCXX20ModulesInputFiles337 ) { |
2437 | 2 | SkipChecks = false; |
2438 | 2 | Overridden = false; |
2439 | 2 | } |
2440 | | |
2441 | 1.50M | OptionalFileEntryRefDegradesToFileEntryPtr File = OptionalFileEntryRef( |
2442 | 1.50M | expectedToOptional(FileMgr.getFileRef(Filename, /*OpenFile=*/false))); |
2443 | | |
2444 | | // For an overridden file, create a virtual file with the stored |
2445 | | // size/timestamp. |
2446 | 1.50M | if ((Overridden || Transient1.50M || SkipChecks1.50M ) && !File766 ) |
2447 | 78 | File = FileMgr.getVirtualFileRef(Filename, StoredSize, StoredTime); |
2448 | | |
2449 | 1.50M | if (!File) { |
2450 | 5 | if (Complain) { |
2451 | 5 | std::string ErrorStr = "could not find file '"; |
2452 | 5 | ErrorStr += Filename; |
2453 | 5 | ErrorStr += "' referenced by AST file '"; |
2454 | 5 | ErrorStr += F.FileName; |
2455 | 5 | ErrorStr += "'"; |
2456 | 5 | Error(ErrorStr); |
2457 | 5 | } |
2458 | | // Record that we didn't find the file. |
2459 | 5 | F.InputFilesLoaded[ID-1] = InputFile::getNotFound(); |
2460 | 5 | return InputFile(); |
2461 | 5 | } |
2462 | | |
2463 | | // Check if there was a request to override the contents of the file |
2464 | | // that was part of the precompiled header. Overriding such a file |
2465 | | // can lead to problems when lexing using the source locations from the |
2466 | | // PCH. |
2467 | 1.50M | SourceManager &SM = getSourceManager(); |
2468 | | // FIXME: Reject if the overrides are different. |
2469 | 1.50M | if ((!Overridden && !Transient1.50M ) && !SkipChecks1.50M && SM.isFileOverridden(File)1.50M ) { |
2470 | 1 | if (Complain) |
2471 | 1 | Error(diag::err_fe_pch_file_overridden, Filename); |
2472 | | |
2473 | | // After emitting the diagnostic, bypass the overriding file to recover |
2474 | | // (this creates a separate FileEntry). |
2475 | 1 | File = SM.bypassFileContentsOverride(*File); |
2476 | 1 | if (!File) { |
2477 | 0 | F.InputFilesLoaded[ID - 1] = InputFile::getNotFound(); |
2478 | 0 | return InputFile(); |
2479 | 0 | } |
2480 | 1 | } |
2481 | | |
2482 | 1.50M | struct Change { |
2483 | 1.50M | enum ModificationKind { |
2484 | 1.50M | Size, |
2485 | 1.50M | ModTime, |
2486 | 1.50M | Content, |
2487 | 1.50M | None, |
2488 | 1.50M | } Kind; |
2489 | 1.50M | std::optional<int64_t> Old = std::nullopt; |
2490 | 1.50M | std::optional<int64_t> New = std::nullopt; |
2491 | 1.50M | }; |
2492 | 1.50M | auto HasInputContentChanged = [&](Change OriginalChange) { |
2493 | 5 | assert(ValidateASTInputFilesContent && |
2494 | 5 | "We should only check the content of the inputs with " |
2495 | 5 | "ValidateASTInputFilesContent enabled."); |
2496 | | |
2497 | 5 | if (StoredContentHash == static_cast<uint64_t>(llvm::hash_code(-1))) |
2498 | 0 | return OriginalChange; |
2499 | | |
2500 | 5 | auto MemBuffOrError = FileMgr.getBufferForFile(*File); |
2501 | 5 | if (!MemBuffOrError) { |
2502 | 0 | if (!Complain) |
2503 | 0 | return OriginalChange; |
2504 | 0 | std::string ErrorStr = "could not get buffer for file '"; |
2505 | 0 | ErrorStr += File->getName(); |
2506 | 0 | ErrorStr += "'"; |
2507 | 0 | Error(ErrorStr); |
2508 | 0 | return OriginalChange; |
2509 | 0 | } |
2510 | | |
2511 | | // FIXME: hash_value is not guaranteed to be stable! |
2512 | 5 | auto ContentHash = hash_value(MemBuffOrError.get()->getBuffer()); |
2513 | 5 | if (StoredContentHash == static_cast<uint64_t>(ContentHash)) |
2514 | 2 | return Change{Change::None}; |
2515 | | |
2516 | 3 | return Change{Change::Content}; |
2517 | 5 | }; |
2518 | 1.50M | auto HasInputFileChanged = [&]() { |
2519 | 1.50M | if (StoredSize != File->getSize()) |
2520 | 232 | return Change{Change::Size, StoredSize, File->getSize()}; |
2521 | 1.50M | if (!shouldDisableValidationForFile(F) && StoredTime1.50M && |
2522 | 1.50M | StoredTime != File->getModificationTime()1.50M ) { |
2523 | 5 | Change MTimeChange = {Change::ModTime, StoredTime, |
2524 | 5 | File->getModificationTime()}; |
2525 | | |
2526 | | // In case the modification time changes but not the content, |
2527 | | // accept the cached file as legit. |
2528 | 5 | if (ValidateASTInputFilesContent) |
2529 | 4 | return HasInputContentChanged(MTimeChange); |
2530 | | |
2531 | 1 | return MTimeChange; |
2532 | 5 | } |
2533 | 1.50M | return Change{Change::None}; |
2534 | 1.50M | }; |
2535 | | |
2536 | 1.50M | bool IsOutOfDate = false; |
2537 | 1.50M | auto FileChange = SkipChecks ? Change{Change::None}335 : HasInputFileChanged()1.50M ; |
2538 | | // When ForceCheckCXX20ModulesInputFiles and ValidateASTInputFilesContent |
2539 | | // enabled, it is better to check the contents of the inputs. Since we can't |
2540 | | // get correct modified time information for inputs from overriden inputs. |
2541 | 1.50M | if (HSOpts.ForceCheckCXX20ModulesInputFiles && ValidateASTInputFilesContent2 && |
2542 | 1.50M | F.StandardCXXModule1 && FileChange.Kind == Change::None1 ) |
2543 | 1 | FileChange = HasInputContentChanged(FileChange); |
2544 | | |
2545 | | // For an overridden file, there is nothing to validate. |
2546 | 1.50M | if (!Overridden && FileChange.Kind != Change::None1.50M ) { |
2547 | 39 | if (Complain && !Diags.isDiagnosticInFlight()12 ) { |
2548 | | // Build a list of the PCH imports that got us here (in reverse). |
2549 | 12 | SmallVector<ModuleFile *, 4> ImportStack(1, &F); |
2550 | 14 | while (!ImportStack.back()->ImportedBy.empty()) |
2551 | 2 | ImportStack.push_back(ImportStack.back()->ImportedBy[0]); |
2552 | | |
2553 | | // The top-level PCH is stale. |
2554 | 12 | StringRef TopLevelPCHName(ImportStack.back()->FileName); |
2555 | 12 | Diag(diag::err_fe_ast_file_modified) |
2556 | 12 | << Filename << moduleKindForDiagnostic(ImportStack.back()->Kind) |
2557 | 12 | << TopLevelPCHName << FileChange.Kind |
2558 | 12 | << (FileChange.Old && FileChange.New9 ) |
2559 | 12 | << llvm::itostr(FileChange.Old.value_or(0)) |
2560 | 12 | << llvm::itostr(FileChange.New.value_or(0)); |
2561 | | |
2562 | | // Print the import stack. |
2563 | 12 | if (ImportStack.size() > 1) { |
2564 | 2 | Diag(diag::note_pch_required_by) |
2565 | 2 | << Filename << ImportStack[0]->FileName; |
2566 | 4 | for (unsigned I = 1; I < ImportStack.size(); ++I2 ) |
2567 | 2 | Diag(diag::note_pch_required_by) |
2568 | 2 | << ImportStack[I-1]->FileName << ImportStack[I]->FileName; |
2569 | 2 | } |
2570 | | |
2571 | 12 | Diag(diag::note_pch_rebuild_required) << TopLevelPCHName; |
2572 | 12 | } |
2573 | | |
2574 | 39 | IsOutOfDate = true; |
2575 | 39 | } |
2576 | | // FIXME: If the file is overridden and we've already opened it, |
2577 | | // issue an error (or split it into a separate FileEntry). |
2578 | | |
2579 | 1.50M | InputFile IF = InputFile(*File, Overridden || Transient1.50M , IsOutOfDate); |
2580 | | |
2581 | | // Note that we've loaded this input file. |
2582 | 1.50M | F.InputFilesLoaded[ID-1] = IF; |
2583 | 1.50M | return IF; |
2584 | 1.50M | } |
2585 | | |
2586 | | /// If we are loading a relocatable PCH or module file, and the filename |
2587 | | /// is not an absolute path, add the system or module root to the beginning of |
2588 | | /// the file name. |
2589 | 7.51M | void ASTReader::ResolveImportedPath(ModuleFile &M, std::string &Filename) { |
2590 | | // Resolve relative to the base directory, if we have one. |
2591 | 7.51M | if (!M.BaseDirectory.empty()) |
2592 | 7.46M | return ResolveImportedPath(Filename, M.BaseDirectory); |
2593 | 7.51M | } |
2594 | | |
2595 | 10.7M | void ASTReader::ResolveImportedPath(std::string &Filename, StringRef Prefix) { |
2596 | 10.7M | if (Filename.empty() || llvm::sys::path::is_absolute(Filename)9.27M || |
2597 | 10.7M | Filename == "<built-in>"5.91M || Filename == "<command line>"5.44M ) |
2598 | 5.80M | return; |
2599 | | |
2600 | 4.96M | SmallString<128> Buffer; |
2601 | 4.96M | llvm::sys::path::append(Buffer, Prefix, Filename); |
2602 | 4.96M | Filename.assign(Buffer.begin(), Buffer.end()); |
2603 | 4.96M | } |
2604 | | |
2605 | 3.30M | static bool isDiagnosedResult(ASTReader::ASTReadResult ARR, unsigned Caps) { |
2606 | 3.30M | switch (ARR) { |
2607 | 6 | case ASTReader::Failure: return true; |
2608 | 1 | case ASTReader::Missing: return !(Caps & ASTReader::ARR_Missing); |
2609 | 38 | case ASTReader::OutOfDate: return !(Caps & ASTReader::ARR_OutOfDate); |
2610 | 0 | case ASTReader::VersionMismatch: return !(Caps & ASTReader::ARR_VersionMismatch); |
2611 | 0 | case ASTReader::ConfigurationMismatch: |
2612 | 0 | return !(Caps & ASTReader::ARR_ConfigurationMismatch); |
2613 | 0 | case ASTReader::HadErrors: return true; |
2614 | 3.30M | case ASTReader::Success: return false; |
2615 | 3.30M | } |
2616 | | |
2617 | 0 | llvm_unreachable("unknown ASTReadResult"); |
2618 | 0 | } |
2619 | | |
2620 | | ASTReader::ASTReadResult ASTReader::ReadOptionsBlock( |
2621 | | BitstreamCursor &Stream, unsigned ClientLoadCapabilities, |
2622 | | bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener, |
2623 | 12.6k | std::string &SuggestedPredefines) { |
2624 | 12.6k | if (llvm::Error Err = Stream.EnterSubBlock(OPTIONS_BLOCK_ID)) { |
2625 | | // FIXME this drops errors on the floor. |
2626 | 0 | consumeError(std::move(Err)); |
2627 | 0 | return Failure; |
2628 | 0 | } |
2629 | | |
2630 | | // Read all of the records in the options block. |
2631 | 12.6k | RecordData Record; |
2632 | 12.6k | ASTReadResult Result = Success; |
2633 | 75.8k | while (true) { |
2634 | 75.8k | Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); |
2635 | 75.8k | if (!MaybeEntry) { |
2636 | | // FIXME this drops errors on the floor. |
2637 | 0 | consumeError(MaybeEntry.takeError()); |
2638 | 0 | return Failure; |
2639 | 0 | } |
2640 | 75.8k | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
2641 | | |
2642 | 75.8k | switch (Entry.Kind) { |
2643 | 0 | case llvm::BitstreamEntry::Error: |
2644 | 0 | case llvm::BitstreamEntry::SubBlock: |
2645 | 0 | return Failure; |
2646 | | |
2647 | 12.6k | case llvm::BitstreamEntry::EndBlock: |
2648 | 12.6k | return Result; |
2649 | | |
2650 | 63.2k | case llvm::BitstreamEntry::Record: |
2651 | | // The interesting case. |
2652 | 63.2k | break; |
2653 | 75.8k | } |
2654 | | |
2655 | | // Read and process a record. |
2656 | 63.2k | Record.clear(); |
2657 | 63.2k | Expected<unsigned> MaybeRecordType = Stream.readRecord(Entry.ID, Record); |
2658 | 63.2k | if (!MaybeRecordType) { |
2659 | | // FIXME this drops errors on the floor. |
2660 | 0 | consumeError(MaybeRecordType.takeError()); |
2661 | 0 | return Failure; |
2662 | 0 | } |
2663 | 63.2k | switch ((OptionsRecordTypes)MaybeRecordType.get()) { |
2664 | 12.6k | case LANGUAGE_OPTIONS: { |
2665 | 12.6k | bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; |
2666 | 12.6k | if (ParseLanguageOptions(Record, Complain, Listener, |
2667 | 12.6k | AllowCompatibleConfigurationMismatch)) |
2668 | 29 | Result = ConfigurationMismatch; |
2669 | 12.6k | break; |
2670 | 0 | } |
2671 | | |
2672 | 12.6k | case TARGET_OPTIONS: { |
2673 | 12.6k | bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; |
2674 | 12.6k | if (ParseTargetOptions(Record, Complain, Listener, |
2675 | 12.6k | AllowCompatibleConfigurationMismatch)) |
2676 | 7 | Result = ConfigurationMismatch; |
2677 | 12.6k | break; |
2678 | 0 | } |
2679 | | |
2680 | 12.6k | case FILE_SYSTEM_OPTIONS: { |
2681 | 12.6k | bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; |
2682 | 12.6k | if (!AllowCompatibleConfigurationMismatch && |
2683 | 12.6k | ParseFileSystemOptions(Record, Complain, Listener)11.7k ) |
2684 | 0 | Result = ConfigurationMismatch; |
2685 | 12.6k | break; |
2686 | 0 | } |
2687 | | |
2688 | 12.6k | case HEADER_SEARCH_OPTIONS: { |
2689 | 12.6k | bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; |
2690 | 12.6k | if (!AllowCompatibleConfigurationMismatch && |
2691 | 12.6k | ParseHeaderSearchOptions(Record, Complain, Listener)11.7k ) |
2692 | 3 | Result = ConfigurationMismatch; |
2693 | 12.6k | break; |
2694 | 0 | } |
2695 | | |
2696 | 12.6k | case PREPROCESSOR_OPTIONS: |
2697 | 12.6k | bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; |
2698 | 12.6k | if (!AllowCompatibleConfigurationMismatch && |
2699 | 12.6k | ParsePreprocessorOptions(Record, Complain, Listener, |
2700 | 11.7k | SuggestedPredefines)) |
2701 | 19 | Result = ConfigurationMismatch; |
2702 | 12.6k | break; |
2703 | 63.2k | } |
2704 | 63.2k | } |
2705 | 12.6k | } |
2706 | | |
2707 | | ASTReader::ASTReadResult |
2708 | | ASTReader::ReadControlBlock(ModuleFile &F, |
2709 | | SmallVectorImpl<ImportedModule> &Loaded, |
2710 | | const ModuleFile *ImportedBy, |
2711 | 477k | unsigned ClientLoadCapabilities) { |
2712 | 477k | BitstreamCursor &Stream = F.Stream; |
2713 | | |
2714 | 477k | if (llvm::Error Err = Stream.EnterSubBlock(CONTROL_BLOCK_ID)) { |
2715 | 0 | Error(std::move(Err)); |
2716 | 0 | return Failure; |
2717 | 0 | } |
2718 | | |
2719 | | // Lambda to read the unhashed control block the first time it's called. |
2720 | | // |
2721 | | // For PCM files, the unhashed control block cannot be read until after the |
2722 | | // MODULE_NAME record. However, PCH files have no MODULE_NAME, and yet still |
2723 | | // need to look ahead before reading the IMPORTS record. For consistency, |
2724 | | // this block is always read somehow (see BitstreamEntry::EndBlock). |
2725 | 477k | bool HasReadUnhashedControlBlock = false; |
2726 | 1.42M | auto readUnhashedControlBlockOnce = [&]() { |
2727 | 1.42M | if (!HasReadUnhashedControlBlock) { |
2728 | 477k | HasReadUnhashedControlBlock = true; |
2729 | 477k | if (ASTReadResult Result = |
2730 | 477k | readUnhashedControlBlock(F, ImportedBy, ClientLoadCapabilities)) |
2731 | 11 | return Result; |
2732 | 477k | } |
2733 | 1.42M | return Success; |
2734 | 1.42M | }; |
2735 | | |
2736 | 477k | bool DisableValidation = shouldDisableValidationForFile(F); |
2737 | | |
2738 | | // Read all of the records and blocks in the control block. |
2739 | 477k | RecordData Record; |
2740 | 477k | unsigned NumInputs = 0; |
2741 | 477k | unsigned NumUserInputs = 0; |
2742 | 477k | StringRef BaseDirectoryAsWritten; |
2743 | 4.76M | while (true) { |
2744 | 4.76M | Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); |
2745 | 4.76M | if (!MaybeEntry) { |
2746 | 0 | Error(MaybeEntry.takeError()); |
2747 | 0 | return Failure; |
2748 | 0 | } |
2749 | 4.76M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
2750 | | |
2751 | 4.76M | switch (Entry.Kind) { |
2752 | 0 | case llvm::BitstreamEntry::Error: |
2753 | 0 | Error("malformed block record in AST file"); |
2754 | 0 | return Failure; |
2755 | 477k | case llvm::BitstreamEntry::EndBlock: { |
2756 | | // Validate the module before returning. This call catches an AST with |
2757 | | // no module name and no imports. |
2758 | 477k | if (ASTReadResult Result = readUnhashedControlBlockOnce()) |
2759 | 0 | return Result; |
2760 | | |
2761 | | // Validate input files. |
2762 | 477k | const HeaderSearchOptions &HSOpts = |
2763 | 477k | PP.getHeaderSearchInfo().getHeaderSearchOpts(); |
2764 | | |
2765 | | // All user input files reside at the index range [0, NumUserInputs), and |
2766 | | // system input files reside at [NumUserInputs, NumInputs). For explicitly |
2767 | | // loaded module files, ignore missing inputs. |
2768 | 477k | if (!DisableValidation && F.Kind != MK_ExplicitModule477k && |
2769 | 477k | F.Kind != MK_PrebuiltModule475k ) { |
2770 | 475k | bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; |
2771 | | |
2772 | | // If we are reading a module, we will create a verification timestamp, |
2773 | | // so we verify all input files. Otherwise, verify only user input |
2774 | | // files. |
2775 | | |
2776 | 475k | unsigned N = ValidateSystemInputs ? NumInputs6.26k : NumUserInputs468k ; |
2777 | 475k | if (HSOpts.ModulesValidateOncePerBuildSession && |
2778 | 475k | F.InputFilesValidationTimestamp > HSOpts.BuildSessionTimestamp23 && |
2779 | 475k | F.Kind == MK_ImplicitModule12 ) |
2780 | 12 | N = NumUserInputs; |
2781 | | |
2782 | 629k | for (unsigned I = 0; I < N; ++I154k ) { |
2783 | 154k | InputFile IF = getInputFile(F, I+1, Complain); |
2784 | 154k | if (!IF.getFile() || IF.isOutOfDate()154k ) |
2785 | 39 | return OutOfDate; |
2786 | 154k | } |
2787 | 475k | } |
2788 | | |
2789 | 477k | if (Listener) |
2790 | 477k | Listener->visitModuleFile(F.FileName, F.Kind); |
2791 | | |
2792 | 477k | if (Listener && Listener->needsInputFileVisitation()) { |
2793 | 446 | unsigned N = Listener->needsSystemInputFileVisitation() ? NumInputs432 |
2794 | 446 | : NumUserInputs14 ; |
2795 | 12.7k | for (unsigned I = 0; I < N; ++I12.2k ) { |
2796 | 12.2k | bool IsSystem = I >= NumUserInputs; |
2797 | 12.2k | InputFileInfo FI = getInputFileInfo(F, I + 1); |
2798 | 12.2k | Listener->visitInputFile( |
2799 | 12.2k | FI.FilenameAsRequested, IsSystem, FI.Overridden, |
2800 | 12.2k | F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule12.2k ); |
2801 | 12.2k | } |
2802 | 446 | } |
2803 | | |
2804 | 477k | return Success; |
2805 | 477k | } |
2806 | | |
2807 | 955k | case llvm::BitstreamEntry::SubBlock: |
2808 | 955k | switch (Entry.ID) { |
2809 | 477k | case INPUT_FILES_BLOCK_ID: |
2810 | 477k | F.InputFilesCursor = Stream; |
2811 | 477k | if (llvm::Error Err = Stream.SkipBlock()) { |
2812 | 0 | Error(std::move(Err)); |
2813 | 0 | return Failure; |
2814 | 0 | } |
2815 | 477k | if (ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) { |
2816 | 0 | Error("malformed block record in AST file"); |
2817 | 0 | return Failure; |
2818 | 0 | } |
2819 | 477k | F.InputFilesOffsetBase = F.InputFilesCursor.GetCurrentBitNo(); |
2820 | 477k | continue; |
2821 | | |
2822 | 477k | case OPTIONS_BLOCK_ID: |
2823 | | // If we're reading the first module for this group, check its options |
2824 | | // are compatible with ours. For modules it imports, no further checking |
2825 | | // is required, because we checked them when we built it. |
2826 | 477k | if (Listener && !ImportedBy) { |
2827 | | // Should we allow the configuration of the module file to differ from |
2828 | | // the configuration of the current translation unit in a compatible |
2829 | | // way? |
2830 | | // |
2831 | | // FIXME: Allow this for files explicitly specified with -include-pch. |
2832 | 12.5k | bool AllowCompatibleConfigurationMismatch = |
2833 | 12.5k | F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule12.0k ; |
2834 | | |
2835 | 12.5k | ASTReadResult Result = |
2836 | 12.5k | ReadOptionsBlock(Stream, ClientLoadCapabilities, |
2837 | 12.5k | AllowCompatibleConfigurationMismatch, *Listener, |
2838 | 12.5k | SuggestedPredefines); |
2839 | 12.5k | if (Result == Failure) { |
2840 | 0 | Error("malformed block record in AST file"); |
2841 | 0 | return Result; |
2842 | 0 | } |
2843 | | |
2844 | 12.5k | if (DisableValidation || |
2845 | 12.5k | (12.1k AllowConfigurationMismatch12.1k && Result == ConfigurationMismatch6 )) |
2846 | 419 | Result = Success; |
2847 | | |
2848 | | // If we can't load the module, exit early since we likely |
2849 | | // will rebuild the module anyway. The stream may be in the |
2850 | | // middle of a block. |
2851 | 12.5k | if (Result != Success) |
2852 | 26 | return Result; |
2853 | 465k | } else if (llvm::Error Err = Stream.SkipBlock()) { |
2854 | 0 | Error(std::move(Err)); |
2855 | 0 | return Failure; |
2856 | 0 | } |
2857 | 477k | continue; |
2858 | | |
2859 | 477k | default: |
2860 | 0 | if (llvm::Error Err = Stream.SkipBlock()) { |
2861 | 0 | Error(std::move(Err)); |
2862 | 0 | return Failure; |
2863 | 0 | } |
2864 | 0 | continue; |
2865 | 955k | } |
2866 | | |
2867 | 3.33M | case llvm::BitstreamEntry::Record: |
2868 | | // The interesting case. |
2869 | 3.33M | break; |
2870 | 4.76M | } |
2871 | | |
2872 | | // Read and process a record. |
2873 | 3.33M | Record.clear(); |
2874 | 3.33M | StringRef Blob; |
2875 | 3.33M | Expected<unsigned> MaybeRecordType = |
2876 | 3.33M | Stream.readRecord(Entry.ID, Record, &Blob); |
2877 | 3.33M | if (!MaybeRecordType) { |
2878 | 0 | Error(MaybeRecordType.takeError()); |
2879 | 0 | return Failure; |
2880 | 0 | } |
2881 | 3.33M | switch ((ControlRecordTypes)MaybeRecordType.get()) { |
2882 | 477k | case METADATA: { |
2883 | 477k | if (Record[0] != VERSION_MAJOR && !DisableValidation0 ) { |
2884 | 0 | if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) |
2885 | 0 | Diag(Record[0] < VERSION_MAJOR? diag::err_pch_version_too_old |
2886 | 0 | : diag::err_pch_version_too_new); |
2887 | 0 | return VersionMismatch; |
2888 | 0 | } |
2889 | | |
2890 | 477k | bool hasErrors = Record[7]; |
2891 | 477k | if (hasErrors && !DisableValidation120 ) { |
2892 | | // If requested by the caller and the module hasn't already been read |
2893 | | // or compiled, mark modules on error as out-of-date. |
2894 | 84 | if ((ClientLoadCapabilities & ARR_TreatModuleWithErrorsAsOutOfDate) && |
2895 | 84 | canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)21 ) |
2896 | 15 | return OutOfDate; |
2897 | | |
2898 | 69 | if (!AllowASTWithCompilerErrors) { |
2899 | 4 | Diag(diag::err_pch_with_compiler_errors); |
2900 | 4 | return HadErrors; |
2901 | 4 | } |
2902 | 69 | } |
2903 | 477k | if (hasErrors) { |
2904 | 101 | Diags.ErrorOccurred = true; |
2905 | 101 | Diags.UncompilableErrorOccurred = true; |
2906 | 101 | Diags.UnrecoverableErrorOccurred = true; |
2907 | 101 | } |
2908 | | |
2909 | 477k | F.RelocatablePCH = Record[4]; |
2910 | | // Relative paths in a relocatable PCH are relative to our sysroot. |
2911 | 477k | if (F.RelocatablePCH) |
2912 | 2 | F.BaseDirectory = isysroot.empty() ? "/"0 : isysroot; |
2913 | | |
2914 | 477k | F.StandardCXXModule = Record[5]; |
2915 | | |
2916 | 477k | F.HasTimestamps = Record[6]; |
2917 | | |
2918 | 477k | const std::string &CurBranch = getClangFullRepositoryVersion(); |
2919 | 477k | StringRef ASTBranch = Blob; |
2920 | 477k | if (StringRef(CurBranch) != ASTBranch && !DisableValidation0 ) { |
2921 | 0 | if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) |
2922 | 0 | Diag(diag::err_pch_different_branch) << ASTBranch << CurBranch; |
2923 | 0 | return VersionMismatch; |
2924 | 0 | } |
2925 | 477k | break; |
2926 | 477k | } |
2927 | | |
2928 | 477k | case IMPORTS: { |
2929 | | // Validate the AST before processing any imports (otherwise, untangling |
2930 | | // them can be error-prone and expensive). A module will have a name and |
2931 | | // will already have been validated, but this catches the PCH case. |
2932 | 473k | if (ASTReadResult Result = readUnhashedControlBlockOnce()) |
2933 | 0 | return Result; |
2934 | | |
2935 | | // Load each of the imported PCH files. |
2936 | 473k | unsigned Idx = 0, N = Record.size(); |
2937 | 3.78M | while (Idx < N) { |
2938 | | // Read information about the AST file. |
2939 | 3.30M | ModuleKind ImportedKind = (ModuleKind)Record[Idx++]; |
2940 | | // Whether we're importing a standard c++ module. |
2941 | 3.30M | bool IsImportingStdCXXModule = Record[Idx++]; |
2942 | | // The import location will be the local one for now; we will adjust |
2943 | | // all import locations of module imports after the global source |
2944 | | // location info are setup, in ReadAST. |
2945 | 3.30M | SourceLocation ImportLoc = |
2946 | 3.30M | ReadUntranslatedSourceLocation(Record[Idx++]); |
2947 | 3.30M | off_t StoredSize = (off_t)Record[Idx++]; |
2948 | 3.30M | time_t StoredModTime = (time_t)Record[Idx++]; |
2949 | 3.30M | auto FirstSignatureByte = Record.begin() + Idx; |
2950 | 3.30M | ASTFileSignature StoredSignature = ASTFileSignature::create( |
2951 | 3.30M | FirstSignatureByte, FirstSignatureByte + ASTFileSignature::size); |
2952 | 3.30M | Idx += ASTFileSignature::size; |
2953 | | |
2954 | 3.30M | std::string ImportedName = ReadString(Record, Idx); |
2955 | 3.30M | std::string ImportedFile; |
2956 | | |
2957 | | // For prebuilt and explicit modules first consult the file map for |
2958 | | // an override. Note that here we don't search prebuilt module |
2959 | | // directories if we're not importing standard c++ module, only the |
2960 | | // explicit name to file mappings. Also, we will still verify the |
2961 | | // size/signature making sure it is essentially the same file but |
2962 | | // perhaps in a different location. |
2963 | 3.30M | if (ImportedKind == MK_PrebuiltModule || ImportedKind == MK_ExplicitModule3.30M ) |
2964 | 1.92k | ImportedFile = PP.getHeaderSearchInfo().getPrebuiltModuleFileName( |
2965 | 1.92k | ImportedName, /*FileMapOnly*/ !IsImportingStdCXXModule); |
2966 | | |
2967 | 3.30M | if (ImportedFile.empty()) { |
2968 | | // It is deprecated for C++20 Named modules to use the implicitly |
2969 | | // paths. |
2970 | 3.30M | if (IsImportingStdCXXModule) |
2971 | 47 | Diag(clang::diag::warn_reading_std_cxx_module_by_implicit_paths) |
2972 | 47 | << ImportedName; |
2973 | | |
2974 | | // Use BaseDirectoryAsWritten to ensure we use the same path in the |
2975 | | // ModuleCache as when writing. |
2976 | 3.30M | ImportedFile = ReadPath(BaseDirectoryAsWritten, Record, Idx); |
2977 | 3.30M | } else |
2978 | 136 | SkipPath(Record, Idx); |
2979 | | |
2980 | | // If our client can't cope with us being out of date, we can't cope with |
2981 | | // our dependency being missing. |
2982 | 3.30M | unsigned Capabilities = ClientLoadCapabilities; |
2983 | 3.30M | if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) |
2984 | 262k | Capabilities &= ~ARR_Missing; |
2985 | | |
2986 | | // Load the AST file. |
2987 | 3.30M | auto Result = ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, |
2988 | 3.30M | Loaded, StoredSize, StoredModTime, |
2989 | 3.30M | StoredSignature, Capabilities); |
2990 | | |
2991 | | // If we diagnosed a problem, produce a backtrace. |
2992 | 3.30M | bool recompilingFinalized = |
2993 | 3.30M | Result == OutOfDate && (Capabilities & ARR_OutOfDate)38 && |
2994 | 3.30M | getModuleManager().getModuleCache().isPCMFinal(F.FileName)29 ; |
2995 | 3.30M | if (isDiagnosedResult(Result, Capabilities) || recompilingFinalized3.30M ) |
2996 | 17 | Diag(diag::note_module_file_imported_by) |
2997 | 17 | << F.FileName << !F.ModuleName.empty() << F.ModuleName; |
2998 | 3.30M | if (recompilingFinalized) |
2999 | 2 | Diag(diag::note_module_file_conflict); |
3000 | | |
3001 | 3.30M | switch (Result) { |
3002 | 6 | case Failure: return Failure; |
3003 | | // If we have to ignore the dependency, we'll have to ignore this too. |
3004 | 1 | case Missing: |
3005 | 39 | case OutOfDate: return OutOfDate; |
3006 | 0 | case VersionMismatch: return VersionMismatch; |
3007 | 0 | case ConfigurationMismatch: return ConfigurationMismatch; |
3008 | 0 | case HadErrors: return HadErrors; |
3009 | 3.30M | case Success: break; |
3010 | 3.30M | } |
3011 | 3.30M | } |
3012 | 473k | break; |
3013 | 473k | } |
3014 | | |
3015 | 473k | case ORIGINAL_FILE: |
3016 | 4.95k | F.OriginalSourceFileID = FileID::get(Record[0]); |
3017 | 4.95k | F.ActualOriginalSourceFileName = std::string(Blob); |
3018 | 4.95k | F.OriginalSourceFileName = F.ActualOriginalSourceFileName; |
3019 | 4.95k | ResolveImportedPath(F, F.OriginalSourceFileName); |
3020 | 4.95k | break; |
3021 | | |
3022 | 477k | case ORIGINAL_FILE_ID: |
3023 | 477k | F.OriginalSourceFileID = FileID::get(Record[0]); |
3024 | 477k | break; |
3025 | | |
3026 | 473k | case MODULE_NAME: |
3027 | 473k | F.ModuleName = std::string(Blob); |
3028 | 473k | Diag(diag::remark_module_import) |
3029 | 473k | << F.ModuleName << F.FileName << (ImportedBy ? true464k : false8.45k ) |
3030 | 473k | << (ImportedBy ? StringRef(ImportedBy->ModuleName)464k : StringRef()8.45k ); |
3031 | 473k | if (Listener) |
3032 | 473k | Listener->ReadModuleName(F.ModuleName); |
3033 | | |
3034 | | // Validate the AST as soon as we have a name so we can exit early on |
3035 | | // failure. |
3036 | 473k | if (ASTReadResult Result = readUnhashedControlBlockOnce()) |
3037 | 11 | return Result; |
3038 | | |
3039 | 473k | break; |
3040 | | |
3041 | 473k | case MODULE_DIRECTORY: { |
3042 | | // Save the BaseDirectory as written in the PCM for computing the module |
3043 | | // filename for the ModuleCache. |
3044 | 472k | BaseDirectoryAsWritten = Blob; |
3045 | 472k | assert(!F.ModuleName.empty() && |
3046 | 472k | "MODULE_DIRECTORY found before MODULE_NAME"); |
3047 | 472k | F.BaseDirectory = std::string(Blob); |
3048 | 472k | if (!PP.getPreprocessorOpts().ModulesCheckRelocated) |
3049 | 302 | break; |
3050 | | // If we've already loaded a module map file covering this module, we may |
3051 | | // have a better path for it (relative to the current build). |
3052 | 472k | Module *M = PP.getHeaderSearchInfo().lookupModule( |
3053 | 472k | F.ModuleName, SourceLocation(), /*AllowSearch*/ true, |
3054 | 472k | /*AllowExtraModuleMapSearch*/ true); |
3055 | 472k | if (M && M->Directory472k ) { |
3056 | | // If we're implicitly loading a module, the base directory can't |
3057 | | // change between the build and use. |
3058 | | // Don't emit module relocation error if we have -fno-validate-pch |
3059 | 472k | if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation & |
3060 | 472k | DisableValidationForModuleKind::Module) && |
3061 | 472k | F.Kind != MK_ExplicitModule472k && F.Kind != MK_PrebuiltModule471k ) { |
3062 | 471k | auto BuildDir = PP.getFileManager().getDirectory(Blob); |
3063 | 471k | if (!BuildDir || *BuildDir != M->Directory) { |
3064 | 6 | if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)) |
3065 | 4 | Diag(diag::err_imported_module_relocated) |
3066 | 4 | << F.ModuleName << Blob << M->Directory->getName(); |
3067 | 6 | return OutOfDate; |
3068 | 6 | } |
3069 | 471k | } |
3070 | 472k | F.BaseDirectory = std::string(M->Directory->getName()); |
3071 | 472k | } |
3072 | 472k | break; |
3073 | 472k | } |
3074 | | |
3075 | 472k | case MODULE_MAP_FILE: |
3076 | 472k | if (ASTReadResult Result = |
3077 | 472k | ReadModuleMapFileBlock(Record, F, ImportedBy, ClientLoadCapabilities)) |
3078 | 5 | return Result; |
3079 | 472k | break; |
3080 | | |
3081 | 477k | case INPUT_FILE_OFFSETS: |
3082 | 477k | NumInputs = Record[0]; |
3083 | 477k | NumUserInputs = Record[1]; |
3084 | 477k | F.InputFileOffsets = |
3085 | 477k | (const llvm::support::unaligned_uint64_t *)Blob.data(); |
3086 | 477k | F.InputFilesLoaded.resize(NumInputs); |
3087 | 477k | F.InputFileInfosLoaded.resize(NumInputs); |
3088 | 477k | F.NumUserInputFiles = NumUserInputs; |
3089 | 477k | break; |
3090 | 3.33M | } |
3091 | 3.33M | } |
3092 | 477k | } |
3093 | | |
3094 | | llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, |
3095 | 477k | unsigned ClientLoadCapabilities) { |
3096 | 477k | BitstreamCursor &Stream = F.Stream; |
3097 | | |
3098 | 477k | if (llvm::Error Err = Stream.EnterSubBlock(AST_BLOCK_ID)) |
3099 | 0 | return Err; |
3100 | 477k | F.ASTBlockStartOffset = Stream.GetCurrentBitNo(); |
3101 | | |
3102 | | // Read all of the records and blocks for the AST file. |
3103 | 477k | RecordData Record; |
3104 | 14.0M | while (true) { |
3105 | 14.0M | Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); |
3106 | 14.0M | if (!MaybeEntry) |
3107 | 0 | return MaybeEntry.takeError(); |
3108 | 14.0M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
3109 | | |
3110 | 14.0M | switch (Entry.Kind) { |
3111 | 0 | case llvm::BitstreamEntry::Error: |
3112 | 0 | return llvm::createStringError( |
3113 | 0 | std::errc::illegal_byte_sequence, |
3114 | 0 | "error at end of module block in AST file"); |
3115 | 477k | case llvm::BitstreamEntry::EndBlock: |
3116 | | // Outside of C++, we do not store a lookup map for the translation unit. |
3117 | | // Instead, mark it as needing a lookup map to be built if this module |
3118 | | // contains any declarations lexically within it (which it always does!). |
3119 | | // This usually has no cost, since we very rarely need the lookup map for |
3120 | | // the translation unit outside C++. |
3121 | 477k | if (ASTContext *Ctx = ContextObj) { |
3122 | 477k | DeclContext *DC = Ctx->getTranslationUnitDecl(); |
3123 | 477k | if (DC->hasExternalLexicalStorage() && !Ctx->getLangOpts().CPlusPlus) |
3124 | 3.13k | DC->setMustBuildLookupTable(); |
3125 | 477k | } |
3126 | | |
3127 | 477k | return llvm::Error::success(); |
3128 | 2.38M | case llvm::BitstreamEntry::SubBlock: |
3129 | 2.38M | switch (Entry.ID) { |
3130 | 477k | case DECLTYPES_BLOCK_ID: |
3131 | | // We lazily load the decls block, but we want to set up the |
3132 | | // DeclsCursor cursor to point into it. Clone our current bitcode |
3133 | | // cursor to it, enter the block and read the abbrevs in that block. |
3134 | | // With the main cursor, we just skip over it. |
3135 | 477k | F.DeclsCursor = Stream; |
3136 | 477k | if (llvm::Error Err = Stream.SkipBlock()) |
3137 | 0 | return Err; |
3138 | 477k | if (llvm::Error Err = ReadBlockAbbrevs( |
3139 | 477k | F.DeclsCursor, DECLTYPES_BLOCK_ID, &F.DeclsBlockStartOffset)) |
3140 | 0 | return Err; |
3141 | 477k | break; |
3142 | | |
3143 | 477k | case PREPROCESSOR_BLOCK_ID: |
3144 | 477k | F.MacroCursor = Stream; |
3145 | 477k | if (!PP.getExternalSource()) |
3146 | 7.95k | PP.setExternalSource(this); |
3147 | | |
3148 | 477k | if (llvm::Error Err = Stream.SkipBlock()) |
3149 | 0 | return Err; |
3150 | 477k | if (llvm::Error Err = |
3151 | 477k | ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) |
3152 | 0 | return Err; |
3153 | 477k | F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo(); |
3154 | 477k | break; |
3155 | | |
3156 | 733 | case PREPROCESSOR_DETAIL_BLOCK_ID: |
3157 | 733 | F.PreprocessorDetailCursor = Stream; |
3158 | | |
3159 | 733 | if (llvm::Error Err = Stream.SkipBlock()) { |
3160 | 0 | return Err; |
3161 | 0 | } |
3162 | 733 | if (llvm::Error Err = ReadBlockAbbrevs(F.PreprocessorDetailCursor, |
3163 | 733 | PREPROCESSOR_DETAIL_BLOCK_ID)) |
3164 | 0 | return Err; |
3165 | 733 | F.PreprocessorDetailStartOffset |
3166 | 733 | = F.PreprocessorDetailCursor.GetCurrentBitNo(); |
3167 | | |
3168 | 733 | if (!PP.getPreprocessingRecord()) |
3169 | 119 | PP.createPreprocessingRecord(); |
3170 | 733 | if (!PP.getPreprocessingRecord()->getExternalSource()) |
3171 | 581 | PP.getPreprocessingRecord()->SetExternalSource(*this); |
3172 | 733 | break; |
3173 | | |
3174 | 477k | case SOURCE_MANAGER_BLOCK_ID: |
3175 | 477k | if (llvm::Error Err = ReadSourceManagerBlock(F)) |
3176 | 0 | return Err; |
3177 | 477k | break; |
3178 | | |
3179 | 477k | case SUBMODULE_BLOCK_ID: |
3180 | 473k | if (llvm::Error Err = ReadSubmoduleBlock(F, ClientLoadCapabilities)) |
3181 | 5 | return Err; |
3182 | 473k | break; |
3183 | | |
3184 | 477k | case COMMENTS_BLOCK_ID: { |
3185 | 477k | BitstreamCursor C = Stream; |
3186 | | |
3187 | 477k | if (llvm::Error Err = Stream.SkipBlock()) |
3188 | 0 | return Err; |
3189 | 477k | if (llvm::Error Err = ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) |
3190 | 0 | return Err; |
3191 | 477k | CommentsCursors.push_back(std::make_pair(C, &F)); |
3192 | 477k | break; |
3193 | 477k | } |
3194 | | |
3195 | 0 | default: |
3196 | 0 | if (llvm::Error Err = Stream.SkipBlock()) |
3197 | 0 | return Err; |
3198 | 0 | break; |
3199 | 2.38M | } |
3200 | 2.38M | continue; |
3201 | | |
3202 | 11.1M | case llvm::BitstreamEntry::Record: |
3203 | | // The interesting case. |
3204 | 11.1M | break; |
3205 | 14.0M | } |
3206 | | |
3207 | | // Read and process a record. |
3208 | 11.1M | Record.clear(); |
3209 | 11.1M | StringRef Blob; |
3210 | 11.1M | Expected<unsigned> MaybeRecordType = |
3211 | 11.1M | Stream.readRecord(Entry.ID, Record, &Blob); |
3212 | 11.1M | if (!MaybeRecordType) |
3213 | 0 | return MaybeRecordType.takeError(); |
3214 | 11.1M | ASTRecordTypes RecordType = (ASTRecordTypes)MaybeRecordType.get(); |
3215 | | |
3216 | | // If we're not loading an AST context, we don't care about most records. |
3217 | 11.1M | if (!ContextObj) { |
3218 | 450 | switch (RecordType) { |
3219 | 23 | case IDENTIFIER_TABLE: |
3220 | 46 | case IDENTIFIER_OFFSET: |
3221 | 69 | case INTERESTING_IDENTIFIERS: |
3222 | 92 | case STATISTICS: |
3223 | 92 | case PP_ASSUME_NONNULL_LOC: |
3224 | 92 | case PP_CONDITIONAL_STACK: |
3225 | 92 | case PP_COUNTER_VALUE: |
3226 | 115 | case SOURCE_LOCATION_OFFSETS: |
3227 | 138 | case MODULE_OFFSET_MAP: |
3228 | 161 | case SOURCE_MANAGER_LINE_TABLE: |
3229 | 184 | case SOURCE_LOCATION_PRELOADS: |
3230 | 184 | case PPD_ENTITIES_OFFSETS: |
3231 | 207 | case HEADER_SEARCH_TABLE: |
3232 | 207 | case IMPORTED_MODULES: |
3233 | 230 | case MACRO_OFFSET: |
3234 | 230 | break; |
3235 | 220 | default: |
3236 | 220 | continue; |
3237 | 450 | } |
3238 | 450 | } |
3239 | | |
3240 | 11.1M | switch (RecordType) { |
3241 | 477k | default: // Default behavior: ignore. |
3242 | 477k | break; |
3243 | | |
3244 | 477k | case TYPE_OFFSET: { |
3245 | 477k | if (F.LocalNumTypes != 0) |
3246 | 0 | return llvm::createStringError( |
3247 | 0 | std::errc::illegal_byte_sequence, |
3248 | 0 | "duplicate TYPE_OFFSET record in AST file"); |
3249 | 477k | F.TypeOffsets = reinterpret_cast<const UnderalignedInt64 *>(Blob.data()); |
3250 | 477k | F.LocalNumTypes = Record[0]; |
3251 | 477k | unsigned LocalBaseTypeIndex = Record[1]; |
3252 | 477k | F.BaseTypeIndex = getTotalNumTypes(); |
3253 | | |
3254 | 477k | if (F.LocalNumTypes > 0) { |
3255 | | // Introduce the global -> local mapping for types within this module. |
3256 | 477k | GlobalTypeMap.insert(std::make_pair(getTotalNumTypes(), &F)); |
3257 | | |
3258 | | // Introduce the local -> global mapping for types within this module. |
3259 | 477k | F.TypeRemap.insertOrReplace( |
3260 | 477k | std::make_pair(LocalBaseTypeIndex, |
3261 | 477k | F.BaseTypeIndex - LocalBaseTypeIndex)); |
3262 | | |
3263 | 477k | TypesLoaded.resize(TypesLoaded.size() + F.LocalNumTypes); |
3264 | 477k | } |
3265 | 477k | break; |
3266 | 477k | } |
3267 | | |
3268 | 477k | case DECL_OFFSET: { |
3269 | 477k | if (F.LocalNumDecls != 0) |
3270 | 0 | return llvm::createStringError( |
3271 | 0 | std::errc::illegal_byte_sequence, |
3272 | 0 | "duplicate DECL_OFFSET record in AST file"); |
3273 | 477k | F.DeclOffsets = (const DeclOffset *)Blob.data(); |
3274 | 477k | F.LocalNumDecls = Record[0]; |
3275 | 477k | unsigned LocalBaseDeclID = Record[1]; |
3276 | 477k | F.BaseDeclID = getTotalNumDecls(); |
3277 | | |
3278 | 477k | if (F.LocalNumDecls > 0) { |
3279 | | // Introduce the global -> local mapping for declarations within this |
3280 | | // module. |
3281 | 477k | GlobalDeclMap.insert( |
3282 | 477k | std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F)); |
3283 | | |
3284 | | // Introduce the local -> global mapping for declarations within this |
3285 | | // module. |
3286 | 477k | F.DeclRemap.insertOrReplace( |
3287 | 477k | std::make_pair(LocalBaseDeclID, F.BaseDeclID - LocalBaseDeclID)); |
3288 | | |
3289 | | // Introduce the global -> local mapping for declarations within this |
3290 | | // module. |
3291 | 477k | F.GlobalToLocalDeclIDs[&F] = LocalBaseDeclID; |
3292 | | |
3293 | 477k | DeclsLoaded.resize(DeclsLoaded.size() + F.LocalNumDecls); |
3294 | 477k | } |
3295 | 477k | break; |
3296 | 477k | } |
3297 | | |
3298 | 477k | case TU_UPDATE_LEXICAL: { |
3299 | 477k | DeclContext *TU = ContextObj->getTranslationUnitDecl(); |
3300 | 477k | LexicalContents Contents( |
3301 | 477k | reinterpret_cast<const llvm::support::unaligned_uint32_t *>( |
3302 | 477k | Blob.data()), |
3303 | 477k | static_cast<unsigned int>(Blob.size() / 4)); |
3304 | 477k | TULexicalDecls.push_back(std::make_pair(&F, Contents)); |
3305 | 477k | TU->setHasExternalLexicalStorage(true); |
3306 | 477k | break; |
3307 | 477k | } |
3308 | | |
3309 | 1.25M | case UPDATE_VISIBLE: { |
3310 | 1.25M | unsigned Idx = 0; |
3311 | 1.25M | serialization::DeclID ID = ReadDeclID(F, Record, Idx); |
3312 | 1.25M | auto *Data = (const unsigned char*)Blob.data(); |
3313 | 1.25M | PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&F, Data}); |
3314 | | // If we've already loaded the decl, perform the updates when we finish |
3315 | | // loading this block. |
3316 | 1.25M | if (Decl *D = GetExistingDecl(ID)) |
3317 | 523k | PendingUpdateRecords.push_back( |
3318 | 523k | PendingUpdateRecord(ID, D, /*JustLoaded=*/false)); |
3319 | 1.25M | break; |
3320 | 477k | } |
3321 | | |
3322 | 477k | case IDENTIFIER_TABLE: |
3323 | 477k | F.IdentifierTableData = |
3324 | 477k | reinterpret_cast<const unsigned char *>(Blob.data()); |
3325 | 477k | if (Record[0]) { |
3326 | 477k | F.IdentifierLookupTable = ASTIdentifierLookupTable::Create( |
3327 | 477k | F.IdentifierTableData + Record[0], |
3328 | 477k | F.IdentifierTableData + sizeof(uint32_t), |
3329 | 477k | F.IdentifierTableData, |
3330 | 477k | ASTIdentifierLookupTrait(*this, F)); |
3331 | | |
3332 | 477k | PP.getIdentifierTable().setExternalIdentifierLookup(this); |
3333 | 477k | } |
3334 | 477k | break; |
3335 | | |
3336 | 477k | case IDENTIFIER_OFFSET: { |
3337 | 477k | if (F.LocalNumIdentifiers != 0) |
3338 | 0 | return llvm::createStringError( |
3339 | 0 | std::errc::illegal_byte_sequence, |
3340 | 0 | "duplicate IDENTIFIER_OFFSET record in AST file"); |
3341 | 477k | F.IdentifierOffsets = (const uint32_t *)Blob.data(); |
3342 | 477k | F.LocalNumIdentifiers = Record[0]; |
3343 | 477k | unsigned LocalBaseIdentifierID = Record[1]; |
3344 | 477k | F.BaseIdentifierID = getTotalNumIdentifiers(); |
3345 | | |
3346 | 477k | if (F.LocalNumIdentifiers > 0) { |
3347 | | // Introduce the global -> local mapping for identifiers within this |
3348 | | // module. |
3349 | 475k | GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1, |
3350 | 475k | &F)); |
3351 | | |
3352 | | // Introduce the local -> global mapping for identifiers within this |
3353 | | // module. |
3354 | 475k | F.IdentifierRemap.insertOrReplace( |
3355 | 475k | std::make_pair(LocalBaseIdentifierID, |
3356 | 475k | F.BaseIdentifierID - LocalBaseIdentifierID)); |
3357 | | |
3358 | 475k | IdentifiersLoaded.resize(IdentifiersLoaded.size() |
3359 | 475k | + F.LocalNumIdentifiers); |
3360 | 475k | } |
3361 | 477k | break; |
3362 | 477k | } |
3363 | | |
3364 | 473k | case INTERESTING_IDENTIFIERS: |
3365 | 473k | F.PreloadIdentifierOffsets.assign(Record.begin(), Record.end()); |
3366 | 473k | break; |
3367 | | |
3368 | 3.58k | case EAGERLY_DESERIALIZED_DECLS: |
3369 | | // FIXME: Skip reading this record if our ASTConsumer doesn't care |
3370 | | // about "interesting" decls (for instance, if we're building a module). |
3371 | 15.1k | for (unsigned I = 0, N = Record.size(); I != N; ++I11.5k ) |
3372 | 11.5k | EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); |
3373 | 3.58k | break; |
3374 | | |
3375 | 241 | case MODULAR_CODEGEN_DECLS: |
3376 | | // FIXME: Skip reading this record if our ASTConsumer doesn't care about |
3377 | | // them (ie: if we're not codegenerating this module). |
3378 | 241 | if (F.Kind == MK_MainFile || |
3379 | 241 | getContext().getLangOpts().BuildingPCHWithObjectFile203 ) |
3380 | 124 | for (unsigned I = 0, N = Record.size(); 39 I != N; ++I85 ) |
3381 | 85 | EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); |
3382 | 241 | break; |
3383 | | |
3384 | 477k | case SPECIAL_TYPES: |
3385 | 477k | if (SpecialTypes.empty()) { |
3386 | 71.4k | for (unsigned I = 0, N = Record.size(); I != N; ++I63.5k ) |
3387 | 63.5k | SpecialTypes.push_back(getGlobalTypeID(F, Record[I])); |
3388 | 7.94k | break; |
3389 | 7.94k | } |
3390 | | |
3391 | 469k | if (SpecialTypes.size() != Record.size()) |
3392 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3393 | 0 | "invalid special-types record"); |
3394 | | |
3395 | 4.22M | for (unsigned I = 0, N = Record.size(); 469k I != N; ++I3.75M ) { |
3396 | 3.75M | serialization::TypeID ID = getGlobalTypeID(F, Record[I]); |
3397 | 3.75M | if (!SpecialTypes[I]) |
3398 | 1.88M | SpecialTypes[I] = ID; |
3399 | | // FIXME: If ID && SpecialTypes[I] != ID, do we need a separate |
3400 | | // merge step? |
3401 | 3.75M | } |
3402 | 469k | break; |
3403 | | |
3404 | 477k | case STATISTICS: |
3405 | 477k | TotalNumStatements += Record[0]; |
3406 | 477k | TotalNumMacros += Record[1]; |
3407 | 477k | TotalLexicalDeclContexts += Record[2]; |
3408 | 477k | TotalVisibleDeclContexts += Record[3]; |
3409 | 477k | break; |
3410 | | |
3411 | 55 | case UNUSED_FILESCOPED_DECLS: |
3412 | 263 | for (unsigned I = 0, N = Record.size(); I != N; ++I208 ) |
3413 | 208 | UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I])); |
3414 | 55 | break; |
3415 | | |
3416 | 6 | case DELEGATING_CTORS: |
3417 | 14 | for (unsigned I = 0, N = Record.size(); I != N; ++I8 ) |
3418 | 8 | DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I])); |
3419 | 6 | break; |
3420 | | |
3421 | 4 | case WEAK_UNDECLARED_IDENTIFIERS: |
3422 | 4 | if (Record.size() % 3 != 0) |
3423 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3424 | 0 | "invalid weak identifiers record"); |
3425 | | |
3426 | | // FIXME: Ignore weak undeclared identifiers from non-original PCH |
3427 | | // files. This isn't the way to do it :) |
3428 | 4 | WeakUndeclaredIdentifiers.clear(); |
3429 | | |
3430 | | // Translate the weak, undeclared identifiers into global IDs. |
3431 | 12 | for (unsigned I = 0, N = Record.size(); I < N; /* in loop */) { |
3432 | 8 | WeakUndeclaredIdentifiers.push_back( |
3433 | 8 | getGlobalIdentifierID(F, Record[I++])); |
3434 | 8 | WeakUndeclaredIdentifiers.push_back( |
3435 | 8 | getGlobalIdentifierID(F, Record[I++])); |
3436 | 8 | WeakUndeclaredIdentifiers.push_back( |
3437 | 8 | ReadSourceLocation(F, Record, I).getRawEncoding()); |
3438 | 8 | } |
3439 | 4 | break; |
3440 | | |
3441 | 727 | case SELECTOR_OFFSETS: { |
3442 | 727 | F.SelectorOffsets = (const uint32_t *)Blob.data(); |
3443 | 727 | F.LocalNumSelectors = Record[0]; |
3444 | 727 | unsigned LocalBaseSelectorID = Record[1]; |
3445 | 727 | F.BaseSelectorID = getTotalNumSelectors(); |
3446 | | |
3447 | 727 | if (F.LocalNumSelectors > 0) { |
3448 | | // Introduce the global -> local mapping for selectors within this |
3449 | | // module. |
3450 | 564 | GlobalSelectorMap.insert(std::make_pair(getTotalNumSelectors()+1, &F)); |
3451 | | |
3452 | | // Introduce the local -> global mapping for selectors within this |
3453 | | // module. |
3454 | 564 | F.SelectorRemap.insertOrReplace( |
3455 | 564 | std::make_pair(LocalBaseSelectorID, |
3456 | 564 | F.BaseSelectorID - LocalBaseSelectorID)); |
3457 | | |
3458 | 564 | SelectorsLoaded.resize(SelectorsLoaded.size() + F.LocalNumSelectors); |
3459 | 564 | } |
3460 | 727 | break; |
3461 | 4 | } |
3462 | | |
3463 | 727 | case METHOD_POOL: |
3464 | 727 | F.SelectorLookupTableData = (const unsigned char *)Blob.data(); |
3465 | 727 | if (Record[0]) |
3466 | 727 | F.SelectorLookupTable |
3467 | 727 | = ASTSelectorLookupTable::Create( |
3468 | 727 | F.SelectorLookupTableData + Record[0], |
3469 | 727 | F.SelectorLookupTableData, |
3470 | 727 | ASTSelectorLookupTrait(*this, F)); |
3471 | 727 | TotalNumMethodPoolEntries += Record[1]; |
3472 | 727 | break; |
3473 | | |
3474 | 3 | case REFERENCED_SELECTOR_POOL: |
3475 | 3 | if (!Record.empty()) { |
3476 | 6 | for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) { |
3477 | 3 | ReferencedSelectorsData.push_back(getGlobalSelectorID(F, |
3478 | 3 | Record[Idx++])); |
3479 | 3 | ReferencedSelectorsData.push_back(ReadSourceLocation(F, Record, Idx). |
3480 | 3 | getRawEncoding()); |
3481 | 3 | } |
3482 | 3 | } |
3483 | 3 | break; |
3484 | | |
3485 | 5 | case PP_ASSUME_NONNULL_LOC: { |
3486 | 5 | unsigned Idx = 0; |
3487 | 5 | if (!Record.empty()) |
3488 | 5 | PP.setPreambleRecordedPragmaAssumeNonNullLoc( |
3489 | 5 | ReadSourceLocation(F, Record, Idx)); |
3490 | 5 | break; |
3491 | 4 | } |
3492 | | |
3493 | 28 | case PP_CONDITIONAL_STACK: |
3494 | 28 | if (!Record.empty()) { |
3495 | 28 | unsigned Idx = 0, End = Record.size() - 1; |
3496 | 28 | bool ReachedEOFWhileSkipping = Record[Idx++]; |
3497 | 28 | std::optional<Preprocessor::PreambleSkipInfo> SkipInfo; |
3498 | 28 | if (ReachedEOFWhileSkipping) { |
3499 | 18 | SourceLocation HashToken = ReadSourceLocation(F, Record, Idx); |
3500 | 18 | SourceLocation IfTokenLoc = ReadSourceLocation(F, Record, Idx); |
3501 | 18 | bool FoundNonSkipPortion = Record[Idx++]; |
3502 | 18 | bool FoundElse = Record[Idx++]; |
3503 | 18 | SourceLocation ElseLoc = ReadSourceLocation(F, Record, Idx); |
3504 | 18 | SkipInfo.emplace(HashToken, IfTokenLoc, FoundNonSkipPortion, |
3505 | 18 | FoundElse, ElseLoc); |
3506 | 18 | } |
3507 | 28 | SmallVector<PPConditionalInfo, 4> ConditionalStack; |
3508 | 56 | while (Idx < End) { |
3509 | 28 | auto Loc = ReadSourceLocation(F, Record, Idx); |
3510 | 28 | bool WasSkipping = Record[Idx++]; |
3511 | 28 | bool FoundNonSkip = Record[Idx++]; |
3512 | 28 | bool FoundElse = Record[Idx++]; |
3513 | 28 | ConditionalStack.push_back( |
3514 | 28 | {Loc, WasSkipping, FoundNonSkip, FoundElse}); |
3515 | 28 | } |
3516 | 28 | PP.setReplayablePreambleConditionalStack(ConditionalStack, SkipInfo); |
3517 | 28 | } |
3518 | 28 | break; |
3519 | | |
3520 | 5 | case PP_COUNTER_VALUE: |
3521 | 5 | if (!Record.empty() && Listener) |
3522 | 5 | Listener->ReadCounter(F, Record[0]); |
3523 | 5 | break; |
3524 | | |
3525 | 477k | case FILE_SORTED_DECLS: |
3526 | 477k | F.FileSortedDecls = (const DeclID *)Blob.data(); |
3527 | 477k | F.NumFileSortedDecls = Record[0]; |
3528 | 477k | break; |
3529 | | |
3530 | 477k | case SOURCE_LOCATION_OFFSETS: { |
3531 | 477k | F.SLocEntryOffsets = (const uint32_t *)Blob.data(); |
3532 | 477k | F.LocalNumSLocEntries = Record[0]; |
3533 | 477k | SourceLocation::UIntTy SLocSpaceSize = Record[1]; |
3534 | 477k | F.SLocEntryOffsetsBase = Record[2] + F.SourceManagerBlockStartOffset; |
3535 | 477k | std::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) = |
3536 | 477k | SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries, |
3537 | 477k | SLocSpaceSize); |
3538 | 477k | if (!F.SLocEntryBaseID) { |
3539 | 0 | if (!Diags.isDiagnosticInFlight()) { |
3540 | 0 | Diags.Report(SourceLocation(), diag::remark_sloc_usage); |
3541 | 0 | SourceMgr.noteSLocAddressSpaceUsage(Diags); |
3542 | 0 | } |
3543 | 0 | return llvm::createStringError(std::errc::invalid_argument, |
3544 | 0 | "ran out of source locations"); |
3545 | 0 | } |
3546 | | // Make our entry in the range map. BaseID is negative and growing, so |
3547 | | // we invert it. Because we invert it, though, we need the other end of |
3548 | | // the range. |
3549 | 477k | unsigned RangeStart = |
3550 | 477k | unsigned(-F.SLocEntryBaseID) - F.LocalNumSLocEntries + 1; |
3551 | 477k | GlobalSLocEntryMap.insert(std::make_pair(RangeStart, &F)); |
3552 | 477k | F.FirstLoc = SourceLocation::getFromRawEncoding(F.SLocEntryBaseOffset); |
3553 | | |
3554 | | // SLocEntryBaseOffset is lower than MaxLoadedOffset and decreasing. |
3555 | 477k | assert((F.SLocEntryBaseOffset & SourceLocation::MacroIDBit) == 0); |
3556 | 477k | GlobalSLocOffsetMap.insert( |
3557 | 477k | std::make_pair(SourceManager::MaxLoadedOffset - F.SLocEntryBaseOffset |
3558 | 477k | - SLocSpaceSize,&F)); |
3559 | | |
3560 | | // Initialize the remapping table. |
3561 | | // Invalid stays invalid. |
3562 | 477k | F.SLocRemap.insertOrReplace(std::make_pair(0U, 0)); |
3563 | | // This module. Base was 2 when being compiled. |
3564 | 477k | F.SLocRemap.insertOrReplace(std::make_pair( |
3565 | 477k | 2U, static_cast<SourceLocation::IntTy>(F.SLocEntryBaseOffset - 2))); |
3566 | | |
3567 | 477k | TotalNumSLocEntries += F.LocalNumSLocEntries; |
3568 | 477k | break; |
3569 | 477k | } |
3570 | | |
3571 | 473k | case MODULE_OFFSET_MAP: |
3572 | 473k | F.ModuleOffsetMap = Blob; |
3573 | 473k | break; |
3574 | | |
3575 | 477k | case SOURCE_MANAGER_LINE_TABLE: |
3576 | 477k | ParseLineTable(F, Record); |
3577 | 477k | break; |
3578 | | |
3579 | 477k | case SOURCE_LOCATION_PRELOADS: { |
3580 | | // Need to transform from the local view (1-based IDs) to the global view, |
3581 | | // which is based off F.SLocEntryBaseID. |
3582 | 477k | if (!F.PreloadSLocEntries.empty()) |
3583 | 0 | return llvm::createStringError( |
3584 | 0 | std::errc::illegal_byte_sequence, |
3585 | 0 | "Multiple SOURCE_LOCATION_PRELOADS records in AST file"); |
3586 | | |
3587 | 477k | F.PreloadSLocEntries.swap(Record); |
3588 | 477k | break; |
3589 | 477k | } |
3590 | | |
3591 | 34 | case EXT_VECTOR_DECLS: |
3592 | 884 | for (unsigned I = 0, N = Record.size(); I != N; ++I850 ) |
3593 | 850 | ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I])); |
3594 | 34 | break; |
3595 | | |
3596 | 14 | case VTABLE_USES: |
3597 | 14 | if (Record.size() % 3 != 0) |
3598 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3599 | 0 | "Invalid VTABLE_USES record"); |
3600 | | |
3601 | | // Later tables overwrite earlier ones. |
3602 | | // FIXME: Modules will have some trouble with this. This is clearly not |
3603 | | // the right way to do this. |
3604 | 14 | VTableUses.clear(); |
3605 | | |
3606 | 48 | for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) { |
3607 | 34 | VTableUses.push_back(getGlobalDeclID(F, Record[Idx++])); |
3608 | 34 | VTableUses.push_back( |
3609 | 34 | ReadSourceLocation(F, Record, Idx).getRawEncoding()); |
3610 | 34 | VTableUses.push_back(Record[Idx++]); |
3611 | 34 | } |
3612 | 14 | break; |
3613 | | |
3614 | 1.64k | case PENDING_IMPLICIT_INSTANTIATIONS: |
3615 | 1.64k | if (PendingInstantiations.size() % 2 != 0) |
3616 | 0 | return llvm::createStringError( |
3617 | 0 | std::errc::illegal_byte_sequence, |
3618 | 0 | "Invalid existing PendingInstantiations"); |
3619 | | |
3620 | 1.64k | if (Record.size() % 2 != 0) |
3621 | 0 | return llvm::createStringError( |
3622 | 0 | std::errc::illegal_byte_sequence, |
3623 | 0 | "Invalid PENDING_IMPLICIT_INSTANTIATIONS block"); |
3624 | | |
3625 | 5.77k | for (unsigned I = 0, N = Record.size(); 1.64k I != N; /* in loop */) { |
3626 | 4.13k | PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++])); |
3627 | 4.13k | PendingInstantiations.push_back( |
3628 | 4.13k | ReadSourceLocation(F, Record, I).getRawEncoding()); |
3629 | 4.13k | } |
3630 | 1.64k | break; |
3631 | | |
3632 | 466k | case SEMA_DECL_REFS: |
3633 | 466k | if (Record.size() != 3) |
3634 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3635 | 0 | "Invalid SEMA_DECL_REFS block"); |
3636 | 1.86M | for (unsigned I = 0, N = Record.size(); 466k I != N; ++I1.39M ) |
3637 | 1.39M | SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I])); |
3638 | 466k | break; |
3639 | | |
3640 | 733 | case PPD_ENTITIES_OFFSETS: { |
3641 | 733 | F.PreprocessedEntityOffsets = (const PPEntityOffset *)Blob.data(); |
3642 | 733 | assert(Blob.size() % sizeof(PPEntityOffset) == 0); |
3643 | 733 | F.NumPreprocessedEntities = Blob.size() / sizeof(PPEntityOffset); |
3644 | | |
3645 | 733 | unsigned LocalBasePreprocessedEntityID = Record[0]; |
3646 | | |
3647 | 733 | unsigned StartingID; |
3648 | 733 | if (!PP.getPreprocessingRecord()) |
3649 | 0 | PP.createPreprocessingRecord(); |
3650 | 733 | if (!PP.getPreprocessingRecord()->getExternalSource()) |
3651 | 0 | PP.getPreprocessingRecord()->SetExternalSource(*this); |
3652 | 733 | StartingID |
3653 | 733 | = PP.getPreprocessingRecord() |
3654 | 733 | ->allocateLoadedEntities(F.NumPreprocessedEntities); |
3655 | 733 | F.BasePreprocessedEntityID = StartingID; |
3656 | | |
3657 | 733 | if (F.NumPreprocessedEntities > 0) { |
3658 | | // Introduce the global -> local mapping for preprocessed entities in |
3659 | | // this module. |
3660 | 733 | GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F)); |
3661 | | |
3662 | | // Introduce the local -> global mapping for preprocessed entities in |
3663 | | // this module. |
3664 | 733 | F.PreprocessedEntityRemap.insertOrReplace( |
3665 | 733 | std::make_pair(LocalBasePreprocessedEntityID, |
3666 | 733 | F.BasePreprocessedEntityID - LocalBasePreprocessedEntityID)); |
3667 | 733 | } |
3668 | | |
3669 | 733 | break; |
3670 | 733 | } |
3671 | | |
3672 | 83 | case PPD_SKIPPED_RANGES: { |
3673 | 83 | F.PreprocessedSkippedRangeOffsets = (const PPSkippedRange*)Blob.data(); |
3674 | 83 | assert(Blob.size() % sizeof(PPSkippedRange) == 0); |
3675 | 83 | F.NumPreprocessedSkippedRanges = Blob.size() / sizeof(PPSkippedRange); |
3676 | | |
3677 | 83 | if (!PP.getPreprocessingRecord()) |
3678 | 0 | PP.createPreprocessingRecord(); |
3679 | 83 | if (!PP.getPreprocessingRecord()->getExternalSource()) |
3680 | 0 | PP.getPreprocessingRecord()->SetExternalSource(*this); |
3681 | 83 | F.BasePreprocessedSkippedRangeID = PP.getPreprocessingRecord() |
3682 | 83 | ->allocateSkippedRanges(F.NumPreprocessedSkippedRanges); |
3683 | | |
3684 | 83 | if (F.NumPreprocessedSkippedRanges > 0) |
3685 | 83 | GlobalSkippedRangeMap.insert( |
3686 | 83 | std::make_pair(F.BasePreprocessedSkippedRangeID, &F)); |
3687 | 83 | break; |
3688 | 83 | } |
3689 | | |
3690 | 75.4k | case DECL_UPDATE_OFFSETS: |
3691 | 75.4k | if (Record.size() % 2 != 0) |
3692 | 0 | return llvm::createStringError( |
3693 | 0 | std::errc::illegal_byte_sequence, |
3694 | 0 | "invalid DECL_UPDATE_OFFSETS block in AST file"); |
3695 | 857k | for (unsigned I = 0, N = Record.size(); 75.4k I != N; I += 2781k ) { |
3696 | 781k | GlobalDeclID ID = getGlobalDeclID(F, Record[I]); |
3697 | 781k | DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1])); |
3698 | | |
3699 | | // If we've already loaded the decl, perform the updates when we finish |
3700 | | // loading this block. |
3701 | 781k | if (Decl *D = GetExistingDecl(ID)) |
3702 | 887 | PendingUpdateRecords.push_back( |
3703 | 887 | PendingUpdateRecord(ID, D, /*JustLoaded=*/false)); |
3704 | 781k | } |
3705 | 75.4k | break; |
3706 | | |
3707 | 477k | case OBJC_CATEGORIES_MAP: |
3708 | 477k | if (F.LocalNumObjCCategoriesInMap != 0) |
3709 | 0 | return llvm::createStringError( |
3710 | 0 | std::errc::illegal_byte_sequence, |
3711 | 0 | "duplicate OBJC_CATEGORIES_MAP record in AST file"); |
3712 | | |
3713 | 477k | F.LocalNumObjCCategoriesInMap = Record[0]; |
3714 | 477k | F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)Blob.data(); |
3715 | 477k | break; |
3716 | | |
3717 | 477k | case OBJC_CATEGORIES: |
3718 | 477k | F.ObjCCategories.swap(Record); |
3719 | 477k | break; |
3720 | | |
3721 | 1 | case CUDA_SPECIAL_DECL_REFS: |
3722 | | // Later tables overwrite earlier ones. |
3723 | | // FIXME: Modules will have trouble with this. |
3724 | 1 | CUDASpecialDeclRefs.clear(); |
3725 | 2 | for (unsigned I = 0, N = Record.size(); I != N; ++I1 ) |
3726 | 1 | CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I])); |
3727 | 1 | break; |
3728 | | |
3729 | 477k | case HEADER_SEARCH_TABLE: |
3730 | 477k | F.HeaderFileInfoTableData = Blob.data(); |
3731 | 477k | F.LocalNumHeaderFileInfos = Record[1]; |
3732 | 477k | if (Record[0]) { |
3733 | 477k | F.HeaderFileInfoTable |
3734 | 477k | = HeaderFileInfoLookupTable::Create( |
3735 | 477k | (const unsigned char *)F.HeaderFileInfoTableData + Record[0], |
3736 | 477k | (const unsigned char *)F.HeaderFileInfoTableData, |
3737 | 477k | HeaderFileInfoTrait(*this, F, |
3738 | 477k | &PP.getHeaderSearchInfo(), |
3739 | 477k | Blob.data() + Record[2])); |
3740 | | |
3741 | 477k | PP.getHeaderSearchInfo().SetExternalSource(this); |
3742 | 477k | if (!PP.getHeaderSearchInfo().getExternalLookup()) |
3743 | 7.95k | PP.getHeaderSearchInfo().SetExternalLookup(this); |
3744 | 477k | } |
3745 | 477k | break; |
3746 | | |
3747 | 477k | case FP_PRAGMA_OPTIONS: |
3748 | | // Later tables overwrite earlier ones. |
3749 | 477k | FPPragmaOptions.swap(Record); |
3750 | 477k | break; |
3751 | | |
3752 | 23 | case OPENCL_EXTENSIONS: |
3753 | 910 | for (unsigned I = 0, E = Record.size(); I != E; ) { |
3754 | 887 | auto Name = ReadString(Record, I); |
3755 | 887 | auto &OptInfo = OpenCLExtensions.OptMap[Name]; |
3756 | 887 | OptInfo.Supported = Record[I++] != 0; |
3757 | 887 | OptInfo.Enabled = Record[I++] != 0; |
3758 | 887 | OptInfo.WithPragma = Record[I++] != 0; |
3759 | 887 | OptInfo.Avail = Record[I++]; |
3760 | 887 | OptInfo.Core = Record[I++]; |
3761 | 887 | OptInfo.Opt = Record[I++]; |
3762 | 887 | } |
3763 | 23 | break; |
3764 | | |
3765 | 292 | case TENTATIVE_DEFINITIONS: |
3766 | 1.77k | for (unsigned I = 0, N = Record.size(); I != N; ++I1.47k ) |
3767 | 1.47k | TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I])); |
3768 | 292 | break; |
3769 | | |
3770 | 257k | case KNOWN_NAMESPACES: |
3771 | 531k | for (unsigned I = 0, N = Record.size(); I != N; ++I274k ) |
3772 | 274k | KnownNamespaces.push_back(getGlobalDeclID(F, Record[I])); |
3773 | 257k | break; |
3774 | | |
3775 | 813 | case UNDEFINED_BUT_USED: |
3776 | 813 | if (UndefinedButUsed.size() % 2 != 0) |
3777 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3778 | 0 | "Invalid existing UndefinedButUsed"); |
3779 | | |
3780 | 813 | if (Record.size() % 2 != 0) |
3781 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3782 | 0 | "invalid undefined-but-used record"); |
3783 | 3.37k | for (unsigned I = 0, N = Record.size(); 813 I != N; /* in loop */) { |
3784 | 2.55k | UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++])); |
3785 | 2.55k | UndefinedButUsed.push_back( |
3786 | 2.55k | ReadSourceLocation(F, Record, I).getRawEncoding()); |
3787 | 2.55k | } |
3788 | 813 | break; |
3789 | | |
3790 | 1 | case DELETE_EXPRS_TO_ANALYZE: |
3791 | 2 | for (unsigned I = 0, N = Record.size(); I != N;) { |
3792 | 1 | DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++])); |
3793 | 1 | const uint64_t Count = Record[I++]; |
3794 | 1 | DelayedDeleteExprs.push_back(Count); |
3795 | 2 | for (uint64_t C = 0; C < Count; ++C1 ) { |
3796 | 1 | DelayedDeleteExprs.push_back(ReadSourceLocation(F, Record, I).getRawEncoding()); |
3797 | 1 | bool IsArrayForm = Record[I++] == 1; |
3798 | 1 | DelayedDeleteExprs.push_back(IsArrayForm); |
3799 | 1 | } |
3800 | 1 | } |
3801 | 1 | break; |
3802 | | |
3803 | 69 | case IMPORTED_MODULES: |
3804 | 69 | if (!F.isModule()) { |
3805 | | // If we aren't loading a module (which has its own exports), make |
3806 | | // all of the imported modules visible. |
3807 | | // FIXME: Deal with macros-only imports. |
3808 | 154 | for (unsigned I = 0, N = Record.size(); I != N; /**/) { |
3809 | 85 | unsigned GlobalID = getGlobalSubmoduleID(F, Record[I++]); |
3810 | 85 | SourceLocation Loc = ReadSourceLocation(F, Record, I); |
3811 | 85 | if (GlobalID) { |
3812 | 85 | PendingImportedModules.push_back(ImportedSubmodule(GlobalID, Loc)); |
3813 | 85 | if (DeserializationListener) |
3814 | 2 | DeserializationListener->ModuleImportRead(GlobalID, Loc); |
3815 | 85 | } |
3816 | 85 | } |
3817 | 69 | } |
3818 | 69 | break; |
3819 | | |
3820 | 477k | case MACRO_OFFSET: { |
3821 | 477k | if (F.LocalNumMacros != 0) |
3822 | 0 | return llvm::createStringError( |
3823 | 0 | std::errc::illegal_byte_sequence, |
3824 | 0 | "duplicate MACRO_OFFSET record in AST file"); |
3825 | 477k | F.MacroOffsets = (const uint32_t *)Blob.data(); |
3826 | 477k | F.LocalNumMacros = Record[0]; |
3827 | 477k | unsigned LocalBaseMacroID = Record[1]; |
3828 | 477k | F.MacroOffsetsBase = Record[2] + F.ASTBlockStartOffset; |
3829 | 477k | F.BaseMacroID = getTotalNumMacros(); |
3830 | | |
3831 | 477k | if (F.LocalNumMacros > 0) { |
3832 | | // Introduce the global -> local mapping for macros within this module. |
3833 | 473k | GlobalMacroMap.insert(std::make_pair(getTotalNumMacros() + 1, &F)); |
3834 | | |
3835 | | // Introduce the local -> global mapping for macros within this module. |
3836 | 473k | F.MacroRemap.insertOrReplace( |
3837 | 473k | std::make_pair(LocalBaseMacroID, |
3838 | 473k | F.BaseMacroID - LocalBaseMacroID)); |
3839 | | |
3840 | 473k | MacrosLoaded.resize(MacrosLoaded.size() + F.LocalNumMacros); |
3841 | 473k | } |
3842 | 477k | break; |
3843 | 477k | } |
3844 | | |
3845 | 15 | case LATE_PARSED_TEMPLATE: |
3846 | 15 | LateParsedTemplates.emplace_back( |
3847 | 15 | std::piecewise_construct, std::forward_as_tuple(&F), |
3848 | 15 | std::forward_as_tuple(Record.begin(), Record.end())); |
3849 | 15 | break; |
3850 | | |
3851 | 4.25k | case OPTIMIZE_PRAGMA_OPTIONS: |
3852 | 4.25k | if (Record.size() != 1) |
3853 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3854 | 0 | "invalid pragma optimize record"); |
3855 | 4.25k | OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]); |
3856 | 4.25k | break; |
3857 | | |
3858 | 4.25k | case MSSTRUCT_PRAGMA_OPTIONS: |
3859 | 4.25k | if (Record.size() != 1) |
3860 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3861 | 0 | "invalid pragma ms_struct record"); |
3862 | 4.25k | PragmaMSStructState = Record[0]; |
3863 | 4.25k | break; |
3864 | | |
3865 | 4.25k | case POINTERS_TO_MEMBERS_PRAGMA_OPTIONS: |
3866 | 4.25k | if (Record.size() != 2) |
3867 | 0 | return llvm::createStringError( |
3868 | 0 | std::errc::illegal_byte_sequence, |
3869 | 0 | "invalid pragma pointers to members record"); |
3870 | 4.25k | PragmaMSPointersToMembersState = Record[0]; |
3871 | 4.25k | PointersToMembersPragmaLocation = ReadSourceLocation(F, Record[1]); |
3872 | 4.25k | break; |
3873 | | |
3874 | 4 | case UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES: |
3875 | 10 | for (unsigned I = 0, N = Record.size(); I != N; ++I6 ) |
3876 | 6 | UnusedLocalTypedefNameCandidates.push_back( |
3877 | 6 | getGlobalDeclID(F, Record[I])); |
3878 | 4 | break; |
3879 | | |
3880 | 1 | case CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH: |
3881 | 1 | if (Record.size() != 1) |
3882 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3883 | 0 | "invalid cuda pragma options record"); |
3884 | 1 | ForceCUDAHostDeviceDepth = Record[0]; |
3885 | 1 | break; |
3886 | | |
3887 | 4.25k | case ALIGN_PACK_PRAGMA_OPTIONS: { |
3888 | 4.25k | if (Record.size() < 3) |
3889 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3890 | 0 | "invalid pragma pack record"); |
3891 | 4.25k | PragmaAlignPackCurrentValue = ReadAlignPackInfo(Record[0]); |
3892 | 4.25k | PragmaAlignPackCurrentLocation = ReadSourceLocation(F, Record[1]); |
3893 | 4.25k | unsigned NumStackEntries = Record[2]; |
3894 | 4.25k | unsigned Idx = 3; |
3895 | | // Reset the stack when importing a new module. |
3896 | 4.25k | PragmaAlignPackStack.clear(); |
3897 | 4.26k | for (unsigned I = 0; I < NumStackEntries; ++I14 ) { |
3898 | 14 | PragmaAlignPackStackEntry Entry; |
3899 | 14 | Entry.Value = ReadAlignPackInfo(Record[Idx++]); |
3900 | 14 | Entry.Location = ReadSourceLocation(F, Record[Idx++]); |
3901 | 14 | Entry.PushLocation = ReadSourceLocation(F, Record[Idx++]); |
3902 | 14 | PragmaAlignPackStrings.push_back(ReadString(Record, Idx)); |
3903 | 14 | Entry.SlotLabel = PragmaAlignPackStrings.back(); |
3904 | 14 | PragmaAlignPackStack.push_back(Entry); |
3905 | 14 | } |
3906 | 4.25k | break; |
3907 | 4.25k | } |
3908 | | |
3909 | 4.25k | case FLOAT_CONTROL_PRAGMA_OPTIONS: { |
3910 | 4.25k | if (Record.size() < 3) |
3911 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
3912 | 0 | "invalid pragma float control record"); |
3913 | 4.25k | FpPragmaCurrentValue = FPOptionsOverride::getFromOpaqueInt(Record[0]); |
3914 | 4.25k | FpPragmaCurrentLocation = ReadSourceLocation(F, Record[1]); |
3915 | 4.25k | unsigned NumStackEntries = Record[2]; |
3916 | 4.25k | unsigned Idx = 3; |
3917 | | // Reset the stack when importing a new module. |
3918 | 4.25k | FpPragmaStack.clear(); |
3919 | 4.25k | for (unsigned I = 0; I < NumStackEntries; ++I2 ) { |
3920 | 2 | FpPragmaStackEntry Entry; |
3921 | 2 | Entry.Value = FPOptionsOverride::getFromOpaqueInt(Record[Idx++]); |
3922 | 2 | Entry.Location = ReadSourceLocation(F, Record[Idx++]); |
3923 | 2 | Entry.PushLocation = ReadSourceLocation(F, Record[Idx++]); |
3924 | 2 | FpPragmaStrings.push_back(ReadString(Record, Idx)); |
3925 | 2 | Entry.SlotLabel = FpPragmaStrings.back(); |
3926 | 2 | FpPragmaStack.push_back(Entry); |
3927 | 2 | } |
3928 | 4.25k | break; |
3929 | 4.25k | } |
3930 | | |
3931 | 2.13k | case DECLS_TO_CHECK_FOR_DEFERRED_DIAGS: |
3932 | 10.1k | for (unsigned I = 0, N = Record.size(); I != N; ++I7.96k ) |
3933 | 7.96k | DeclsToCheckForDeferredDiags.insert(getGlobalDeclID(F, Record[I])); |
3934 | 2.13k | break; |
3935 | 11.1M | } |
3936 | 11.1M | } |
3937 | 477k | } |
3938 | | |
3939 | 428k | void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { |
3940 | 428k | assert(!F.ModuleOffsetMap.empty() && "no module offset map to read"); |
3941 | | |
3942 | | // Additional remapping information. |
3943 | 428k | const unsigned char *Data = (const unsigned char*)F.ModuleOffsetMap.data(); |
3944 | 428k | const unsigned char *DataEnd = Data + F.ModuleOffsetMap.size(); |
3945 | 428k | F.ModuleOffsetMap = StringRef(); |
3946 | | |
3947 | | // If we see this entry before SOURCE_LOCATION_OFFSETS, add placeholders. |
3948 | 428k | if (F.SLocRemap.find(0) == F.SLocRemap.end()) { |
3949 | 75.3k | F.SLocRemap.insert(std::make_pair(0U, 0)); |
3950 | 75.3k | F.SLocRemap.insert(std::make_pair(2U, 1)); |
3951 | 75.3k | } |
3952 | | |
3953 | | // Continuous range maps we may be updating in our module. |
3954 | 428k | using SLocRemapBuilder = |
3955 | 428k | ContinuousRangeMap<SourceLocation::UIntTy, SourceLocation::IntTy, |
3956 | 428k | 2>::Builder; |
3957 | 428k | using RemapBuilder = ContinuousRangeMap<uint32_t, int, 2>::Builder; |
3958 | 428k | SLocRemapBuilder SLocRemap(F.SLocRemap); |
3959 | 428k | RemapBuilder IdentifierRemap(F.IdentifierRemap); |
3960 | 428k | RemapBuilder MacroRemap(F.MacroRemap); |
3961 | 428k | RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap); |
3962 | 428k | RemapBuilder SubmoduleRemap(F.SubmoduleRemap); |
3963 | 428k | RemapBuilder SelectorRemap(F.SelectorRemap); |
3964 | 428k | RemapBuilder DeclRemap(F.DeclRemap); |
3965 | 428k | RemapBuilder TypeRemap(F.TypeRemap); |
3966 | | |
3967 | 62.8M | while (Data < DataEnd) { |
3968 | | // FIXME: Looking up dependency modules by filename is horrible. Let's |
3969 | | // start fixing this with prebuilt, explicit and implicit modules and see |
3970 | | // how it goes... |
3971 | 62.3M | using namespace llvm::support; |
3972 | 62.3M | ModuleKind Kind = static_cast<ModuleKind>( |
3973 | 62.3M | endian::readNext<uint8_t, little, unaligned>(Data)); |
3974 | 62.3M | uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data); |
3975 | 62.3M | StringRef Name = StringRef((const char*)Data, Len); |
3976 | 62.3M | Data += Len; |
3977 | 62.3M | ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule62.3M || |
3978 | 62.3M | Kind == MK_ImplicitModule62.3M |
3979 | 62.3M | ? ModuleMgr.lookupByModuleName(Name)62.3M |
3980 | 62.3M | : ModuleMgr.lookupByFileName(Name)145 ); |
3981 | 62.3M | if (!OM) { |
3982 | 0 | std::string Msg = |
3983 | 0 | "SourceLocation remap refers to unknown module, cannot find "; |
3984 | 0 | Msg.append(std::string(Name)); |
3985 | 0 | Error(Msg); |
3986 | 0 | return; |
3987 | 0 | } |
3988 | | |
3989 | 62.3M | SourceLocation::UIntTy SLocOffset = |
3990 | 62.3M | endian::readNext<uint32_t, little, unaligned>(Data); |
3991 | 62.3M | uint32_t IdentifierIDOffset = |
3992 | 62.3M | endian::readNext<uint32_t, little, unaligned>(Data); |
3993 | 62.3M | uint32_t MacroIDOffset = |
3994 | 62.3M | endian::readNext<uint32_t, little, unaligned>(Data); |
3995 | 62.3M | uint32_t PreprocessedEntityIDOffset = |
3996 | 62.3M | endian::readNext<uint32_t, little, unaligned>(Data); |
3997 | 62.3M | uint32_t SubmoduleIDOffset = |
3998 | 62.3M | endian::readNext<uint32_t, little, unaligned>(Data); |
3999 | 62.3M | uint32_t SelectorIDOffset = |
4000 | 62.3M | endian::readNext<uint32_t, little, unaligned>(Data); |
4001 | 62.3M | uint32_t DeclIDOffset = |
4002 | 62.3M | endian::readNext<uint32_t, little, unaligned>(Data); |
4003 | 62.3M | uint32_t TypeIndexOffset = |
4004 | 62.3M | endian::readNext<uint32_t, little, unaligned>(Data); |
4005 | | |
4006 | 62.3M | auto mapOffset = [&](uint32_t Offset, uint32_t BaseOffset, |
4007 | 436M | RemapBuilder &Remap) { |
4008 | 436M | constexpr uint32_t None = std::numeric_limits<uint32_t>::max(); |
4009 | 436M | if (Offset != None) |
4010 | 311M | Remap.insert(std::make_pair(Offset, |
4011 | 311M | static_cast<int>(BaseOffset - Offset))); |
4012 | 436M | }; |
4013 | | |
4014 | 62.3M | constexpr SourceLocation::UIntTy SLocNone = |
4015 | 62.3M | std::numeric_limits<SourceLocation::UIntTy>::max(); |
4016 | 62.3M | if (SLocOffset != SLocNone) |
4017 | 62.3M | SLocRemap.insert(std::make_pair( |
4018 | 62.3M | SLocOffset, static_cast<SourceLocation::IntTy>( |
4019 | 62.3M | OM->SLocEntryBaseOffset - SLocOffset))); |
4020 | | |
4021 | 62.3M | mapOffset(IdentifierIDOffset, OM->BaseIdentifierID, IdentifierRemap); |
4022 | 62.3M | mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap); |
4023 | 62.3M | mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID, |
4024 | 62.3M | PreprocessedEntityRemap); |
4025 | 62.3M | mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap); |
4026 | 62.3M | mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap); |
4027 | 62.3M | mapOffset(DeclIDOffset, OM->BaseDeclID, DeclRemap); |
4028 | 62.3M | mapOffset(TypeIndexOffset, OM->BaseTypeIndex, TypeRemap); |
4029 | | |
4030 | | // Global -> local mappings. |
4031 | 62.3M | F.GlobalToLocalDeclIDs[OM] = DeclIDOffset; |
4032 | 62.3M | } |
4033 | 428k | } |
4034 | | |
4035 | | ASTReader::ASTReadResult |
4036 | | ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, |
4037 | | const ModuleFile *ImportedBy, |
4038 | 472k | unsigned ClientLoadCapabilities) { |
4039 | 472k | unsigned Idx = 0; |
4040 | 472k | F.ModuleMapPath = ReadPath(F, Record, Idx); |
4041 | | |
4042 | | // Try to resolve ModuleName in the current header search context and |
4043 | | // verify that it is found in the same module map file as we saved. If the |
4044 | | // top-level AST file is a main file, skip this check because there is no |
4045 | | // usable header search context. |
4046 | 472k | assert(!F.ModuleName.empty() && |
4047 | 472k | "MODULE_NAME should come before MODULE_MAP_FILE"); |
4048 | 472k | if (PP.getPreprocessorOpts().ModulesCheckRelocated && |
4049 | 472k | F.Kind == MK_ImplicitModule472k && ModuleMgr.begin()->Kind != MK_MainFile471k ) { |
4050 | | // An implicitly-loaded module file should have its module listed in some |
4051 | | // module map file that we've already loaded. |
4052 | 471k | Module *M = |
4053 | 471k | PP.getHeaderSearchInfo().lookupModule(F.ModuleName, F.ImportLoc); |
4054 | 471k | auto &Map = PP.getHeaderSearchInfo().getModuleMap(); |
4055 | 471k | OptionalFileEntryRef ModMap = |
4056 | 471k | M ? Map.getModuleMapFileForUniquing(M)471k : std::nullopt3 ; |
4057 | | // Don't emit module relocation error if we have -fno-validate-pch |
4058 | 471k | if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation & |
4059 | 471k | DisableValidationForModuleKind::Module) && |
4060 | 471k | !ModMap471k ) { |
4061 | 3 | if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)) { |
4062 | 3 | if (auto ASTFE = M ? M->getASTFile() : std::nullopt) { |
4063 | | // This module was defined by an imported (explicit) module. |
4064 | 0 | Diag(diag::err_module_file_conflict) << F.ModuleName << F.FileName |
4065 | 0 | << ASTFE->getName(); |
4066 | 3 | } else { |
4067 | | // This module was built with a different module map. |
4068 | 3 | Diag(diag::err_imported_module_not_found) |
4069 | 3 | << F.ModuleName << F.FileName |
4070 | 3 | << (ImportedBy ? ImportedBy->FileName : ""0 ) << F.ModuleMapPath |
4071 | 3 | << !ImportedBy; |
4072 | | // In case it was imported by a PCH, there's a chance the user is |
4073 | | // just missing to include the search path to the directory containing |
4074 | | // the modulemap. |
4075 | 3 | if (ImportedBy && ImportedBy->Kind == MK_PCH) |
4076 | 2 | Diag(diag::note_imported_by_pch_module_not_found) |
4077 | 2 | << llvm::sys::path::parent_path(F.ModuleMapPath); |
4078 | 3 | } |
4079 | 3 | } |
4080 | 3 | return OutOfDate; |
4081 | 3 | } |
4082 | | |
4083 | 471k | assert(M && M->Name == F.ModuleName && "found module with different name"); |
4084 | | |
4085 | | // Check the primary module map file. |
4086 | 471k | auto StoredModMap = FileMgr.getFile(F.ModuleMapPath); |
4087 | 471k | if (!StoredModMap || *StoredModMap != ModMap) { |
4088 | 0 | assert(ModMap && "found module is missing module map file"); |
4089 | 0 | assert((ImportedBy || F.Kind == MK_ImplicitModule) && |
4090 | 0 | "top-level import should be verified"); |
4091 | 0 | bool NotImported = F.Kind == MK_ImplicitModule && !ImportedBy; |
4092 | 0 | if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)) |
4093 | 0 | Diag(diag::err_imported_module_modmap_changed) |
4094 | 0 | << F.ModuleName << (NotImported ? F.FileName : ImportedBy->FileName) |
4095 | 0 | << ModMap->getName() << F.ModuleMapPath << NotImported; |
4096 | 0 | return OutOfDate; |
4097 | 0 | } |
4098 | | |
4099 | 471k | llvm::SmallPtrSet<const FileEntry *, 1> AdditionalStoredMaps; |
4100 | 471k | for (unsigned I = 0, N = Record[Idx++]; I < N; ++I242 ) { |
4101 | | // FIXME: we should use input files rather than storing names. |
4102 | 243 | std::string Filename = ReadPath(F, Record, Idx); |
4103 | 243 | auto SF = FileMgr.getFile(Filename, false, false); |
4104 | 243 | if (!SF) { |
4105 | 1 | if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)) |
4106 | 0 | Error("could not find file '" + Filename +"' referenced by AST file"); |
4107 | 1 | return OutOfDate; |
4108 | 1 | } |
4109 | 242 | AdditionalStoredMaps.insert(*SF); |
4110 | 242 | } |
4111 | | |
4112 | | // Check any additional module map files (e.g. module.private.modulemap) |
4113 | | // that are not in the pcm. |
4114 | 471k | if (auto *AdditionalModuleMaps = Map.getAdditionalModuleMapFiles(M)) { |
4115 | 243 | for (FileEntryRef ModMap : *AdditionalModuleMaps) { |
4116 | | // Remove files that match |
4117 | | // Note: SmallPtrSet::erase is really remove |
4118 | 243 | if (!AdditionalStoredMaps.erase(ModMap)) { |
4119 | 1 | if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)) |
4120 | 0 | Diag(diag::err_module_different_modmap) |
4121 | 0 | << F.ModuleName << /*new*/0 << ModMap.getName(); |
4122 | 1 | return OutOfDate; |
4123 | 1 | } |
4124 | 243 | } |
4125 | 149 | } |
4126 | | |
4127 | | // Check any additional module map files that are in the pcm, but not |
4128 | | // found in header search. Cases that match are already removed. |
4129 | 471k | for (const FileEntry *ModMap : AdditionalStoredMaps) { |
4130 | 0 | if (!canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities)) |
4131 | 0 | Diag(diag::err_module_different_modmap) |
4132 | 0 | << F.ModuleName << /*not new*/1 << ModMap->getName(); |
4133 | 0 | return OutOfDate; |
4134 | 0 | } |
4135 | 471k | } |
4136 | | |
4137 | 472k | if (Listener) |
4138 | 472k | Listener->ReadModuleMapFile(F.ModuleMapPath); |
4139 | 472k | return Success; |
4140 | 472k | } |
4141 | | |
4142 | | /// Move the given method to the back of the global list of methods. |
4143 | 33 | static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { |
4144 | | // Find the entry for this selector in the method pool. |
4145 | 33 | Sema::GlobalMethodPool::iterator Known |
4146 | 33 | = S.MethodPool.find(Method->getSelector()); |
4147 | 33 | if (Known == S.MethodPool.end()) |
4148 | 4 | return; |
4149 | | |
4150 | | // Retrieve the appropriate method list. |
4151 | 29 | ObjCMethodList &Start = Method->isInstanceMethod()? Known->second.first |
4152 | 29 | : Known->second.second0 ; |
4153 | 29 | bool Found = false; |
4154 | 308 | for (ObjCMethodList *List = &Start; List; List = List->getNext()279 ) { |
4155 | 279 | if (!Found) { |
4156 | 148 | if (List->getMethod() == Method) { |
4157 | 29 | Found = true; |
4158 | 119 | } else { |
4159 | | // Keep searching. |
4160 | 119 | continue; |
4161 | 119 | } |
4162 | 148 | } |
4163 | | |
4164 | 160 | if (List->getNext()) |
4165 | 131 | List->setMethod(List->getNext()->getMethod()); |
4166 | 29 | else |
4167 | 29 | List->setMethod(Method); |
4168 | 160 | } |
4169 | 29 | } |
4170 | | |
4171 | 21.6k | void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) { |
4172 | 21.6k | assert(Owner->NameVisibility != Module::Hidden && "nothing to make visible?"); |
4173 | 74.4k | for (Decl *D : Names)21.6k { |
4174 | 74.4k | bool wasHidden = !D->isUnconditionallyVisible(); |
4175 | 74.4k | D->setVisibleDespiteOwningModule(); |
4176 | | |
4177 | 74.4k | if (wasHidden && SemaObj74.3k ) { |
4178 | 74.3k | if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D)) { |
4179 | 33 | moveMethodToBackOfGlobalList(*SemaObj, Method); |
4180 | 33 | } |
4181 | 74.3k | } |
4182 | 74.4k | } |
4183 | 21.6k | } |
4184 | | |
4185 | | void ASTReader::makeModuleVisible(Module *Mod, |
4186 | | Module::NameVisibilityKind NameVisibility, |
4187 | 64.3k | SourceLocation ImportLoc) { |
4188 | 64.3k | llvm::SmallPtrSet<Module *, 4> Visited; |
4189 | 64.3k | SmallVector<Module *, 4> Stack; |
4190 | 64.3k | Stack.push_back(Mod); |
4191 | 706k | while (!Stack.empty()) { |
4192 | 642k | Mod = Stack.pop_back_val(); |
4193 | | |
4194 | 642k | if (NameVisibility <= Mod->NameVisibility) { |
4195 | | // This module already has this level of visibility (or greater), so |
4196 | | // there is nothing more to do. |
4197 | 84.8k | continue; |
4198 | 84.8k | } |
4199 | | |
4200 | 557k | if (Mod->isUnimportable()) { |
4201 | | // Modules that aren't importable cannot be made visible. |
4202 | 142 | continue; |
4203 | 142 | } |
4204 | | |
4205 | | // Update the module's name visibility. |
4206 | 557k | Mod->NameVisibility = NameVisibility; |
4207 | | |
4208 | | // If we've already deserialized any names from this module, |
4209 | | // mark them as visible. |
4210 | 557k | HiddenNamesMapType::iterator Hidden = HiddenNamesMap.find(Mod); |
4211 | 557k | if (Hidden != HiddenNamesMap.end()) { |
4212 | 21.6k | auto HiddenNames = std::move(*Hidden); |
4213 | 21.6k | HiddenNamesMap.erase(Hidden); |
4214 | 21.6k | makeNamesVisible(HiddenNames.second, HiddenNames.first); |
4215 | 21.6k | assert(!HiddenNamesMap.contains(Mod) && |
4216 | 21.6k | "making names visible added hidden names"); |
4217 | 21.6k | } |
4218 | | |
4219 | | // Push any exported modules onto the stack to be marked as visible. |
4220 | 557k | SmallVector<Module *, 16> Exports; |
4221 | 557k | Mod->getExportedModules(Exports); |
4222 | 557k | for (SmallVectorImpl<Module *>::iterator |
4223 | 2.24M | I = Exports.begin(), E = Exports.end(); I != E; ++I1.68M ) { |
4224 | 1.68M | Module *Exported = *I; |
4225 | 1.68M | if (Visited.insert(Exported).second) |
4226 | 578k | Stack.push_back(Exported); |
4227 | 1.68M | } |
4228 | 557k | } |
4229 | 64.3k | } |
4230 | | |
4231 | | /// We've merged the definition \p MergedDef into the existing definition |
4232 | | /// \p Def. Ensure that \p Def is made visible whenever \p MergedDef is made |
4233 | | /// visible. |
4234 | | void ASTReader::mergeDefinitionVisibility(NamedDecl *Def, |
4235 | 12.4k | NamedDecl *MergedDef) { |
4236 | 12.4k | if (!Def->isUnconditionallyVisible()) { |
4237 | | // If MergedDef is visible or becomes visible, make the definition visible. |
4238 | 599 | if (MergedDef->isUnconditionallyVisible()) |
4239 | 163 | Def->setVisibleDespiteOwningModule(); |
4240 | 436 | else { |
4241 | 436 | getContext().mergeDefinitionIntoModule( |
4242 | 436 | Def, MergedDef->getImportedOwningModule(), |
4243 | 436 | /*NotifyListeners*/ false); |
4244 | 436 | PendingMergedDefinitionsToDeduplicate.insert(Def); |
4245 | 436 | } |
4246 | 599 | } |
4247 | 12.4k | } |
4248 | | |
4249 | 1.04M | bool ASTReader::loadGlobalIndex() { |
4250 | 1.04M | if (GlobalIndex) |
4251 | 213k | return false; |
4252 | | |
4253 | 828k | if (TriedLoadingGlobalIndex || !UseGlobalIndex263k || |
4254 | 828k | !PP.getLangOpts().Modules237k ) |
4255 | 826k | return true; |
4256 | | |
4257 | | // Try to load the global index. |
4258 | 2.38k | TriedLoadingGlobalIndex = true; |
4259 | 2.38k | StringRef ModuleCachePath |
4260 | 2.38k | = getPreprocessor().getHeaderSearchInfo().getModuleCachePath(); |
4261 | 2.38k | std::pair<GlobalModuleIndex *, llvm::Error> Result = |
4262 | 2.38k | GlobalModuleIndex::readIndex(ModuleCachePath); |
4263 | 2.38k | if (llvm::Error Err = std::move(Result.second)) { |
4264 | 1.96k | assert(!Result.first); |
4265 | 1.96k | consumeError(std::move(Err)); // FIXME this drops errors on the floor. |
4266 | 1.96k | return true; |
4267 | 1.96k | } |
4268 | | |
4269 | 428 | GlobalIndex.reset(Result.first); |
4270 | 428 | ModuleMgr.setGlobalIndex(GlobalIndex.get()); |
4271 | 428 | return false; |
4272 | 2.38k | } |
4273 | | |
4274 | 12.6k | bool ASTReader::isGlobalIndexUnavailable() const { |
4275 | 12.6k | return PP.getLangOpts().Modules && UseGlobalIndex8.77k && |
4276 | 12.6k | !hasGlobalIndex()8.49k && TriedLoadingGlobalIndex8.14k ; |
4277 | 12.6k | } |
4278 | | |
4279 | 9 | static void updateModuleTimestamp(ModuleFile &MF) { |
4280 | | // Overwrite the timestamp file contents so that file's mtime changes. |
4281 | 9 | std::string TimestampFilename = MF.getTimestampFilename(); |
4282 | 9 | std::error_code EC; |
4283 | 9 | llvm::raw_fd_ostream OS(TimestampFilename, EC, |
4284 | 9 | llvm::sys::fs::OF_TextWithCRLF); |
4285 | 9 | if (EC) |
4286 | 0 | return; |
4287 | 9 | OS << "Timestamp file\n"; |
4288 | 9 | OS.close(); |
4289 | 9 | OS.clear_error(); // Avoid triggering a fatal error. |
4290 | 9 | } |
4291 | | |
4292 | | /// Given a cursor at the start of an AST file, scan ahead and drop the |
4293 | | /// cursor into the start of the given block ID, returning false on success and |
4294 | | /// true on failure. |
4295 | 1.42M | static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) { |
4296 | 2.37M | while (true) { |
4297 | 2.37M | Expected<llvm::BitstreamEntry> MaybeEntry = Cursor.advance(); |
4298 | 2.37M | if (!MaybeEntry) { |
4299 | | // FIXME this drops errors on the floor. |
4300 | 0 | consumeError(MaybeEntry.takeError()); |
4301 | 0 | return true; |
4302 | 0 | } |
4303 | 2.37M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
4304 | | |
4305 | 2.37M | switch (Entry.Kind) { |
4306 | 477k | case llvm::BitstreamEntry::Error: |
4307 | 477k | case llvm::BitstreamEntry::EndBlock: |
4308 | 477k | return true; |
4309 | | |
4310 | 0 | case llvm::BitstreamEntry::Record: |
4311 | | // Ignore top-level records. |
4312 | 0 | if (Expected<unsigned> Skipped = Cursor.skipRecord(Entry.ID)) |
4313 | 0 | break; |
4314 | 0 | else { |
4315 | | // FIXME this drops errors on the floor. |
4316 | 0 | consumeError(Skipped.takeError()); |
4317 | 0 | return true; |
4318 | 0 | } |
4319 | | |
4320 | 1.89M | case llvm::BitstreamEntry::SubBlock: |
4321 | 1.89M | if (Entry.ID == BlockID) { |
4322 | 945k | if (llvm::Error Err = Cursor.EnterSubBlock(BlockID)) { |
4323 | | // FIXME this drops the error on the floor. |
4324 | 0 | consumeError(std::move(Err)); |
4325 | 0 | return true; |
4326 | 0 | } |
4327 | | // Found it! |
4328 | 945k | return false; |
4329 | 945k | } |
4330 | | |
4331 | 949k | if (llvm::Error Err = Cursor.SkipBlock()) { |
4332 | | // FIXME this drops the error on the floor. |
4333 | 0 | consumeError(std::move(Err)); |
4334 | 0 | return true; |
4335 | 0 | } |
4336 | 2.37M | } |
4337 | 2.37M | } |
4338 | 1.42M | } |
4339 | | |
4340 | | ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type, |
4341 | | SourceLocation ImportLoc, |
4342 | | unsigned ClientLoadCapabilities, |
4343 | 20.1k | ModuleFile **NewLoadedModuleFile) { |
4344 | 20.1k | llvm::TimeTraceScope scope("ReadAST", FileName); |
4345 | | |
4346 | 20.1k | llvm::SaveAndRestore SetCurImportLocRAII(CurrentImportLoc, ImportLoc); |
4347 | 20.1k | llvm::SaveAndRestore<std::optional<ModuleKind>> SetCurModuleKindRAII( |
4348 | 20.1k | CurrentDeserializingModuleKind, Type); |
4349 | | |
4350 | | // Defer any pending actions until we get to the end of reading the AST file. |
4351 | 20.1k | Deserializing AnASTFile(this); |
4352 | | |
4353 | | // Bump the generation number. |
4354 | 20.1k | unsigned PreviousGeneration = 0; |
4355 | 20.1k | if (ContextObj) |
4356 | 20.1k | PreviousGeneration = incrementGeneration(*ContextObj); |
4357 | | |
4358 | 20.1k | unsigned NumModules = ModuleMgr.size(); |
4359 | 20.1k | SmallVector<ImportedModule, 4> Loaded; |
4360 | 20.1k | if (ASTReadResult ReadResult = |
4361 | 20.1k | ReadASTCore(FileName, Type, ImportLoc, |
4362 | 20.1k | /*ImportedBy=*/nullptr, Loaded, 0, 0, ASTFileSignature(), |
4363 | 20.1k | ClientLoadCapabilities)) { |
4364 | 3.02k | ModuleMgr.removeModules(ModuleMgr.begin() + NumModules); |
4365 | | |
4366 | | // If we find that any modules are unusable, the global index is going |
4367 | | // to be out-of-date. Just remove it. |
4368 | 3.02k | GlobalIndex.reset(); |
4369 | 3.02k | ModuleMgr.setGlobalIndex(nullptr); |
4370 | 3.02k | return ReadResult; |
4371 | 3.02k | } |
4372 | | |
4373 | 17.1k | if (NewLoadedModuleFile && !Loaded.empty()433 ) |
4374 | 426 | *NewLoadedModuleFile = Loaded.back().Mod; |
4375 | | |
4376 | | // Here comes stuff that we only do once the entire chain is loaded. Do *not* |
4377 | | // remove modules from this point. Various fields are updated during reading |
4378 | | // the AST block and removing the modules would result in dangling pointers. |
4379 | | // They are generally only incidentally dereferenced, ie. a binary search |
4380 | | // runs over `GlobalSLocEntryMap`, which could cause an invalid module to |
4381 | | // be dereferenced but it wouldn't actually be used. |
4382 | | |
4383 | | // Load the AST blocks of all of the modules that we loaded. We can still |
4384 | | // hit errors parsing the ASTs at this point. |
4385 | 477k | for (ImportedModule &M : Loaded) { |
4386 | 477k | ModuleFile &F = *M.Mod; |
4387 | 477k | llvm::TimeTraceScope Scope2("Read Loaded AST", F.ModuleName); |
4388 | | |
4389 | | // Read the AST block. |
4390 | 477k | if (llvm::Error Err = ReadASTBlock(F, ClientLoadCapabilities)) { |
4391 | 5 | Error(std::move(Err)); |
4392 | 5 | return Failure; |
4393 | 5 | } |
4394 | | |
4395 | | // The AST block should always have a definition for the main module. |
4396 | 477k | if (F.isModule() && !F.DidReadTopLevelSubmodule473k ) { |
4397 | 0 | Error(diag::err_module_file_missing_top_level_submodule, F.FileName); |
4398 | 0 | return Failure; |
4399 | 0 | } |
4400 | | |
4401 | | // Read the extension blocks. |
4402 | 477k | while (477k !SkipCursorToBlock(F.Stream, EXTENSION_BLOCK_ID)) { |
4403 | 18 | if (llvm::Error Err = ReadExtensionBlock(F)) { |
4404 | 0 | Error(std::move(Err)); |
4405 | 0 | return Failure; |
4406 | 0 | } |
4407 | 18 | } |
4408 | | |
4409 | | // Once read, set the ModuleFile bit base offset and update the size in |
4410 | | // bits of all files we've seen. |
4411 | 477k | F.GlobalBitOffset = TotalModulesSizeInBits; |
4412 | 477k | TotalModulesSizeInBits += F.SizeInBits; |
4413 | 477k | GlobalBitOffsetsMap.insert(std::make_pair(F.GlobalBitOffset, &F)); |
4414 | 477k | } |
4415 | | |
4416 | | // Preload source locations and interesting indentifiers. |
4417 | 477k | for (ImportedModule &M : Loaded)17.1k { |
4418 | 477k | ModuleFile &F = *M.Mod; |
4419 | | |
4420 | | // Preload SLocEntries. |
4421 | 955k | for (unsigned I = 0, N = F.PreloadSLocEntries.size(); I != N; ++I477k ) { |
4422 | 477k | int Index = int(F.PreloadSLocEntries[I] - 1) + F.SLocEntryBaseID; |
4423 | | // Load it through the SourceManager and don't call ReadSLocEntry() |
4424 | | // directly because the entry may have already been loaded in which case |
4425 | | // calling ReadSLocEntry() directly would trigger an assertion in |
4426 | | // SourceManager. |
4427 | 477k | SourceMgr.getLoadedSLocEntryByID(Index); |
4428 | 477k | } |
4429 | | |
4430 | | // Map the original source file ID into the ID space of the current |
4431 | | // compilation. |
4432 | 477k | if (F.OriginalSourceFileID.isValid()) |
4433 | 477k | F.OriginalSourceFileID = TranslateFileID(F, F.OriginalSourceFileID); |
4434 | | |
4435 | 52.6M | for (auto Offset : F.PreloadIdentifierOffsets) { |
4436 | 52.6M | const unsigned char *Data = F.IdentifierTableData + Offset; |
4437 | | |
4438 | 52.6M | ASTIdentifierLookupTrait Trait(*this, F); |
4439 | 52.6M | auto KeyDataLen = Trait.ReadKeyDataLength(Data); |
4440 | 52.6M | auto Key = Trait.ReadKey(Data, KeyDataLen.first); |
4441 | | |
4442 | 52.6M | IdentifierInfo *II; |
4443 | 52.6M | if (!PP.getLangOpts().CPlusPlus) { |
4444 | | // Identifiers present in both the module file and the importing |
4445 | | // instance are marked out-of-date so that they can be deserialized |
4446 | | // on next use via ASTReader::updateOutOfDateIdentifier(). |
4447 | | // Identifiers present in the module file but not in the importing |
4448 | | // instance are ignored for now, preventing growth of the identifier |
4449 | | // table. They will be deserialized on first use via ASTReader::get(). |
4450 | 1.77M | auto It = PP.getIdentifierTable().find(Key); |
4451 | 1.77M | if (It == PP.getIdentifierTable().end()) |
4452 | 1.68M | continue; |
4453 | 81.4k | II = It->second; |
4454 | 50.9M | } else { |
4455 | | // With C++ modules, not many identifiers are considered interesting. |
4456 | | // All identifiers in the module file can be placed into the identifier |
4457 | | // table of the importing instance and marked as out-of-date. This makes |
4458 | | // ASTReader::get() a no-op, and deserialization will take place on |
4459 | | // first/next use via ASTReader::updateOutOfDateIdentifier(). |
4460 | 50.9M | II = &PP.getIdentifierTable().getOwn(Key); |
4461 | 50.9M | } |
4462 | | |
4463 | 50.9M | II->setOutOfDate(true); |
4464 | | |
4465 | | // Mark this identifier as being from an AST file so that we can track |
4466 | | // whether we need to serialize it. |
4467 | 50.9M | markIdentifierFromAST(*this, *II); |
4468 | | |
4469 | | // Associate the ID with the identifier so that the writer can reuse it. |
4470 | 50.9M | auto ID = Trait.ReadIdentifierID(Data + KeyDataLen.first); |
4471 | 50.9M | SetIdentifierInfo(ID, II); |
4472 | 50.9M | } |
4473 | 477k | } |
4474 | | |
4475 | | // Builtins and library builtins have already been initialized. Mark all |
4476 | | // identifiers as out-of-date, so that they are deserialized on first use. |
4477 | 17.1k | if (Type == MK_PCH || Type == MK_Preamble13.5k || Type == MK_MainFile13.1k ) |
4478 | 4.20k | for (auto &Id : PP.getIdentifierTable()) |
4479 | 1.24M | Id.second->setOutOfDate(true); |
4480 | | |
4481 | | // Mark selectors as out of date. |
4482 | 17.1k | for (const auto &Sel : SelectorGeneration) |
4483 | 86.0k | SelectorOutOfDate[Sel.first] = true; |
4484 | | |
4485 | | // Setup the import locations and notify the module manager that we've |
4486 | | // committed to these module files. |
4487 | 477k | for (ImportedModule &M : Loaded) { |
4488 | 477k | ModuleFile &F = *M.Mod; |
4489 | | |
4490 | 477k | ModuleMgr.moduleFileAccepted(&F); |
4491 | | |
4492 | | // Set the import location. |
4493 | 477k | F.DirectImportLoc = ImportLoc; |
4494 | | // FIXME: We assume that locations from PCH / preamble do not need |
4495 | | // any translation. |
4496 | 477k | if (!M.ImportedBy) |
4497 | 12.4k | F.ImportLoc = M.ImportLoc; |
4498 | 465k | else |
4499 | 465k | F.ImportLoc = TranslateSourceLocation(*M.ImportedBy, M.ImportLoc); |
4500 | 477k | } |
4501 | | |
4502 | | // Resolve any unresolved module exports. |
4503 | 5.58M | for (unsigned I = 0, N = UnresolvedModuleRefs.size(); I != N; ++I5.56M ) { |
4504 | 5.56M | UnresolvedModuleRef &Unresolved = UnresolvedModuleRefs[I]; |
4505 | 5.56M | SubmoduleID GlobalID = getGlobalSubmoduleID(*Unresolved.File,Unresolved.ID); |
4506 | 5.56M | Module *ResolvedMod = getSubmodule(GlobalID); |
4507 | | |
4508 | 5.56M | switch (Unresolved.Kind) { |
4509 | 1 | case UnresolvedModuleRef::Conflict: |
4510 | 1 | if (ResolvedMod) { |
4511 | 1 | Module::Conflict Conflict; |
4512 | 1 | Conflict.Other = ResolvedMod; |
4513 | 1 | Conflict.Message = Unresolved.String.str(); |
4514 | 1 | Unresolved.Mod->Conflicts.push_back(Conflict); |
4515 | 1 | } |
4516 | 1 | continue; |
4517 | | |
4518 | 4.91M | case UnresolvedModuleRef::Import: |
4519 | 4.91M | if (ResolvedMod) |
4520 | 4.91M | Unresolved.Mod->Imports.insert(ResolvedMod); |
4521 | 4.91M | continue; |
4522 | | |
4523 | 3 | case UnresolvedModuleRef::Affecting: |
4524 | 3 | if (ResolvedMod) |
4525 | 3 | Unresolved.Mod->AffectingClangModules.insert(ResolvedMod); |
4526 | 3 | continue; |
4527 | | |
4528 | 648k | case UnresolvedModuleRef::Export: |
4529 | 648k | if (ResolvedMod || Unresolved.IsWildcard534k ) |
4530 | 648k | Unresolved.Mod->Exports.push_back( |
4531 | 648k | Module::ExportDecl(ResolvedMod, Unresolved.IsWildcard)); |
4532 | 648k | continue; |
4533 | 5.56M | } |
4534 | 5.56M | } |
4535 | 17.1k | UnresolvedModuleRefs.clear(); |
4536 | | |
4537 | | // FIXME: How do we load the 'use'd modules? They may not be submodules. |
4538 | | // Might be unnecessary as use declarations are only used to build the |
4539 | | // module itself. |
4540 | | |
4541 | 17.1k | if (ContextObj) |
4542 | 17.1k | InitializeContext(); |
4543 | | |
4544 | 17.1k | if (SemaObj) |
4545 | 12.3k | UpdateSema(); |
4546 | | |
4547 | 17.1k | if (DeserializationListener) |
4548 | 10.6k | DeserializationListener->ReaderInitialized(this); |
4549 | | |
4550 | 17.1k | ModuleFile &PrimaryModule = ModuleMgr.getPrimaryModule(); |
4551 | 17.1k | if (PrimaryModule.OriginalSourceFileID.isValid()) { |
4552 | | // If this AST file is a precompiled preamble, then set the |
4553 | | // preamble file ID of the source manager to the file source file |
4554 | | // from which the preamble was built. |
4555 | 17.1k | if (Type == MK_Preamble) { |
4556 | 348 | SourceMgr.setPreambleFileID(PrimaryModule.OriginalSourceFileID); |
4557 | 16.8k | } else if (Type == MK_MainFile) { |
4558 | 219 | SourceMgr.setMainFileID(PrimaryModule.OriginalSourceFileID); |
4559 | 219 | } |
4560 | 17.1k | } |
4561 | | |
4562 | | // For any Objective-C class definitions we have already loaded, make sure |
4563 | | // that we load any additional categories. |
4564 | 17.1k | if (ContextObj) { |
4565 | 21.2k | for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I4.13k ) { |
4566 | 4.13k | loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), |
4567 | 4.13k | ObjCClassesLoaded[I], |
4568 | 4.13k | PreviousGeneration); |
4569 | 4.13k | } |
4570 | 17.1k | } |
4571 | | |
4572 | 17.1k | HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); |
4573 | 17.1k | if (HSOpts.ModulesValidateOncePerBuildSession) { |
4574 | | // Now we are certain that the module and all modules it depends on are |
4575 | | // up-to-date. For implicitly-built module files, ensure the corresponding |
4576 | | // timestamp files are up-to-date in this build session. |
4577 | 38 | for (unsigned I = 0, N = Loaded.size(); I != N; ++I19 ) { |
4578 | 19 | ImportedModule &M = Loaded[I]; |
4579 | 19 | if (M.Mod->Kind == MK_ImplicitModule && |
4580 | 19 | M.Mod->InputFilesValidationTimestamp < HSOpts.BuildSessionTimestamp) |
4581 | 9 | updateModuleTimestamp(*M.Mod); |
4582 | 19 | } |
4583 | 19 | } |
4584 | | |
4585 | 17.1k | return Success; |
4586 | 17.1k | } |
4587 | | |
4588 | | static ASTFileSignature readASTFileSignature(StringRef PCH); |
4589 | | |
4590 | | /// Whether \p Stream doesn't start with the AST/PCH file magic number 'CPCH'. |
4591 | 1.42M | static llvm::Error doesntStartWithASTFileMagic(BitstreamCursor &Stream) { |
4592 | | // FIXME checking magic headers is done in other places such as |
4593 | | // SerializedDiagnosticReader and GlobalModuleIndex, but error handling isn't |
4594 | | // always done the same. Unify it all with a helper. |
4595 | 1.42M | if (!Stream.canSkipToPos(4)) |
4596 | 7 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
4597 | 7 | "file too small to contain AST file magic"); |
4598 | 1.42M | for (unsigned C : {'C', 'P', 'C', 'H'}) |
4599 | 5.69M | if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = Stream.Read(8)) { |
4600 | 5.69M | if (Res.get() != C) |
4601 | 0 | return llvm::createStringError( |
4602 | 0 | std::errc::illegal_byte_sequence, |
4603 | 0 | "file doesn't start with AST file magic"); |
4604 | 5.69M | } else |
4605 | 3 | return Res.takeError(); |
4606 | 1.42M | return llvm::Error::success(); |
4607 | 1.42M | } |
4608 | | |
4609 | 23 | static unsigned moduleKindForDiagnostic(ModuleKind Kind) { |
4610 | 23 | switch (Kind) { |
4611 | 9 | case MK_PCH: |
4612 | 9 | return 0; // PCH |
4613 | 5 | case MK_ImplicitModule: |
4614 | 10 | case MK_ExplicitModule: |
4615 | 11 | case MK_PrebuiltModule: |
4616 | 11 | return 1; // module |
4617 | 3 | case MK_MainFile: |
4618 | 3 | case MK_Preamble: |
4619 | 3 | return 2; // main source file |
4620 | 23 | } |
4621 | 0 | llvm_unreachable("unknown module kind"); |
4622 | 0 | } |
4623 | | |
4624 | | ASTReader::ASTReadResult |
4625 | | ASTReader::ReadASTCore(StringRef FileName, |
4626 | | ModuleKind Type, |
4627 | | SourceLocation ImportLoc, |
4628 | | ModuleFile *ImportedBy, |
4629 | | SmallVectorImpl<ImportedModule> &Loaded, |
4630 | | off_t ExpectedSize, time_t ExpectedModTime, |
4631 | | ASTFileSignature ExpectedSignature, |
4632 | 3.32M | unsigned ClientLoadCapabilities) { |
4633 | 3.32M | ModuleFile *M; |
4634 | 3.32M | std::string ErrorStr; |
4635 | 3.32M | ModuleManager::AddModuleResult AddResult |
4636 | 3.32M | = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy, |
4637 | 3.32M | getGeneration(), ExpectedSize, ExpectedModTime, |
4638 | 3.32M | ExpectedSignature, readASTFileSignature, |
4639 | 3.32M | M, ErrorStr); |
4640 | | |
4641 | 3.32M | switch (AddResult) { |
4642 | 2.84M | case ModuleManager::AlreadyLoaded: |
4643 | 2.84M | Diag(diag::remark_module_import) |
4644 | 2.84M | << M->ModuleName << M->FileName << (ImportedBy ? true2.84M : false4.66k ) |
4645 | 2.84M | << (ImportedBy ? StringRef(ImportedBy->ModuleName)2.84M : StringRef()4.66k ); |
4646 | 2.84M | return Success; |
4647 | | |
4648 | 477k | case ModuleManager::NewlyLoaded: |
4649 | | // Load module file below. |
4650 | 477k | break; |
4651 | | |
4652 | 2.88k | case ModuleManager::Missing: |
4653 | | // The module file was missing; if the client can handle that, return |
4654 | | // it. |
4655 | 2.88k | if (ClientLoadCapabilities & ARR_Missing) |
4656 | 2.88k | return Missing; |
4657 | | |
4658 | | // Otherwise, return an error. |
4659 | 5 | Diag(diag::err_ast_file_not_found) |
4660 | 5 | << moduleKindForDiagnostic(Type) << FileName << !ErrorStr.empty() |
4661 | 5 | << ErrorStr; |
4662 | 5 | return Failure; |
4663 | | |
4664 | 27 | case ModuleManager::OutOfDate: |
4665 | | // We couldn't load the module file because it is out-of-date. If the |
4666 | | // client can handle out-of-date, return it. |
4667 | 27 | if (ClientLoadCapabilities & ARR_OutOfDate) |
4668 | 26 | return OutOfDate; |
4669 | | |
4670 | | // Otherwise, return an error. |
4671 | 1 | Diag(diag::err_ast_file_out_of_date) |
4672 | 1 | << moduleKindForDiagnostic(Type) << FileName << !ErrorStr.empty() |
4673 | 1 | << ErrorStr; |
4674 | 1 | return Failure; |
4675 | 3.32M | } |
4676 | | |
4677 | 477k | assert(M && "Missing module file"); |
4678 | | |
4679 | 477k | bool ShouldFinalizePCM = false; |
4680 | 477k | auto FinalizeOrDropPCM = llvm::make_scope_exit([&]() { |
4681 | 477k | auto &MC = getModuleManager().getModuleCache(); |
4682 | 477k | if (ShouldFinalizePCM) |
4683 | 477k | MC.finalizePCM(FileName); |
4684 | 157 | else |
4685 | 157 | MC.tryToDropPCM(FileName); |
4686 | 477k | }); |
4687 | 477k | ModuleFile &F = *M; |
4688 | 477k | BitstreamCursor &Stream = F.Stream; |
4689 | 477k | Stream = BitstreamCursor(PCHContainerRdr.ExtractPCH(*F.Buffer)); |
4690 | 477k | F.SizeInBits = F.Buffer->getBufferSize() * 8; |
4691 | | |
4692 | | // Sniff for the signature. |
4693 | 477k | if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) { |
4694 | 5 | Diag(diag::err_ast_file_invalid) |
4695 | 5 | << moduleKindForDiagnostic(Type) << FileName << std::move(Err); |
4696 | 5 | return Failure; |
4697 | 5 | } |
4698 | | |
4699 | | // This is used for compatibility with older PCH formats. |
4700 | 477k | bool HaveReadControlBlock = false; |
4701 | 1.91M | while (true) { |
4702 | 1.91M | Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); |
4703 | 1.91M | if (!MaybeEntry) { |
4704 | 0 | Error(MaybeEntry.takeError()); |
4705 | 0 | return Failure; |
4706 | 0 | } |
4707 | 1.91M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
4708 | | |
4709 | 1.91M | switch (Entry.Kind) { |
4710 | 0 | case llvm::BitstreamEntry::Error: |
4711 | 0 | case llvm::BitstreamEntry::Record: |
4712 | 0 | case llvm::BitstreamEntry::EndBlock: |
4713 | 0 | Error("invalid record at top-level of AST file"); |
4714 | 0 | return Failure; |
4715 | | |
4716 | 1.91M | case llvm::BitstreamEntry::SubBlock: |
4717 | 1.91M | break; |
4718 | 1.91M | } |
4719 | | |
4720 | 1.91M | switch (Entry.ID) { |
4721 | 477k | case CONTROL_BLOCK_ID: |
4722 | 477k | HaveReadControlBlock = true; |
4723 | 477k | switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) { |
4724 | 477k | case Success: |
4725 | | // Check that we didn't try to load a non-module AST file as a module. |
4726 | | // |
4727 | | // FIXME: Should we also perform the converse check? Loading a module as |
4728 | | // a PCH file sort of works, but it's a bit wonky. |
4729 | 477k | if ((Type == MK_ImplicitModule || Type == MK_ExplicitModule6.27k || |
4730 | 477k | Type == MK_PrebuiltModule4.92k ) && |
4731 | 477k | F.ModuleName.empty()473k ) { |
4732 | 1 | auto Result = (Type == MK_ImplicitModule) ? OutOfDate0 : Failure; |
4733 | 1 | if (Result != OutOfDate || |
4734 | 1 | (ClientLoadCapabilities & ARR_OutOfDate) == 00 ) |
4735 | 1 | Diag(diag::err_module_file_not_module) << FileName; |
4736 | 1 | return Result; |
4737 | 1 | } |
4738 | 477k | break; |
4739 | | |
4740 | 477k | case Failure: return Failure6 ; |
4741 | 0 | case Missing: return Missing; |
4742 | 115 | case OutOfDate: return OutOfDate; |
4743 | 0 | case VersionMismatch: return VersionMismatch; |
4744 | 26 | case ConfigurationMismatch: return ConfigurationMismatch; |
4745 | 4 | case HadErrors: return HadErrors; |
4746 | 477k | } |
4747 | 477k | break; |
4748 | | |
4749 | 477k | case AST_BLOCK_ID: |
4750 | 477k | if (!HaveReadControlBlock) { |
4751 | 0 | if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) |
4752 | 0 | Diag(diag::err_pch_version_too_old); |
4753 | 0 | return VersionMismatch; |
4754 | 0 | } |
4755 | | |
4756 | | // Record that we've loaded this module. |
4757 | 477k | Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc)); |
4758 | 477k | ShouldFinalizePCM = true; |
4759 | 477k | return Success; |
4760 | | |
4761 | 955k | default: |
4762 | 955k | if (llvm::Error Err = Stream.SkipBlock()) { |
4763 | 0 | Error(std::move(Err)); |
4764 | 0 | return Failure; |
4765 | 0 | } |
4766 | 955k | break; |
4767 | 1.91M | } |
4768 | 1.91M | } |
4769 | | |
4770 | 4 | llvm_unreachable("unexpected break; expected return"); |
4771 | 4 | } |
4772 | | |
4773 | | ASTReader::ASTReadResult |
4774 | | ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy, |
4775 | 477k | unsigned ClientLoadCapabilities) { |
4776 | 477k | const HeaderSearchOptions &HSOpts = |
4777 | 477k | PP.getHeaderSearchInfo().getHeaderSearchOpts(); |
4778 | 477k | bool AllowCompatibleConfigurationMismatch = |
4779 | 477k | F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule476k ; |
4780 | 477k | bool DisableValidation = shouldDisableValidationForFile(F); |
4781 | | |
4782 | 477k | ASTReadResult Result = readUnhashedControlBlockImpl( |
4783 | 477k | &F, F.Data, ClientLoadCapabilities, AllowCompatibleConfigurationMismatch, |
4784 | 477k | Listener.get(), |
4785 | 477k | WasImportedBy ? false465k : HSOpts.ModulesValidateDiagnosticOptions12.5k ); |
4786 | | |
4787 | | // If F was directly imported by another module, it's implicitly validated by |
4788 | | // the importing module. |
4789 | 477k | if (DisableValidation || WasImportedBy477k || |
4790 | 477k | (12.1k AllowConfigurationMismatch12.1k && Result == ConfigurationMismatch7 )) |
4791 | 465k | return Success; |
4792 | | |
4793 | 12.1k | if (Result == Failure) { |
4794 | 0 | Error("malformed block record in AST file"); |
4795 | 0 | return Failure; |
4796 | 0 | } |
4797 | | |
4798 | 12.1k | if (Result == OutOfDate && F.Kind == MK_ImplicitModule13 ) { |
4799 | | // If this module has already been finalized in the ModuleCache, we're stuck |
4800 | | // with it; we can only load a single version of each module. |
4801 | | // |
4802 | | // This can happen when a module is imported in two contexts: in one, as a |
4803 | | // user module; in another, as a system module (due to an import from |
4804 | | // another module marked with the [system] flag). It usually indicates a |
4805 | | // bug in the module map: this module should also be marked with [system]. |
4806 | | // |
4807 | | // If -Wno-system-headers (the default), and the first import is as a |
4808 | | // system module, then validation will fail during the as-user import, |
4809 | | // since -Werror flags won't have been validated. However, it's reasonable |
4810 | | // to treat this consistently as a system module. |
4811 | | // |
4812 | | // If -Wsystem-headers, the PCM on disk was built with |
4813 | | // -Wno-system-headers, and the first import is as a user module, then |
4814 | | // validation will fail during the as-system import since the PCM on disk |
4815 | | // doesn't guarantee that -Werror was respected. However, the -Werror |
4816 | | // flags were checked during the initial as-user import. |
4817 | 13 | if (getModuleManager().getModuleCache().isPCMFinal(F.FileName)) { |
4818 | 2 | Diag(diag::warn_module_system_bit_conflict) << F.FileName; |
4819 | 2 | return Success; |
4820 | 2 | } |
4821 | 13 | } |
4822 | | |
4823 | 12.1k | return Result; |
4824 | 12.1k | } |
4825 | | |
4826 | | ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( |
4827 | | ModuleFile *F, llvm::StringRef StreamData, unsigned ClientLoadCapabilities, |
4828 | | bool AllowCompatibleConfigurationMismatch, ASTReaderListener *Listener, |
4829 | 477k | bool ValidateDiagnosticOptions) { |
4830 | | // Initialize a stream. |
4831 | 477k | BitstreamCursor Stream(StreamData); |
4832 | | |
4833 | | // Sniff for the signature. |
4834 | 477k | if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) { |
4835 | | // FIXME this drops the error on the floor. |
4836 | 0 | consumeError(std::move(Err)); |
4837 | 0 | return Failure; |
4838 | 0 | } |
4839 | | |
4840 | | // Scan for the UNHASHED_CONTROL_BLOCK_ID block. |
4841 | 477k | if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID)) |
4842 | 0 | return Failure; |
4843 | | |
4844 | | // Read all of the records in the options block. |
4845 | 477k | RecordData Record; |
4846 | 477k | ASTReadResult Result = Success; |
4847 | 3.33M | while (true3.33M ) { |
4848 | 3.33M | Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); |
4849 | 3.33M | if (!MaybeEntry) { |
4850 | | // FIXME this drops the error on the floor. |
4851 | 0 | consumeError(MaybeEntry.takeError()); |
4852 | 0 | return Failure; |
4853 | 0 | } |
4854 | 3.33M | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
4855 | | |
4856 | 3.33M | switch (Entry.Kind) { |
4857 | 0 | case llvm::BitstreamEntry::Error: |
4858 | 0 | case llvm::BitstreamEntry::SubBlock: |
4859 | 0 | return Failure; |
4860 | | |
4861 | 477k | case llvm::BitstreamEntry::EndBlock: |
4862 | 477k | return Result; |
4863 | | |
4864 | 2.85M | case llvm::BitstreamEntry::Record: |
4865 | | // The interesting case. |
4866 | 2.85M | break; |
4867 | 3.33M | } |
4868 | | |
4869 | | // Read and process a record. |
4870 | 2.85M | Record.clear(); |
4871 | 2.85M | StringRef Blob; |
4872 | 2.85M | Expected<unsigned> MaybeRecordType = |
4873 | 2.85M | Stream.readRecord(Entry.ID, Record, &Blob); |
4874 | 2.85M | if (!MaybeRecordType) { |
4875 | | // FIXME this drops the error. |
4876 | 0 | return Failure; |
4877 | 0 | } |
4878 | 2.85M | switch ((UnhashedControlBlockRecordTypes)MaybeRecordType.get()) { |
4879 | 471k | case SIGNATURE: |
4880 | 471k | if (F) { |
4881 | 471k | F->Signature = ASTFileSignature::create(Blob.begin(), Blob.end()); |
4882 | 471k | assert(F->Signature != ASTFileSignature::createDummy() && |
4883 | 471k | "Dummy AST file signature not backpatched in ASTWriter."); |
4884 | 471k | } |
4885 | 471k | break; |
4886 | 471k | case AST_BLOCK_HASH: |
4887 | 471k | if (F) { |
4888 | 471k | F->ASTBlockHash = ASTFileSignature::create(Blob.begin(), Blob.end()); |
4889 | 471k | assert(F->ASTBlockHash != ASTFileSignature::createDummy() && |
4890 | 471k | "Dummy AST block hash not backpatched in ASTWriter."); |
4891 | 471k | } |
4892 | 471k | break; |
4893 | 477k | case DIAGNOSTIC_OPTIONS: { |
4894 | 477k | bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; |
4895 | 477k | if (Listener && ValidateDiagnosticOptions && |
4896 | 477k | !AllowCompatibleConfigurationMismatch12.6k && |
4897 | 477k | ParseDiagnosticOptions(Record, Complain, *Listener)11.6k ) |
4898 | 13 | Result = OutOfDate; // Don't return early. Read the signature. |
4899 | 477k | break; |
4900 | 471k | } |
4901 | 477k | case HEADER_SEARCH_PATHS: { |
4902 | 477k | bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; |
4903 | 477k | if (!AllowCompatibleConfigurationMismatch && |
4904 | 477k | ParseHeaderSearchPaths(Record, Complain, *Listener)475k ) |
4905 | 0 | Result = ConfigurationMismatch; |
4906 | 477k | break; |
4907 | 471k | } |
4908 | 477k | case DIAG_PRAGMA_MAPPINGS: |
4909 | 477k | if (!F) |
4910 | 74 | break; |
4911 | 477k | if (F->PragmaDiagMappings.empty()) |
4912 | 477k | F->PragmaDiagMappings.swap(Record); |
4913 | 0 | else |
4914 | 0 | F->PragmaDiagMappings.insert(F->PragmaDiagMappings.end(), |
4915 | 0 | Record.begin(), Record.end()); |
4916 | 477k | break; |
4917 | 477k | case HEADER_SEARCH_ENTRY_USAGE: |
4918 | 477k | if (!F) |
4919 | 74 | break; |
4920 | 477k | unsigned Count = Record[0]; |
4921 | 477k | const char *Byte = Blob.data(); |
4922 | 477k | F->SearchPathUsage = llvm::BitVector(Count, false); |
4923 | 955k | for (unsigned I = 0; I < Count; ++Byte477k ) |
4924 | 2.38M | for (unsigned Bit = 0; 477k Bit < 8 && I < Count2.38M ; ++Bit, ++I1.90M ) |
4925 | 1.90M | if (*Byte & (1 << Bit)) |
4926 | 487k | F->SearchPathUsage[I] = true; |
4927 | 477k | break; |
4928 | 2.85M | } |
4929 | 2.85M | } |
4930 | 477k | } |
4931 | | |
4932 | | /// Parse a record and blob containing module file extension metadata. |
4933 | | static bool parseModuleFileExtensionMetadata( |
4934 | | const SmallVectorImpl<uint64_t> &Record, |
4935 | | StringRef Blob, |
4936 | 20 | ModuleFileExtensionMetadata &Metadata) { |
4937 | 20 | if (Record.size() < 4) return true0 ; |
4938 | | |
4939 | 20 | Metadata.MajorVersion = Record[0]; |
4940 | 20 | Metadata.MinorVersion = Record[1]; |
4941 | | |
4942 | 20 | unsigned BlockNameLen = Record[2]; |
4943 | 20 | unsigned UserInfoLen = Record[3]; |
4944 | | |
4945 | 20 | if (BlockNameLen + UserInfoLen > Blob.size()) return true0 ; |
4946 | | |
4947 | 20 | Metadata.BlockName = std::string(Blob.data(), Blob.data() + BlockNameLen); |
4948 | 20 | Metadata.UserInfo = std::string(Blob.data() + BlockNameLen, |
4949 | 20 | Blob.data() + BlockNameLen + UserInfoLen); |
4950 | 20 | return false; |
4951 | 20 | } |
4952 | | |
4953 | 18 | llvm::Error ASTReader::ReadExtensionBlock(ModuleFile &F) { |
4954 | 18 | BitstreamCursor &Stream = F.Stream; |
4955 | | |
4956 | 18 | RecordData Record; |
4957 | 54 | while (true) { |
4958 | 54 | Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); |
4959 | 54 | if (!MaybeEntry) |
4960 | 0 | return MaybeEntry.takeError(); |
4961 | 54 | llvm::BitstreamEntry Entry = MaybeEntry.get(); |
4962 | | |
4963 | 54 | switch (Entry.Kind) { |
4964 | 0 | case llvm::BitstreamEntry::SubBlock: |
4965 | 0 | if (llvm::Error Err = Stream.SkipBlock()) |
4966 | 0 | return Err; |
4967 | 0 | continue; |
4968 | 18 | case llvm::BitstreamEntry::EndBlock: |
4969 | 18 | return llvm::Error::success(); |
4970 | 0 | case llvm::BitstreamEntry::Error: |
4971 | 0 | return llvm::createStringError(std::errc::illegal_byte_sequence, |
4972 | 0 | "malformed block record in AST file"); |
4973 | 36 | case llvm::BitstreamEntry::Record: |
4974 | 36 | break; |
4975 | 54 | } |
4976 | | |
4977 | 36 | Record.clear(); |
4978 | 36 | StringRef Blob; |
4979 | 36 | Expected<unsigned> MaybeRecCode = |
4980 | 36 | Stream.readRecord(Entry.ID, Record, &Blob); |
4981 | 36 | if (!MaybeRecCode) |
4982 | 0 | return MaybeRecCode.takeError(); |
4983 | 36 | switch (MaybeRecCode.get()) { |
4984 | 18 | case EXTENSION_METADATA: { |
4985 | 18 | ModuleFileExtensionMetadata Metadata; |
4986 | 18 | if (parseModuleFileExtensionMetadata(Record, Blob, Metadata)) |
4987 | 0 | return llvm::createStringError( |
4988 | 0 | std::errc::illegal_byte_sequence, |
4989 | 0 | "malformed EXTENSION_METADATA in AST file"); |
4990 | | |
4991 | | // Find a module file extension with this block name. |
4992 | 18 | auto Known = ModuleFileExtensions.find(Metadata.BlockName); |
4993 | 18 | if (Known == ModuleFileExtensions.end()) break3 ; |
4994 | | |
4995 | | // Form a reader. |
4996 | 15 | if (auto Reader = Known->second->createExtensionReader(Metadata, *this, |
4997 | 15 | F, Stream)) { |
4998 | 13 | F.ExtensionReaders.push_back(std::move(Reader)); |
4999 | 13 | } |
5000 | | |
5001 | 15 | break; |
5002 | 18 | } |
5003 | 36 | } |
5004 | 36 | } |
5005 | | |
5006 | 0 | return llvm::Error::success(); |
5007 | 18 | } |
5008 | | |
5009 | 17.1k | void ASTReader::InitializeContext() { |
5010 | 17.1k | assert(ContextObj && "no context to initialize"); |
5011 | 17.1k | ASTContext &Context = *ContextObj; |
5012 | | |
5013 | | // If there's a listener, notify them that we "read" the translation unit. |
5014 | 17.1k | if (DeserializationListener) |
5015 | 10.6k | DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, |
5016 | 10.6k | Context.getTranslationUnitDecl()); |
5017 | | |
5018 | | // FIXME: Find a better way to deal with collisions between these |
5019 | | // built-in types. Right now, we just ignore the problem. |
5020 | | |
5021 | | // Load the special types. |
5022 | 17.1k | if (SpecialTypes.size() >= NumSpecialTypeIDs) { |
5023 | 17.1k | if (unsigned String = SpecialTypes[SPECIAL_TYPE_CF_CONSTANT_STRING]) { |
5024 | 17.1k | if (!Context.CFConstantStringTypeDecl) |
5025 | 4.61k | Context.setCFConstantStringType(GetType(String)); |
5026 | 17.1k | } |
5027 | | |
5028 | 17.1k | if (unsigned File = SpecialTypes[SPECIAL_TYPE_FILE]) { |
5029 | 7.00k | QualType FileType = GetType(File); |
5030 | 7.00k | if (FileType.isNull()) { |
5031 | 0 | Error("FILE type is NULL"); |
5032 | 0 | return; |
5033 | 0 | } |
5034 | | |
5035 | 7.00k | if (!Context.FILEDecl) { |
5036 | 1.16k | if (const TypedefType *Typedef = FileType->getAs<TypedefType>()) |
5037 | 1.16k | Context.setFILEDecl(Typedef->getDecl()); |
5038 | 0 | else { |
5039 | 0 | const TagType *Tag = FileType->getAs<TagType>(); |
5040 | 0 | if (!Tag) { |
5041 | 0 | Error("Invalid FILE type in AST file"); |
5042 | 0 | return; |
5043 | 0 | } |
5044 | 0 | Context.setFILEDecl(Tag->getDecl()); |
5045 | 0 | } |
5046 | 1.16k | } |
5047 | 7.00k | } |
5048 | | |
5049 | 17.1k | if (unsigned Jmp_buf = SpecialTypes[SPECIAL_TYPE_JMP_BUF]) { |
5050 | 6.80k | QualType Jmp_bufType = GetType(Jmp_buf); |
5051 | 6.80k | if (Jmp_bufType.isNull()) { |
5052 | 0 | Error("jmp_buf type is NULL"); |
5053 | 0 | return; |
5054 | 0 | } |
5055 | | |
5056 | 6.80k | if (!Context.jmp_bufDecl) { |
5057 | 987 | if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>()) |
5058 | 987 | Context.setjmp_bufDecl(Typedef->getDecl()); |
5059 | 0 | else { |
5060 | 0 | const TagType *Tag = Jmp_bufType->getAs<TagType>(); |
5061 | 0 | if (!Tag) { |
5062 | 0 | Error("Invalid jmp_buf type in AST file"); |
5063 | 0 | return; |
5064 | 0 | } |
5065 | 0 | Context.setjmp_bufDecl(Tag->getDecl()); |
5066 | 0 | } |
5067 | 987 | } |
5068 | 6.80k | } |
5069 | | |
5070 | 17.1k | if (unsigned Sigjmp_buf = SpecialTypes[SPECIAL_TYPE_SIGJMP_BUF]) { |
5071 | 6.80k | QualType Sigjmp_bufType = GetType(Sigjmp_buf); |
5072 | 6.80k | if (Sigjmp_bufType.isNull()) { |
5073 | 0 | Error("sigjmp_buf type is NULL"); |
5074 | 0 | return; |
5075 | 0 | } |
5076 | | |
5077 | 6.80k | if (!Context.sigjmp_bufDecl) { |
5078 | 987 | if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>()) |
5079 | 987 | Context.setsigjmp_bufDecl(Typedef->getDecl()); |
5080 | 0 | else { |
5081 | 0 | const TagType *Tag = Sigjmp_bufType->getAs<TagType>(); |
5082 | 0 | assert(Tag && "Invalid sigjmp_buf type in AST file"); |
5083 | 0 | Context.setsigjmp_bufDecl(Tag->getDecl()); |
5084 | 0 | } |
5085 | 987 | } |
5086 | 6.80k | } |
5087 | | |
5088 | 17.1k | if (unsigned ObjCIdRedef |
5089 | 17.1k | = SpecialTypes[SPECIAL_TYPE_OBJC_ID_REDEFINITION]) { |
5090 | 287 | if (Context.ObjCIdRedefinitionType.isNull()) |
5091 | 91 | Context.ObjCIdRedefinitionType = GetType(ObjCIdRedef); |
5092 | 287 | } |
5093 | | |
5094 | 17.1k | if (unsigned ObjCClassRedef |
5095 | 17.1k | = SpecialTypes[SPECIAL_TYPE_OBJC_CLASS_REDEFINITION]) { |
5096 | 289 | if (Context.ObjCClassRedefinitionType.isNull()) |
5097 | 93 | Context.ObjCClassRedefinitionType = GetType(ObjCClassRedef); |
5098 | 289 | } |
5099 | | |
5100 | 17.1k | if (unsigned ObjCSelRedef |
5101 | 17.1k | = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) { |
5102 | 287 | if (Context.ObjCSelRedefinitionType.isNull()) |
5103 | 91 | Context.ObjCSelRedefinitionType = GetType(ObjCSelRedef); |
5104 | 287 | } |
5105 | | |
5106 | 17.1k | if (unsigned Ucontext_t = SpecialTypes[SPECIAL_TYPE_UCONTEXT_T]) { |
5107 | 6.80k | QualType Ucontext_tType = GetType(Ucontext_t); |
5108 | 6.80k | if (Ucontext_tType.isNull()) { |
5109 | 0 | Error("ucontext_t type is NULL"); |
5110 | 0 | return; |
5111 | 0 | } |
5112 | | |
5113 | 6.80k | if (!Context.ucontext_tDecl) { |
5114 | 987 | if (const TypedefType *Typedef = Ucontext_tType->getAs<TypedefType>()) |
5115 | 987 | Context.setucontext_tDecl(Typedef->getDecl()); |
5116 | 0 | else { |
5117 | 0 | const TagType *Tag = Ucontext_tType->getAs<TagType>(); |
5118 | 0 | assert(Tag && "Invalid ucontext_t type in AST file"); |
5119 | 0 | Context.setucontext_tDecl(Tag->getDecl()); |
5120 | 0 | } |
5121 | 987 | } |
5122 | 6.80k | } |
5123 | 17.1k | } |
5124 | | |
5125 | 17.1k | ReadPragmaDiagnosticMappings(Context.getDiagnostics()); |
5126 | | |
|