1//===- ASTUnit.cpp - ASTUnit utility --------------------------------------===//
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// ASTUnit Implementation.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/Frontend/ASTUnit.h"
14#include "clang/AST/ASTConsumer.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/CommentCommandTraits.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclBase.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclGroup.h"
21#include "clang/AST/DeclObjC.h"
22#include "clang/AST/DeclTemplate.h"
23#include "clang/AST/DeclarationName.h"
24#include "clang/AST/ExternalASTSource.h"
25#include "clang/AST/PrettyPrinter.h"
26#include "clang/AST/Type.h"
27#include "clang/AST/TypeOrdering.h"
28#include "clang/Basic/Diagnostic.h"
29#include "clang/Basic/DiagnosticFrontend.h"
30#include "clang/Basic/FileManager.h"
31#include "clang/Basic/IdentifierTable.h"
32#include "clang/Basic/LLVM.h"
33#include "clang/Basic/LangOptions.h"
34#include "clang/Basic/LangStandard.h"
35#include "clang/Basic/Module.h"
36#include "clang/Basic/SourceLocation.h"
37#include "clang/Basic/SourceManager.h"
38#include "clang/Basic/TargetInfo.h"
39#include "clang/Basic/TargetOptions.h"
40#include "clang/Frontend/CompilerInstance.h"
41#include "clang/Frontend/CompilerInvocation.h"
42#include "clang/Frontend/FrontendAction.h"
43#include "clang/Frontend/FrontendActions.h"
44#include "clang/Frontend/FrontendOptions.h"
45#include "clang/Frontend/MultiplexConsumer.h"
46#include "clang/Frontend/PrecompiledPreamble.h"
47#include "clang/Frontend/StandaloneDiagnostic.h"
48#include "clang/Frontend/Utils.h"
49#include "clang/Lex/HeaderSearch.h"
50#include "clang/Lex/HeaderSearchOptions.h"
51#include "clang/Lex/Lexer.h"
52#include "clang/Lex/PPCallbacks.h"
53#include "clang/Lex/PreprocessingRecord.h"
54#include "clang/Lex/Preprocessor.h"
55#include "clang/Lex/PreprocessorOptions.h"
56#include "clang/Lex/Token.h"
57#include "clang/Sema/CodeCompleteConsumer.h"
58#include "clang/Sema/CodeCompleteOptions.h"
59#include "clang/Sema/Sema.h"
60#include "clang/Sema/SemaCodeCompletion.h"
61#include "clang/Serialization/ASTReader.h"
62#include "clang/Serialization/ASTWriter.h"
63#include "clang/Serialization/InMemoryModuleCache.h"
64#include "clang/Serialization/ModuleCache.h"
65#include "clang/Serialization/ModuleFile.h"
66#include "clang/Serialization/PCHContainerOperations.h"
67#include "llvm/ADT/ArrayRef.h"
68#include "llvm/ADT/DenseMap.h"
69#include "llvm/ADT/IntrusiveRefCntPtr.h"
70#include "llvm/ADT/STLExtras.h"
71#include "llvm/ADT/ScopeExit.h"
72#include "llvm/ADT/SmallVector.h"
73#include "llvm/ADT/StringMap.h"
74#include "llvm/ADT/StringRef.h"
75#include "llvm/ADT/StringSet.h"
76#include "llvm/ADT/Twine.h"
77#include "llvm/ADT/iterator_range.h"
78#include "llvm/Bitstream/BitstreamWriter.h"
79#include "llvm/Support/Allocator.h"
80#include "llvm/Support/CrashRecoveryContext.h"
81#include "llvm/Support/DJB.h"
82#include "llvm/Support/ErrorHandling.h"
83#include "llvm/Support/ErrorOr.h"
84#include "llvm/Support/MemoryBuffer.h"
85#include "llvm/Support/SaveAndRestore.h"
86#include "llvm/Support/Timer.h"
87#include "llvm/Support/VirtualFileSystem.h"
88#include "llvm/Support/raw_ostream.h"
89#include <algorithm>
90#include <atomic>
91#include <cassert>
92#include <cstdint>
93#include <cstdio>
94#include <cstdlib>
95#include <memory>
96#include <mutex>
97#include <optional>
98#include <string>
99#include <tuple>
100#include <utility>
101#include <vector>
102
103using namespace clang;
104
105using llvm::TimeRecord;
106
107namespace {
108
109 class SimpleTimer {
110 bool WantTiming;
111 TimeRecord Start;
112 std::string Output;
113
114 public:
115 explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) {
116 if (WantTiming)
117 Start = TimeRecord::getCurrentTime();
118 }
119
120 ~SimpleTimer() {
121 if (WantTiming) {
122 TimeRecord Elapsed = TimeRecord::getCurrentTime();
123 Elapsed -= Start;
124 llvm::errs() << Output << ':';
125 Elapsed.print(Total: Elapsed, OS&: llvm::errs());
126 llvm::errs() << '\n';
127 }
128 }
129
130 void setOutput(const Twine &Output) {
131 if (WantTiming)
132 this->Output = Output.str();
133 }
134 };
135
136} // namespace
137
138template <class T>
139static std::unique_ptr<T> valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val) {
140 if (!Val)
141 return nullptr;
142 return std::move(*Val);
143}
144
145/// Get a source buffer for \p MainFilePath, handling all file-to-file
146/// and file-to-buffer remappings inside \p Invocation.
147static std::unique_ptr<llvm::MemoryBuffer>
148getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
149 llvm::vfs::FileSystem *VFS,
150 StringRef FilePath, bool isVolatile) {
151 const auto &PreprocessorOpts = Invocation.getPreprocessorOpts();
152
153 // Try to determine if the main file has been remapped, either from the
154 // command line (to another file) or directly through the compiler
155 // invocation (to a memory buffer).
156 llvm::MemoryBuffer *Buffer = nullptr;
157 std::unique_ptr<llvm::MemoryBuffer> BufferOwner;
158 auto FileStatus = VFS->status(Path: FilePath);
159 if (FileStatus) {
160 llvm::sys::fs::UniqueID MainFileID = FileStatus->getUniqueID();
161
162 // Check whether there is a file-file remapping of the main file
163 for (const auto &RF : PreprocessorOpts.RemappedFiles) {
164 std::string MPath(RF.first);
165 auto MPathStatus = VFS->status(Path: MPath);
166 if (MPathStatus) {
167 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
168 if (MainFileID == MID) {
169 // We found a remapping. Try to load the resulting, remapped source.
170 BufferOwner = valueOrNull(Val: VFS->getBufferForFile(Name: RF.second, FileSize: -1, RequiresNullTerminator: true, IsVolatile: isVolatile));
171 if (!BufferOwner)
172 return nullptr;
173 }
174 }
175 }
176
177 // Check whether there is a file-buffer remapping. It supercedes the
178 // file-file remapping.
179 for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
180 std::string MPath(RB.first);
181 auto MPathStatus = VFS->status(Path: MPath);
182 if (MPathStatus) {
183 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
184 if (MainFileID == MID) {
185 // We found a remapping.
186 BufferOwner.reset();
187 Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);
188 }
189 }
190 }
191 }
192
193 // If the main source file was not remapped, load it now.
194 if (!Buffer && !BufferOwner) {
195 BufferOwner = valueOrNull(Val: VFS->getBufferForFile(Name: FilePath, FileSize: -1, RequiresNullTerminator: true, IsVolatile: isVolatile));
196 if (!BufferOwner)
197 return nullptr;
198 }
199
200 if (BufferOwner)
201 return BufferOwner;
202 if (!Buffer)
203 return nullptr;
204 return llvm::MemoryBuffer::getMemBufferCopy(InputData: Buffer->getBuffer(), BufferName: FilePath);
205}
206
207void ASTUnit::clearFileLevelDecls() {
208 FileDecls.clear();
209}
210
211/// After failing to build a precompiled preamble (due to
212/// errors in the source that occurs in the preamble), the number of
213/// reparses during which we'll skip even trying to precompile the
214/// preamble.
215const unsigned DefaultPreambleRebuildInterval = 5;
216
217/// Tracks the number of ASTUnit objects that are currently active.
218///
219/// Used for debugging purposes only.
220static std::atomic<unsigned> ActiveASTUnitObjects;
221
222ASTUnit::ASTUnit(bool _MainFileIsAST)
223 : CodeGenOpts(std::make_unique<CodeGenOptions>()),
224 MainFileIsAST(_MainFileIsAST), WantTiming(getenv(name: "LIBCLANG_TIMING")),
225 ShouldCacheCodeCompletionResults(false),
226 IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
227 UnsafeToFree(false) {
228 if (getenv(name: "LIBCLANG_OBJTRACKING"))
229 fprintf(stderr, format: "+++ %u translation units\n", ++ActiveASTUnitObjects);
230}
231
232ASTUnit::~ASTUnit() {
233 // If we loaded from an AST file, balance out the BeginSourceFile call.
234 if (MainFileIsAST && getDiagnostics().getClient()) {
235 getDiagnostics().getClient()->EndSourceFile();
236 }
237
238 clearFileLevelDecls();
239
240 // Free the buffers associated with remapped files. We are required to
241 // perform this operation here because we explicitly request that the
242 // compiler instance *not* free these buffers for each invocation of the
243 // parser.
244 if (Invocation && OwnsRemappedFileBuffers) {
245 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
246 for (const auto &RB : PPOpts.RemappedFileBuffers)
247 delete RB.second;
248 }
249
250 ClearCachedCompletionResults();
251
252 if (getenv(name: "LIBCLANG_OBJTRACKING"))
253 fprintf(stderr, format: "--- %u translation units\n", --ActiveASTUnitObjects);
254}
255
256void ASTUnit::setPreprocessor(std::shared_ptr<Preprocessor> PP) {
257 this->PP = std::move(PP);
258}
259
260void ASTUnit::enableSourceFileDiagnostics() {
261 assert(getDiagnostics().getClient() && Ctx &&
262 "Bad context for source file");
263 getDiagnostics().getClient()->BeginSourceFile(LangOpts: Ctx->getLangOpts(), PP: PP.get());
264}
265
266/// Determine the set of code-completion contexts in which this
267/// declaration should be shown.
268static uint64_t getDeclShowContexts(const NamedDecl *ND,
269 const LangOptions &LangOpts,
270 bool &IsNestedNameSpecifier) {
271 IsNestedNameSpecifier = false;
272
273 if (isa<UsingShadowDecl>(Val: ND))
274 ND = ND->getUnderlyingDecl();
275 if (!ND)
276 return 0;
277
278 uint64_t Contexts = 0;
279 if (isa<TypeDecl>(Val: ND) || isa<ObjCInterfaceDecl>(Val: ND) ||
280 isa<ClassTemplateDecl>(Val: ND) || isa<TemplateTemplateParmDecl>(Val: ND) ||
281 isa<TypeAliasTemplateDecl>(Val: ND)) {
282 // Types can appear in these contexts.
283 if (LangOpts.CPlusPlus || !isa<TagDecl>(Val: ND))
284 Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)
285 | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
286 | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
287 | (1LL << CodeCompletionContext::CCC_Statement)
288 | (1LL << CodeCompletionContext::CCC_Type)
289 | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);
290
291 // In C++, types can appear in expressions contexts (for functional casts).
292 if (LangOpts.CPlusPlus)
293 Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
294
295 // In Objective-C, message sends can send interfaces. In Objective-C++,
296 // all types are available due to functional casts.
297 if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(Val: ND))
298 Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
299
300 // In Objective-C, you can only be a subclass of another Objective-C class
301 if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(Val: ND)) {
302 // Objective-C interfaces can be used in a class property expression.
303 if (ID->getDefinition())
304 Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
305 Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName);
306 Contexts |= (1LL << CodeCompletionContext::CCC_ObjCClassForwardDecl);
307 }
308
309 // Deal with tag names.
310 if (isa<EnumDecl>(Val: ND)) {
311 Contexts |= (1LL << CodeCompletionContext::CCC_EnumTag);
312
313 // Part of the nested-name-specifier in C++0x.
314 if (LangOpts.CPlusPlus11)
315 IsNestedNameSpecifier = true;
316 } else if (const auto *Record = dyn_cast<RecordDecl>(Val: ND)) {
317 if (Record->isUnion())
318 Contexts |= (1LL << CodeCompletionContext::CCC_UnionTag);
319 else
320 Contexts |= (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
321
322 if (LangOpts.CPlusPlus)
323 IsNestedNameSpecifier = true;
324 } else if (isa<ClassTemplateDecl>(Val: ND))
325 IsNestedNameSpecifier = true;
326 } else if (isa<ValueDecl>(Val: ND) || isa<FunctionTemplateDecl>(Val: ND)) {
327 // Values can appear in these contexts.
328 Contexts = (1LL << CodeCompletionContext::CCC_Statement)
329 | (1LL << CodeCompletionContext::CCC_Expression)
330 | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
331 | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
332 } else if (isa<ObjCProtocolDecl>(Val: ND)) {
333 Contexts = (1LL << CodeCompletionContext::CCC_ObjCProtocolName);
334 } else if (isa<ObjCCategoryDecl>(Val: ND)) {
335 Contexts = (1LL << CodeCompletionContext::CCC_ObjCCategoryName);
336 } else if (isa<NamespaceDecl>(Val: ND) || isa<NamespaceAliasDecl>(Val: ND)) {
337 Contexts = (1LL << CodeCompletionContext::CCC_Namespace);
338
339 // Part of the nested-name-specifier.
340 IsNestedNameSpecifier = true;
341 }
342
343 return Contexts;
344}
345
346void ASTUnit::CacheCodeCompletionResults() {
347 if (!TheSema)
348 return;
349
350 SimpleTimer Timer(WantTiming);
351 Timer.setOutput("Cache global code completions for " + getMainFileName());
352
353 // Clear out the previous results.
354 ClearCachedCompletionResults();
355
356 // Gather the set of global code completions.
357 using Result = CodeCompletionResult;
358 SmallVector<Result, 8> Results;
359 CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
360 CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator);
361 TheSema->CodeCompletion().GatherGlobalCodeCompletions(
362 Allocator&: *CachedCompletionAllocator, CCTUInfo, Results);
363
364 // Translate global code completions into cached completions.
365 llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
366 CodeCompletionContext CCContext(CodeCompletionContext::CCC_TopLevel);
367
368 for (auto &R : Results) {
369 switch (R.Kind) {
370 case Result::RK_Declaration: {
371 bool IsNestedNameSpecifier = false;
372 CachedCodeCompletionResult CachedResult;
373 CachedResult.Completion = R.CreateCodeCompletionString(
374 S&: *TheSema, CCContext, Allocator&: *CachedCompletionAllocator, CCTUInfo,
375 IncludeBriefComments: IncludeBriefCommentsInCodeCompletion);
376 CachedResult.ShowInContexts = getDeclShowContexts(
377 ND: R.Declaration, LangOpts: Ctx->getLangOpts(), IsNestedNameSpecifier);
378 CachedResult.Priority = R.Priority;
379 CachedResult.Kind = R.CursorKind;
380 CachedResult.Availability = R.Availability;
381
382 // Keep track of the type of this completion in an ASTContext-agnostic
383 // way.
384 QualType UsageType = getDeclUsageType(C&: *Ctx, Qualifier: R.Qualifier, ND: R.Declaration);
385 if (UsageType.isNull()) {
386 CachedResult.TypeClass = STC_Void;
387 CachedResult.Type = 0;
388 } else {
389 CanQualType CanUsageType
390 = Ctx->getCanonicalType(T: UsageType.getUnqualifiedType());
391 CachedResult.TypeClass = getSimplifiedTypeClass(T: CanUsageType);
392
393 // Determine whether we have already seen this type. If so, we save
394 // ourselves the work of formatting the type string by using the
395 // temporary, CanQualType-based hash table to find the associated value.
396 unsigned &TypeValue = CompletionTypes[CanUsageType];
397 if (TypeValue == 0) {
398 TypeValue = CompletionTypes.size();
399 CachedCompletionTypes[QualType(CanUsageType).getAsString()]
400 = TypeValue;
401 }
402
403 CachedResult.Type = TypeValue;
404 }
405
406 CachedCompletionResults.push_back(x: CachedResult);
407
408 /// Handle nested-name-specifiers in C++.
409 if (TheSema->Context.getLangOpts().CPlusPlus && IsNestedNameSpecifier &&
410 !R.StartsNestedNameSpecifier) {
411 // The contexts in which a nested-name-specifier can appear in C++.
412 uint64_t NNSContexts
413 = (1LL << CodeCompletionContext::CCC_TopLevel)
414 | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
415 | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
416 | (1LL << CodeCompletionContext::CCC_Statement)
417 | (1LL << CodeCompletionContext::CCC_Expression)
418 | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
419 | (1LL << CodeCompletionContext::CCC_EnumTag)
420 | (1LL << CodeCompletionContext::CCC_UnionTag)
421 | (1LL << CodeCompletionContext::CCC_ClassOrStructTag)
422 | (1LL << CodeCompletionContext::CCC_Type)
423 | (1LL << CodeCompletionContext::CCC_SymbolOrNewName)
424 | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);
425
426 if (isa<NamespaceDecl>(Val: R.Declaration) ||
427 isa<NamespaceAliasDecl>(Val: R.Declaration))
428 NNSContexts |= (1LL << CodeCompletionContext::CCC_Namespace);
429
430 if (uint64_t RemainingContexts
431 = NNSContexts & ~CachedResult.ShowInContexts) {
432 // If there any contexts where this completion can be a
433 // nested-name-specifier but isn't already an option, create a
434 // nested-name-specifier completion.
435 R.StartsNestedNameSpecifier = true;
436 CachedResult.Completion = R.CreateCodeCompletionString(
437 S&: *TheSema, CCContext, Allocator&: *CachedCompletionAllocator, CCTUInfo,
438 IncludeBriefComments: IncludeBriefCommentsInCodeCompletion);
439 CachedResult.ShowInContexts = RemainingContexts;
440 CachedResult.Priority = CCP_NestedNameSpecifier;
441 CachedResult.TypeClass = STC_Void;
442 CachedResult.Type = 0;
443 CachedCompletionResults.push_back(x: CachedResult);
444 }
445 }
446 break;
447 }
448
449 case Result::RK_Keyword:
450 case Result::RK_Pattern:
451 // Ignore keywords and patterns; we don't care, since they are so
452 // easily regenerated.
453 break;
454
455 case Result::RK_Macro: {
456 CachedCodeCompletionResult CachedResult;
457 CachedResult.Completion = R.CreateCodeCompletionString(
458 S&: *TheSema, CCContext, Allocator&: *CachedCompletionAllocator, CCTUInfo,
459 IncludeBriefComments: IncludeBriefCommentsInCodeCompletion);
460 CachedResult.ShowInContexts
461 = (1LL << CodeCompletionContext::CCC_TopLevel)
462 | (1LL << CodeCompletionContext::CCC_ObjCInterface)
463 | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
464 | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
465 | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
466 | (1LL << CodeCompletionContext::CCC_Statement)
467 | (1LL << CodeCompletionContext::CCC_Expression)
468 | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
469 | (1LL << CodeCompletionContext::CCC_MacroNameUse)
470 | (1LL << CodeCompletionContext::CCC_PreprocessorExpression)
471 | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
472 | (1LL << CodeCompletionContext::CCC_OtherWithMacros);
473
474 CachedResult.Priority = R.Priority;
475 CachedResult.Kind = R.CursorKind;
476 CachedResult.Availability = R.Availability;
477 CachedResult.TypeClass = STC_Void;
478 CachedResult.Type = 0;
479 CachedCompletionResults.push_back(x: CachedResult);
480 break;
481 }
482 }
483 }
484
485 // Save the current top-level hash value.
486 CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
487}
488
489void ASTUnit::ClearCachedCompletionResults() {
490 CachedCompletionResults.clear();
491 CachedCompletionTypes.clear();
492 CachedCompletionAllocator = nullptr;
493}
494
495namespace {
496
497/// Gathers information from ASTReader that will be used to initialize
498/// a Preprocessor.
499class ASTInfoCollector : public ASTReaderListener {
500 HeaderSearchOptions &HSOpts;
501 std::string &ContextHash;
502 PreprocessorOptions &PPOpts;
503 LangOptions &LangOpts;
504 CodeGenOptions &CodeGenOpts;
505 TargetOptions &TargetOpts;
506 uint32_t &Counter;
507
508public:
509 ASTInfoCollector(HeaderSearchOptions &HSOpts, std::string &ContextHash,
510 PreprocessorOptions &PPOpts, LangOptions &LangOpts,
511 CodeGenOptions &CodeGenOpts, TargetOptions &TargetOpts,
512 uint32_t &Counter)
513 : HSOpts(HSOpts), ContextHash(ContextHash), PPOpts(PPOpts),
514 LangOpts(LangOpts), CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts),
515 Counter(Counter) {}
516
517 bool ReadLanguageOptions(const LangOptions &NewLangOpts,
518 StringRef ModuleFilename, bool Complain,
519 bool AllowCompatibleDifferences) override {
520 LangOpts = NewLangOpts;
521 return false;
522 }
523
524 bool ReadCodeGenOptions(const CodeGenOptions &NewCodeGenOpts,
525 StringRef ModuleFilename, bool Complain,
526 bool AllowCompatibleDifferences) override {
527 CodeGenOpts = NewCodeGenOpts;
528 return false;
529 }
530
531 bool ReadHeaderSearchOptions(const HeaderSearchOptions &NewHSOpts,
532 StringRef ModuleFilename,
533 StringRef NewContextHash,
534 bool Complain) override {
535 HSOpts = NewHSOpts;
536 ContextHash = NewContextHash;
537 return false;
538 }
539
540 bool ReadHeaderSearchPaths(const HeaderSearchOptions &NewHSOpts,
541 bool Complain) override {
542 HSOpts.UserEntries = NewHSOpts.UserEntries;
543 HSOpts.SystemHeaderPrefixes = NewHSOpts.SystemHeaderPrefixes;
544 HSOpts.VFSOverlayFiles = NewHSOpts.VFSOverlayFiles;
545 return false;
546 }
547
548 bool ReadPreprocessorOptions(const PreprocessorOptions &NewPPOpts,
549 StringRef ModuleFilename, bool ReadMacros,
550 bool Complain,
551 std::string &SuggestedPredefines) override {
552 PPOpts = NewPPOpts;
553 return false;
554 }
555
556 bool ReadTargetOptions(const TargetOptions &NewTargetOpts,
557 StringRef ModuleFilename, bool Complain,
558 bool AllowCompatibleDifferences) override {
559 TargetOpts = NewTargetOpts;
560 return false;
561 }
562
563 void ReadCounter(const serialization::ModuleFile &M,
564 uint32_t NewCounter) override {
565 Counter = NewCounter;
566 }
567};
568} // anonymous namespace
569
570FilterAndStoreDiagnosticConsumer::FilterAndStoreDiagnosticConsumer(
571 SmallVectorImpl<StoredDiagnostic> *StoredDiags,
572 SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags,
573 bool CaptureNonErrorsFromIncludes)
574 : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
575 CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
576 assert((StoredDiags || StandaloneDiags) &&
577 "No output collections were passed to StoredDiagnosticConsumer.");
578}
579
580void FilterAndStoreDiagnosticConsumer::BeginSourceFile(
581 const LangOptions &LangOpts, const Preprocessor *PP) {
582 this->LangOpts = &LangOpts;
583 if (PP)
584 SourceMgr = &PP->getSourceManager();
585}
586
587static bool isInMainFile(const clang::Diagnostic &D) {
588 if (!D.hasSourceManager() || !D.getLocation().isValid())
589 return false;
590
591 auto &M = D.getSourceManager();
592 return M.isWrittenInMainFile(Loc: M.getExpansionLoc(Loc: D.getLocation()));
593}
594
595void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
596 DiagnosticsEngine::Level Level, const Diagnostic &Info) {
597 // Default implementation (Warnings/errors count).
598 DiagnosticConsumer::HandleDiagnostic(DiagLevel: Level, Info);
599
600 // Only record the diagnostic if it's part of the source manager we know
601 // about. This effectively drops diagnostics from modules we're building.
602 // FIXME: In the long run, ee don't want to drop source managers from modules.
603 if (!Info.hasSourceManager() || &Info.getSourceManager() == SourceMgr) {
604 if (!CaptureNonErrorsFromIncludes && Level <= DiagnosticsEngine::Warning &&
605 !isInMainFile(D: Info)) {
606 return;
607 }
608
609 StoredDiagnostic *ResultDiag = nullptr;
610 if (StoredDiags) {
611 StoredDiags->emplace_back(Args&: Level, Args: Info);
612 ResultDiag = &StoredDiags->back();
613 }
614
615 if (StandaloneDiags) {
616 std::optional<StoredDiagnostic> StoredDiag;
617 if (!ResultDiag) {
618 StoredDiag.emplace(args&: Level, args: Info);
619 ResultDiag = &*StoredDiag;
620 }
621 StandaloneDiags->emplace_back(Args: *LangOpts, Args&: *ResultDiag);
622 }
623 }
624}
625
626CaptureDroppedDiagnostics::CaptureDroppedDiagnostics(
627 CaptureDiagsKind CaptureDiagnostics, DiagnosticsEngine &Diags,
628 SmallVectorImpl<StoredDiagnostic> *StoredDiags,
629 SmallVectorImpl<StandaloneDiagnostic> *StandaloneDiags)
630 : Diags(Diags),
631 Client(StoredDiags, StandaloneDiags,
632 CaptureDiagnostics !=
633 CaptureDiagsKind::AllWithoutNonErrorsFromIncludes) {
634 if (CaptureDiagnostics != CaptureDiagsKind::None ||
635 Diags.getClient() == nullptr) {
636 OwningPreviousClient = Diags.takeClient();
637 PreviousClient = Diags.getClient();
638 Diags.setClient(client: &Client, ShouldOwnClient: false);
639 }
640}
641
642CaptureDroppedDiagnostics::~CaptureDroppedDiagnostics() {
643 if (Diags.getClient() == &Client)
644 Diags.setClient(client: PreviousClient, ShouldOwnClient: !!OwningPreviousClient.release());
645}
646
647IntrusiveRefCntPtr<ASTReader> ASTUnit::getASTReader() const {
648 return Reader;
649}
650
651ASTMutationListener *ASTUnit::getASTMutationListener() {
652 if (WriterData)
653 return &WriterData->Writer;
654 return nullptr;
655}
656
657ASTDeserializationListener *ASTUnit::getDeserializationListener() {
658 if (WriterData)
659 return &WriterData->Writer;
660 return nullptr;
661}
662
663std::unique_ptr<llvm::MemoryBuffer>
664ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
665 assert(FileMgr);
666 auto Buffer = FileMgr->getBufferForFile(Filename, isVolatile: UserFilesAreVolatile);
667 if (Buffer)
668 return std::move(*Buffer);
669 if (ErrorStr)
670 *ErrorStr = Buffer.getError().message();
671 return nullptr;
672}
673
674/// Configure the diagnostics object for use with ASTUnit.
675void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
676 ASTUnit &AST,
677 CaptureDiagsKind CaptureDiagnostics) {
678 assert(Diags.get() && "no DiagnosticsEngine was provided");
679 if (CaptureDiagnostics != CaptureDiagsKind::None)
680 Diags->setClient(client: new FilterAndStoreDiagnosticConsumer(
681 &AST.StoredDiagnostics, nullptr,
682 CaptureDiagnostics != CaptureDiagsKind::AllWithoutNonErrorsFromIncludes));
683}
684
685std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
686 StringRef Filename, const PCHContainerReader &PCHContainerRdr,
687 WhatToLoad ToLoad, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
688 std::shared_ptr<DiagnosticOptions> DiagOpts,
689 IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
690 const FileSystemOptions &FileSystemOpts, const HeaderSearchOptions &HSOpts,
691 const LangOptions *ProvidedLangOpts, bool OnlyLocalDecls,
692 CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors,
693 bool UserFilesAreVolatile) {
694 std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
695
696 // Recover resources if we crash before exiting this method.
697 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
698 ASTUnitCleanup(AST.get());
699 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
700 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
701 DiagCleanup(Diags.get());
702
703 ConfigureDiags(Diags, AST&: *AST, CaptureDiagnostics);
704
705 std::unique_ptr<LangOptions> LocalLangOpts;
706 const LangOptions &LangOpts = [&]() -> const LangOptions & {
707 if (ProvidedLangOpts)
708 return *ProvidedLangOpts;
709 LocalLangOpts = std::make_unique<LangOptions>();
710 return *LocalLangOpts;
711 }();
712
713 AST->LangOpts = std::make_unique<LangOptions>(args: LangOpts);
714 AST->OnlyLocalDecls = OnlyLocalDecls;
715 AST->CaptureDiagnostics = CaptureDiagnostics;
716 AST->DiagOpts = DiagOpts;
717 AST->Diagnostics = Diags;
718 AST->UserFilesAreVolatile = UserFilesAreVolatile;
719 AST->HSOpts = std::make_unique<HeaderSearchOptions>(args: HSOpts);
720 AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.getFormats().front());
721 AST->PPOpts = std::make_shared<PreprocessorOptions>();
722 AST->CodeGenOpts = std::make_unique<CodeGenOptions>();
723 AST->TargetOpts = std::make_shared<TargetOptions>();
724
725 AST->ModCache = createCrossProcessModuleCache();
726
727 // Gather info for preprocessor construction later on.
728 std::string ContextHash;
729 unsigned Counter = 0;
730 // Using a temporary FileManager since the AST file might specify custom
731 // HeaderSearchOptions::VFSOverlayFiles that affect the underlying VFS.
732 FileManager TmpFileMgr(FileSystemOpts, VFS);
733 ASTInfoCollector Collector(*AST->HSOpts, ContextHash, *AST->PPOpts,
734 *AST->LangOpts, *AST->CodeGenOpts,
735 *AST->TargetOpts, Counter);
736 if (ASTReader::readASTFileControlBlock(
737 Filename, FileMgr&: TmpFileMgr, ModCache: *AST->ModCache, PCHContainerRdr,
738 /*FindModuleFileExtensions=*/true, Listener&: Collector,
739 /*ValidateDiagnosticOptions=*/true, ClientLoadCapabilities: ASTReader::ARR_None)) {
740 AST->getDiagnostics().Report(DiagID: diag::err_fe_unable_to_load_ast_file);
741 return nullptr;
742 }
743
744 VFS = createVFSFromOverlayFiles(VFSOverlayFiles: AST->HSOpts->VFSOverlayFiles,
745 Diags&: *AST->Diagnostics, BaseFS: std::move(VFS));
746
747 AST->FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(A: FileSystemOpts, A&: VFS);
748
749 AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
750 A&: AST->getDiagnostics(), A&: AST->getFileManager(), A&: UserFilesAreVolatile);
751
752 AST->HSOpts->PrebuiltModuleFiles = HSOpts.PrebuiltModuleFiles;
753 AST->HSOpts->PrebuiltModulePaths = HSOpts.PrebuiltModulePaths;
754 AST->HeaderInfo = std::make_unique<HeaderSearch>(
755 args: AST->getHeaderSearchOpts(), args&: AST->getSourceManager(),
756 args&: AST->getDiagnostics(), args: AST->getLangOpts(),
757 /*Target=*/args: nullptr);
758 AST->HeaderInfo->initializeModuleCachePath(ContextHash: std::move(ContextHash));
759
760 AST->PP = std::make_shared<Preprocessor>(
761 args&: *AST->PPOpts, args&: AST->getDiagnostics(), args&: *AST->LangOpts,
762 args&: AST->getSourceManager(), args&: *AST->HeaderInfo, args&: AST->ModuleLoader,
763 /*IILookup=*/args: nullptr,
764 /*OwnsHeaderSearch=*/args: false);
765
766 if (ToLoad >= LoadASTOnly)
767 AST->Ctx = llvm::makeIntrusiveRefCnt<ASTContext>(
768 A&: *AST->LangOpts, A&: AST->getSourceManager(), A&: AST->PP->getIdentifierTable(),
769 A&: AST->PP->getSelectorTable(), A&: AST->PP->getBuiltinInfo(),
770 A: AST->getTranslationUnitKind());
771
772 DisableValidationForModuleKind disableValid =
773 DisableValidationForModuleKind::None;
774 if (::getenv(name: "LIBCLANG_DISABLE_PCH_VALIDATION"))
775 disableValid = DisableValidationForModuleKind::All;
776 AST->Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
777 A&: *AST->PP, A&: *AST->ModCache, A: AST->Ctx.get(), A: PCHContainerRdr,
778 A&: *AST->CodeGenOpts, A: ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
779 /*isysroot=*/A: "",
780 /*DisableValidationKind=*/A&: disableValid, A&: AllowASTWithCompilerErrors,
781 /*AllowConfigurationMismatch=*/A: false,
782 /*ValidateSystemInputs=*/A: false,
783 /*ForceValidateUserInputs=*/A: true, A: HSOpts.ValidateASTInputFilesContent);
784
785 // Attach the AST reader to the AST context as an external AST source, so that
786 // declarations will be deserialized from the AST file as needed.
787 // We need the external source to be set up before we read the AST, because
788 // eagerly-deserialized declarations may use it.
789 if (AST->Ctx)
790 AST->Ctx->setExternalSource(AST->Reader);
791
792 AST->Target =
793 TargetInfo::CreateTargetInfo(Diags&: AST->PP->getDiagnostics(), Opts&: *AST->TargetOpts);
794 // Inform the target of the language options.
795 //
796 // FIXME: We shouldn't need to do this, the target should be immutable once
797 // created. This complexity should be lifted elsewhere.
798 AST->Target->adjust(Diags&: AST->PP->getDiagnostics(), Opts&: *AST->LangOpts,
799 /*AuxTarget=*/Aux: nullptr);
800
801 // Initialize the preprocessor.
802 AST->PP->Initialize(Target: *AST->Target);
803
804 AST->PP->setCounterValue(Counter);
805
806 if (AST->Ctx) {
807 // Initialize the ASTContext
808 AST->Ctx->InitBuiltinTypes(Target: *AST->Target);
809
810 // Adjust printing policy based on language options.
811 AST->Ctx->setPrintingPolicy(PrintingPolicy(*AST->LangOpts));
812
813 // We didn't have access to the comment options when the ASTContext was
814 // constructed, so register them now.
815 AST->Ctx->getCommentCommandTraits().registerCommentOptions(
816 CommentOptions: AST->LangOpts->CommentOpts);
817 }
818
819 ModuleFileName ModuleFilename = ModuleFileName::makeExplicit(Name: Filename);
820
821 // The temporary FileManager we used for ASTReader::readASTFileControlBlock()
822 // might have already read stdin, and reading it again will fail. Let's
823 // explicitly forward the buffer.
824 if (Filename == "-")
825 if (auto FE = llvm::expectedToOptional(E: TmpFileMgr.getSTDIN()))
826 if (auto BufRef = TmpFileMgr.getBufferForFile(Entry: *FE)) {
827 auto Buf = llvm::MemoryBuffer::getMemBufferCopy(
828 InputData: (*BufRef)->getBuffer(), BufferName: (*BufRef)->getBufferIdentifier());
829 off_t BufSize = Buf->getBufferSize();
830 AST->ModCache->getInMemoryModuleCache().addBuiltPCM(
831 Filename: "-", Buffer: std::move(Buf), Size: BufSize, /*ModTime=*/0);
832 ModuleFilename = ModuleFileName::makeInMemory(Name: Filename);
833 }
834
835 // Reinstate the provided options that are relevant for reading AST files.
836 AST->HSOpts->ForceCheckCXX20ModulesInputFiles =
837 HSOpts.ForceCheckCXX20ModulesInputFiles;
838
839 switch (AST->Reader->ReadAST(FileName: ModuleFilename, Type: serialization::MK_MainFile,
840 ImportLoc: SourceLocation(), ClientLoadCapabilities: ASTReader::ARR_None)) {
841 case ASTReader::Success:
842 break;
843
844 case ASTReader::Failure:
845 case ASTReader::Missing:
846 case ASTReader::OutOfDate:
847 case ASTReader::VersionMismatch:
848 case ASTReader::ConfigurationMismatch:
849 case ASTReader::HadErrors:
850 AST->getDiagnostics().Report(DiagID: diag::err_fe_unable_to_load_ast_file);
851 return nullptr;
852 }
853
854 // Now that we have successfully loaded the AST file, we can reinstate some
855 // options that the clients expect us to preserve (but would trip AST file
856 // validation, so we couldn't set them earlier).
857 AST->HSOpts->UserEntries = HSOpts.UserEntries;
858 AST->HSOpts->SystemHeaderPrefixes = HSOpts.SystemHeaderPrefixes;
859 AST->HSOpts->VFSOverlayFiles = HSOpts.VFSOverlayFiles;
860 AST->LangOpts->PICLevel = LangOpts.PICLevel;
861 AST->LangOpts->PIE = LangOpts.PIE;
862
863 AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile());
864
865 Module *M = AST->HeaderInfo->lookupModule(ModuleName: AST->getLangOpts().CurrentModule);
866 if (M && AST->getLangOpts().isCompilingModule() && M->isNamedModule())
867 AST->Ctx->setCurrentNamedModule(M);
868
869 // Create an AST consumer, even though it isn't used.
870 if (ToLoad >= LoadASTOnly)
871 AST->Consumer.reset(p: new ASTConsumer);
872
873 // Create a semantic analysis object and tell the AST reader about it.
874 if (ToLoad >= LoadEverything) {
875 AST->TheSema = std::make_unique<Sema>(args&: *AST->PP, args&: *AST->Ctx, args&: *AST->Consumer);
876 AST->TheSema->Initialize();
877 AST->Reader->InitializeSema(S&: *AST->TheSema);
878 }
879
880 // Tell the diagnostic client that we have started a source file.
881 AST->getDiagnostics().getClient()->BeginSourceFile(LangOpts: AST->PP->getLangOpts(),
882 PP: AST->PP.get());
883
884 return AST;
885}
886
887/// Add the given macro to the hash of all top-level entities.
888static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash) {
889 Hash = llvm::djbHash(Buffer: MacroNameTok.getIdentifierInfo()->getName(), H: Hash);
890}
891
892namespace {
893
894/// Preprocessor callback class that updates a hash value with the names
895/// of all macros that have been defined by the translation unit.
896class MacroDefinitionTrackerPPCallbacks : public PPCallbacks {
897 unsigned &Hash;
898
899public:
900 explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) {}
901
902 void MacroDefined(const Token &MacroNameTok,
903 const MacroDirective *MD) override {
904 AddDefinedMacroToHash(MacroNameTok, Hash);
905 }
906};
907
908} // namespace
909
910/// Add the given declaration to the hash of all top-level entities.
911static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
912 if (!D)
913 return;
914
915 DeclContext *DC = D->getDeclContext();
916 if (!DC)
917 return;
918
919 if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit()))
920 return;
921
922 if (const auto *ND = dyn_cast<NamedDecl>(Val: D)) {
923 if (const auto *EnumD = dyn_cast<EnumDecl>(Val: D)) {
924 // For an unscoped enum include the enumerators in the hash since they
925 // enter the top-level namespace.
926 if (!EnumD->isScoped()) {
927 for (const auto *EI : EnumD->enumerators()) {
928 if (EI->getIdentifier())
929 Hash = llvm::djbHash(Buffer: EI->getIdentifier()->getName(), H: Hash);
930 }
931 }
932 }
933
934 if (ND->getIdentifier())
935 Hash = llvm::djbHash(Buffer: ND->getIdentifier()->getName(), H: Hash);
936 else if (DeclarationName Name = ND->getDeclName()) {
937 std::string NameStr = Name.getAsString();
938 Hash = llvm::djbHash(Buffer: NameStr, H: Hash);
939 }
940 return;
941 }
942
943 if (const auto *ImportD = dyn_cast<ImportDecl>(Val: D)) {
944 if (const Module *Mod = ImportD->getImportedModule()) {
945 std::string ModName = Mod->getFullModuleName();
946 Hash = llvm::djbHash(Buffer: ModName, H: Hash);
947 }
948 return;
949 }
950}
951
952namespace {
953
954class TopLevelDeclTrackerConsumer : public ASTConsumer {
955 ASTUnit &Unit;
956 unsigned &Hash;
957
958public:
959 TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash)
960 : Unit(_Unit), Hash(Hash) {
961 Hash = 0;
962 }
963
964 void handleTopLevelDecl(Decl *D) {
965 if (!D)
966 return;
967
968 // FIXME: Currently ObjC method declarations are incorrectly being
969 // reported as top-level declarations, even though their DeclContext
970 // is the containing ObjC @interface/@implementation. This is a
971 // fundamental problem in the parser right now.
972 if (isa<ObjCMethodDecl>(Val: D))
973 return;
974
975 AddTopLevelDeclarationToHash(D, Hash);
976 Unit.addTopLevelDecl(D);
977
978 handleFileLevelDecl(D);
979 }
980
981 void handleFileLevelDecl(Decl *D) {
982 Unit.addFileLevelDecl(D);
983 if (auto *NSD = dyn_cast<NamespaceDecl>(Val: D)) {
984 for (auto *I : NSD->decls())
985 handleFileLevelDecl(D: I);
986 }
987 }
988
989 bool HandleTopLevelDecl(DeclGroupRef D) override {
990 for (auto *TopLevelDecl : D)
991 handleTopLevelDecl(D: TopLevelDecl);
992 return true;
993 }
994
995 // We're not interested in "interesting" decls.
996 void HandleInterestingDecl(DeclGroupRef) override {}
997
998 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
999 for (auto *TopLevelDecl : D)
1000 handleTopLevelDecl(D: TopLevelDecl);
1001 }
1002
1003 ASTMutationListener *GetASTMutationListener() override {
1004 return Unit.getASTMutationListener();
1005 }
1006
1007 ASTDeserializationListener *GetASTDeserializationListener() override {
1008 return Unit.getDeserializationListener();
1009 }
1010};
1011
1012class TopLevelDeclTrackerAction : public ASTFrontendAction {
1013public:
1014 ASTUnit &Unit;
1015
1016 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
1017 StringRef InFile) override {
1018 CI.getPreprocessor().addPPCallbacks(
1019 C: std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1020 args&: Unit.getCurrentTopLevelHashValue()));
1021 return std::make_unique<TopLevelDeclTrackerConsumer>(
1022 args&: Unit, args&: Unit.getCurrentTopLevelHashValue());
1023 }
1024
1025public:
1026 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
1027
1028 bool hasCodeCompletionSupport() const override { return false; }
1029
1030 TranslationUnitKind getTranslationUnitKind() override {
1031 return Unit.getTranslationUnitKind();
1032 }
1033};
1034
1035class ASTUnitPreambleCallbacks : public PreambleCallbacks {
1036public:
1037 unsigned getHash() const { return Hash; }
1038
1039 std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
1040
1041 std::vector<LocalDeclID> takeTopLevelDeclIDs() {
1042 return std::move(TopLevelDeclIDs);
1043 }
1044
1045 void AfterPCHEmitted(ASTWriter &Writer) override {
1046 TopLevelDeclIDs.reserve(n: TopLevelDecls.size());
1047 for (const auto *D : TopLevelDecls) {
1048 // Invalid top-level decls may not have been serialized.
1049 if (D->isInvalidDecl())
1050 continue;
1051 TopLevelDeclIDs.push_back(x: Writer.getDeclID(D));
1052 }
1053 }
1054
1055 void HandleTopLevelDecl(DeclGroupRef DG) override {
1056 for (auto *D : DG) {
1057 // FIXME: Currently ObjC method declarations are incorrectly being
1058 // reported as top-level declarations, even though their DeclContext
1059 // is the containing ObjC @interface/@implementation. This is a
1060 // fundamental problem in the parser right now.
1061 if (isa<ObjCMethodDecl>(Val: D))
1062 continue;
1063 AddTopLevelDeclarationToHash(D, Hash);
1064 TopLevelDecls.push_back(x: D);
1065 }
1066 }
1067
1068 std::unique_ptr<PPCallbacks> createPPCallbacks() override {
1069 return std::make_unique<MacroDefinitionTrackerPPCallbacks>(args&: Hash);
1070 }
1071
1072private:
1073 unsigned Hash = 0;
1074 std::vector<Decl *> TopLevelDecls;
1075 std::vector<LocalDeclID> TopLevelDeclIDs;
1076 llvm::SmallVector<StandaloneDiagnostic, 4> PreambleDiags;
1077};
1078
1079} // namespace
1080
1081static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {
1082 return StoredDiag.getLocation().isValid();
1083}
1084
1085static void
1086checkAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> &StoredDiags) {
1087 // Get rid of stored diagnostics except the ones from the driver which do not
1088 // have a source location.
1089 llvm::erase_if(C&: StoredDiags, P: isNonDriverDiag);
1090}
1091
1092static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &
1093 StoredDiagnostics,
1094 SourceManager &SM) {
1095 // The stored diagnostic has the old source manager in it; update
1096 // the locations to refer into the new source manager. Since we've
1097 // been careful to make sure that the source manager's state
1098 // before and after are identical, so that we can reuse the source
1099 // location itself.
1100 for (auto &SD : StoredDiagnostics) {
1101 if (SD.getLocation().isValid()) {
1102 FullSourceLoc Loc(SD.getLocation(), SM);
1103 SD.setLocation(Loc);
1104 }
1105 }
1106}
1107
1108/// Parse the source file into a translation unit using the given compiler
1109/// invocation, replacing the current translation unit.
1110///
1111/// \returns True if a failure occurred that causes the ASTUnit not to
1112/// contain any translation-unit information, false otherwise.
1113bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1114 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
1115 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
1116 if (!Invocation)
1117 return true;
1118
1119 if (VFS && FileMgr)
1120 assert(VFS == &FileMgr->getVirtualFileSystem() &&
1121 "VFS passed to Parse and VFS in FileMgr are different");
1122
1123 CCInvocation = std::make_shared<CompilerInvocation>(args&: *Invocation);
1124 if (OverrideMainBuffer) {
1125 assert(Preamble &&
1126 "No preamble was built, but OverrideMainBuffer is not null");
1127 Preamble->AddImplicitPreamble(CI&: *CCInvocation, VFS, MainFileBuffer: OverrideMainBuffer.get());
1128 // VFS may have changed...
1129 }
1130
1131 // Create the compiler instance to use for building the AST.
1132 auto Clang = std::make_unique<CompilerInstance>(args&: CCInvocation,
1133 args: std::move(PCHContainerOps));
1134
1135 // Clean up on error, disengage it if the function returns successfully.
1136 llvm::scope_exit CleanOnError([&]() {
1137 // Remove the overridden buffer we used for the preamble.
1138 SavedMainFileBuffer = nullptr;
1139
1140 // Keep the ownership of the data in the ASTUnit because the client may
1141 // want to see the diagnostics.
1142 transferASTDataFromCompilerInstance(CI&: *Clang);
1143 FailedParseDiagnostics.swap(RHS&: StoredDiagnostics);
1144 StoredDiagnostics.clear();
1145 NumStoredDiagnosticsFromDriver = 0;
1146 });
1147
1148 // Ensure that Clang has a FileManager with the right VFS, which may have
1149 // changed above in AddImplicitPreamble. If VFS is nullptr, rely on
1150 // createFileManager to create one.
1151 if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS) {
1152 Clang->setVirtualFileSystem(std::move(VFS));
1153 Clang->setFileManager(FileMgr);
1154 } else {
1155 Clang->setVirtualFileSystem(std::move(VFS));
1156 Clang->createFileManager();
1157 FileMgr = Clang->getFileManagerPtr();
1158 }
1159
1160 // Recover resources if we crash before exiting this method.
1161 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1162 CICleanup(Clang.get());
1163
1164 OriginalSourceFile =
1165 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1166
1167 // Set up diagnostics, capturing any diagnostics that would
1168 // otherwise be dropped.
1169 Clang->setDiagnostics(getDiagnosticsPtr());
1170
1171 // Create the target instance.
1172 if (!Clang->createTarget())
1173 return true;
1174
1175 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1176 "Invocation must have exactly one source file!");
1177 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1178 InputKind::Source &&
1179 "FIXME: AST inputs not yet supported here!");
1180 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1181 Language::LLVM_IR &&
1182 "IR inputs not support here!");
1183
1184 // Configure the various subsystems.
1185 LangOpts =
1186 std::make_unique<LangOptions>(args&: Clang->getInvocation().getLangOpts());
1187 FileSystemOpts = Clang->getFileSystemOpts();
1188
1189 ResetForParse();
1190
1191 SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
1192 A&: getDiagnostics(), A&: *FileMgr, A: +UserFilesAreVolatile);
1193 if (!OverrideMainBuffer) {
1194 checkAndRemoveNonDriverDiags(StoredDiags&: StoredDiagnostics);
1195 TopLevelDeclsInPreamble.clear();
1196 }
1197
1198 // Create the source manager.
1199 Clang->setSourceManager(getSourceManagerPtr());
1200
1201 // If the main file has been overridden due to the use of a preamble,
1202 // make that override happen and introduce the preamble.
1203 if (OverrideMainBuffer) {
1204 // The stored diagnostic has the old source manager in it; update
1205 // the locations to refer into the new source manager. Since we've
1206 // been careful to make sure that the source manager's state
1207 // before and after are identical, so that we can reuse the source
1208 // location itself.
1209 checkAndSanitizeDiags(StoredDiagnostics, SM&: getSourceManager());
1210
1211 // Keep track of the override buffer;
1212 SavedMainFileBuffer = std::move(OverrideMainBuffer);
1213 }
1214
1215 std::unique_ptr<TopLevelDeclTrackerAction> Act(
1216 new TopLevelDeclTrackerAction(*this));
1217
1218 // Recover resources if we crash before exiting this method.
1219 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1220 ActCleanup(Act.get());
1221
1222 if (!Act->BeginSourceFile(CI&: *Clang, Input: Clang->getFrontendOpts().Inputs[0]))
1223 return true;
1224
1225 if (SavedMainFileBuffer) {
1226 StoredDiagnostics.clear();
1227 StoredDiagnostics.reserve(N: PreambleDiagnostics.size());
1228 llvm::transform(Range: std::move(PreambleDiagnostics),
1229 d_first: std::back_inserter(x&: StoredDiagnostics),
1230 F: [&](auto &&StandaloneDiag) {
1231 return translateStandaloneDiag(
1232 getFileManager(), getSourceManager(),
1233 std::move(StandaloneDiag), PreambleSrcLocCache);
1234 });
1235 } else
1236 PreambleSrcLocCache.clear();
1237
1238 if (llvm::Error Err = Act->Execute()) {
1239 consumeError(Err: std::move(Err)); // FIXME this drops errors on the floor.
1240 return true;
1241 }
1242
1243 transferASTDataFromCompilerInstance(CI&: *Clang);
1244
1245 Act->EndSourceFile();
1246
1247 FailedParseDiagnostics.clear();
1248
1249 CleanOnError.release();
1250
1251 return false;
1252}
1253
1254/// Attempt to build or re-use a precompiled preamble when (re-)parsing
1255/// the source file.
1256///
1257/// This routine will compute the preamble of the main source file. If a
1258/// non-trivial preamble is found, it will precompile that preamble into a
1259/// precompiled header so that the precompiled preamble can be used to reduce
1260/// reparsing time. If a precompiled preamble has already been constructed,
1261/// this routine will determine if it is still valid and, if so, avoid
1262/// rebuilding the precompiled preamble.
1263///
1264/// \param AllowRebuild When true (the default), this routine is
1265/// allowed to rebuild the precompiled preamble if it is found to be
1266/// out-of-date.
1267///
1268/// \param MaxLines When non-zero, the maximum number of lines that
1269/// can occur within the preamble.
1270///
1271/// \returns If the precompiled preamble can be used, returns a newly-allocated
1272/// buffer that should be used in place of the main file when doing so.
1273/// Otherwise, returns a NULL pointer.
1274std::unique_ptr<llvm::MemoryBuffer>
1275ASTUnit::getMainBufferWithPrecompiledPreamble(
1276 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1277 CompilerInvocation &PreambleInvocationIn,
1278 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, bool AllowRebuild,
1279 unsigned MaxLines) {
1280 auto MainFilePath =
1281 PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
1282 std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
1283 getBufferForFileHandlingRemapping(Invocation: PreambleInvocationIn, VFS: VFS.get(),
1284 FilePath: MainFilePath, isVolatile: UserFilesAreVolatile);
1285 if (!MainFileBuffer)
1286 return nullptr;
1287
1288 PreambleBounds Bounds = ComputePreambleBounds(
1289 LangOpts: PreambleInvocationIn.getLangOpts(), Buffer: *MainFileBuffer, MaxLines);
1290 if (!Bounds.Size)
1291 return nullptr;
1292
1293 if (Preamble) {
1294 if (Preamble->CanReuse(Invocation: PreambleInvocationIn, MainFileBuffer: *MainFileBuffer, Bounds,
1295 VFS&: *VFS)) {
1296 // Okay! We can re-use the precompiled preamble.
1297
1298 // Set the state of the diagnostic object to mimic its state
1299 // after parsing the preamble.
1300 getDiagnostics().Reset();
1301 ProcessWarningOptions(Diags&: getDiagnostics(),
1302 Opts: PreambleInvocationIn.getDiagnosticOpts(), VFS&: *VFS);
1303 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1304
1305 PreambleRebuildCountdown = 1;
1306 return MainFileBuffer;
1307 } else {
1308 Preamble.reset();
1309 PreambleDiagnostics.clear();
1310 TopLevelDeclsInPreamble.clear();
1311 PreambleSrcLocCache.clear();
1312 PreambleRebuildCountdown = 1;
1313 }
1314 }
1315
1316 // If the preamble rebuild counter > 1, it's because we previously
1317 // failed to build a preamble and we're not yet ready to try
1318 // again. Decrement the counter and return a failure.
1319 if (PreambleRebuildCountdown > 1) {
1320 --PreambleRebuildCountdown;
1321 return nullptr;
1322 }
1323
1324 assert(!Preamble && "No Preamble should be stored at that point");
1325 // If we aren't allowed to rebuild the precompiled preamble, just
1326 // return now.
1327 if (!AllowRebuild)
1328 return nullptr;
1329
1330 ++PreambleCounter;
1331
1332 SmallVector<StandaloneDiagnostic, 4> NewPreambleDiagsStandalone;
1333 SmallVector<StoredDiagnostic, 4> NewPreambleDiags;
1334 ASTUnitPreambleCallbacks Callbacks;
1335 {
1336 std::optional<CaptureDroppedDiagnostics> Capture;
1337 if (CaptureDiagnostics != CaptureDiagsKind::None)
1338 Capture.emplace(args&: CaptureDiagnostics, args&: *Diagnostics, args: &NewPreambleDiags,
1339 args: &NewPreambleDiagsStandalone);
1340
1341 // We did not previously compute a preamble, or it can't be reused anyway.
1342 SimpleTimer PreambleTimer(WantTiming);
1343 PreambleTimer.setOutput("Precompiling preamble");
1344
1345 const bool PreviousSkipFunctionBodies =
1346 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies;
1347 if (SkipFunctionBodies == SkipFunctionBodiesScope::Preamble)
1348 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = true;
1349
1350 llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build(
1351 Invocation: PreambleInvocationIn, MainFileBuffer: MainFileBuffer.get(), Bounds, Diagnostics, VFS,
1352 PCHContainerOps, StoreInMemory: StorePreamblesInMemory, StoragePath: PreambleStoragePath,
1353 Callbacks);
1354
1355 PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies =
1356 PreviousSkipFunctionBodies;
1357
1358 if (NewPreamble) {
1359 Preamble = std::move(*NewPreamble);
1360 PreambleRebuildCountdown = 1;
1361 } else {
1362 switch (static_cast<BuildPreambleError>(NewPreamble.getError().value())) {
1363 case BuildPreambleError::CouldntCreateTempFile:
1364 // Try again next time.
1365 PreambleRebuildCountdown = 1;
1366 return nullptr;
1367 case BuildPreambleError::CouldntCreateTargetInfo:
1368 case BuildPreambleError::BeginSourceFileFailed:
1369 case BuildPreambleError::CouldntEmitPCH:
1370 case BuildPreambleError::BadInputs:
1371 // These erros are more likely to repeat, retry after some period.
1372 PreambleRebuildCountdown = DefaultPreambleRebuildInterval;
1373 return nullptr;
1374 }
1375 llvm_unreachable("unexpected BuildPreambleError");
1376 }
1377 }
1378
1379 assert(Preamble && "Preamble wasn't built");
1380
1381 TopLevelDecls.clear();
1382 TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();
1383 PreambleTopLevelHashValue = Callbacks.getHash();
1384
1385 NumWarningsInPreamble = getDiagnostics().getNumWarnings();
1386
1387 checkAndRemoveNonDriverDiags(StoredDiags&: NewPreambleDiags);
1388 StoredDiagnostics = std::move(NewPreambleDiags);
1389 PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);
1390
1391 // If the hash of top-level entities differs from the hash of the top-level
1392 // entities the last time we rebuilt the preamble, clear out the completion
1393 // cache.
1394 if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {
1395 CompletionCacheTopLevelHashValue = 0;
1396 PreambleTopLevelHashValue = CurrentTopLevelHashValue;
1397 }
1398
1399 return MainFileBuffer;
1400}
1401
1402void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
1403 assert(Preamble && "Should only be called when preamble was built");
1404
1405 std::vector<Decl *> Resolved;
1406 Resolved.reserve(n: TopLevelDeclsInPreamble.size());
1407 // The module file of the preamble.
1408 serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule();
1409 for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {
1410 // Resolve the declaration ID to an actual declaration, possibly
1411 // deserializing the declaration in the process.
1412 if (Decl *D = Reader->GetLocalDecl(F&: MF, LocalID: TopLevelDecl))
1413 Resolved.push_back(x: D);
1414 }
1415 TopLevelDeclsInPreamble.clear();
1416 TopLevelDecls.insert(position: TopLevelDecls.begin(), first: Resolved.begin(), last: Resolved.end());
1417}
1418
1419void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
1420 // Steal the created target, context, and preprocessor if they have been
1421 // created.
1422 LangOpts = std::make_unique<LangOptions>(args&: CI.getInvocation().getLangOpts());
1423 TheSema = CI.takeSema();
1424 Consumer = CI.takeASTConsumer();
1425 if (CI.hasASTContext())
1426 Ctx = CI.getASTContextPtr();
1427 if (CI.hasPreprocessor())
1428 PP = CI.getPreprocessorPtr();
1429 CI.setSourceManager(nullptr);
1430 CI.setFileManager(nullptr);
1431 if (CI.hasTarget())
1432 Target = CI.getTargetPtr();
1433 Reader = CI.getASTReader();
1434 ModCache = CI.getModuleCachePtr();
1435 HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
1436 if (Invocation != CI.getInvocationPtr()) {
1437 // This happens when Parse creates a copy of \c Invocation to modify.
1438 ModifiedInvocation = CI.getInvocationPtr();
1439 }
1440}
1441
1442StringRef ASTUnit::getMainFileName() const {
1443 if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
1444 const FrontendInputFile &Input = Invocation->getFrontendOpts().Inputs[0];
1445 if (Input.isFile())
1446 return Input.getFile();
1447 else
1448 return Input.getBuffer().getBufferIdentifier();
1449 }
1450
1451 if (SourceMgr) {
1452 if (OptionalFileEntryRef FE =
1453 SourceMgr->getFileEntryRefForID(FID: SourceMgr->getMainFileID()))
1454 return FE->getName();
1455 }
1456
1457 return {};
1458}
1459
1460StringRef ASTUnit::getASTFileName() const {
1461 if (!isMainFileAST())
1462 return {};
1463
1464 serialization::ModuleFile &
1465 Mod = Reader->getModuleManager().getPrimaryModule();
1466 return Mod.FileName;
1467}
1468
1469std::unique_ptr<ASTUnit>
1470ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
1471 std::shared_ptr<DiagnosticOptions> DiagOpts,
1472 IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
1473 CaptureDiagsKind CaptureDiagnostics,
1474 bool UserFilesAreVolatile) {
1475 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1476 ConfigureDiags(Diags, AST&: *AST, CaptureDiagnostics);
1477 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1478 createVFSFromCompilerInvocation(CI: *CI, Diags&: *Diags);
1479 AST->DiagOpts = std::move(DiagOpts);
1480 AST->Diagnostics = std::move(Diags);
1481 AST->FileSystemOpts = CI->getFileSystemOpts();
1482 AST->Invocation = std::move(CI);
1483 AST->FileMgr =
1484 llvm::makeIntrusiveRefCnt<FileManager>(A&: AST->FileSystemOpts, A&: VFS);
1485 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1486 AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
1487 A&: AST->getDiagnostics(), A&: *AST->FileMgr, A&: UserFilesAreVolatile);
1488 AST->ModCache = createCrossProcessModuleCache();
1489
1490 return AST;
1491}
1492
1493ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
1494 std::shared_ptr<CompilerInvocation> CI,
1495 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1496 std::shared_ptr<DiagnosticOptions> DiagOpts,
1497 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FrontendAction *Action,
1498 ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
1499 bool OnlyLocalDecls, CaptureDiagsKind CaptureDiagnostics,
1500 unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
1501 bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
1502 assert(CI && "A CompilerInvocation is required");
1503
1504 std::unique_ptr<ASTUnit> OwnAST;
1505 ASTUnit *AST = Unit;
1506 if (!AST) {
1507 // Create the AST unit.
1508 OwnAST =
1509 create(CI, DiagOpts, Diags, CaptureDiagnostics, UserFilesAreVolatile);
1510 AST = OwnAST.get();
1511 if (!AST)
1512 return nullptr;
1513 }
1514
1515 if (!ResourceFilesPath.empty()) {
1516 // Override the resources path.
1517 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1518 }
1519 AST->OnlyLocalDecls = OnlyLocalDecls;
1520 AST->CaptureDiagnostics = CaptureDiagnostics;
1521 if (PrecompilePreambleAfterNParses > 0)
1522 AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1523 AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
1524 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1525 AST->IncludeBriefCommentsInCodeCompletion = false;
1526
1527 // Recover resources if we crash before exiting this method.
1528 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1529 ASTUnitCleanup(OwnAST.get());
1530 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1531 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1532 DiagCleanup(Diags.get());
1533
1534 // We'll manage file buffers ourselves.
1535 CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1536 CI->getFrontendOpts().DisableFree = false;
1537 ProcessWarningOptions(Diags&: AST->getDiagnostics(), Opts: CI->getDiagnosticOpts(),
1538 VFS&: AST->getFileManager().getVirtualFileSystem());
1539
1540 // Create the compiler instance to use for building the AST.
1541 auto Clang = std::make_unique<CompilerInstance>(args: std::move(CI),
1542 args: std::move(PCHContainerOps));
1543
1544 // Recover resources if we crash before exiting this method.
1545 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1546 CICleanup(Clang.get());
1547
1548 AST->OriginalSourceFile =
1549 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1550
1551 // Set up diagnostics, capturing any diagnostics that would
1552 // otherwise be dropped.
1553 Clang->setDiagnostics(AST->getDiagnosticsPtr());
1554
1555 // Create the target instance.
1556 if (!Clang->createTarget())
1557 return nullptr;
1558
1559 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1560 "Invocation must have exactly one source file!");
1561 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1562 InputKind::Source &&
1563 "FIXME: AST inputs not yet supported here!");
1564 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1565 Language::LLVM_IR &&
1566 "IR inputs not support here!");
1567
1568 // Configure the various subsystems.
1569 AST->TheSema.reset();
1570 AST->Ctx = nullptr;
1571 AST->PP = nullptr;
1572 AST->Reader = nullptr;
1573
1574 // Create a file manager object to provide access to and cache the filesystem.
1575 Clang->setVirtualFileSystem(AST->getVirtualFileSystemPtr());
1576 Clang->setFileManager(AST->getFileManagerPtr());
1577
1578 // Create the source manager.
1579 Clang->setSourceManager(AST->getSourceManagerPtr());
1580
1581 FrontendAction *Act = Action;
1582
1583 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1584 if (!Act) {
1585 TrackerAct.reset(p: new TopLevelDeclTrackerAction(*AST));
1586 Act = TrackerAct.get();
1587 }
1588
1589 // Recover resources if we crash before exiting this method.
1590 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1591 ActCleanup(TrackerAct.get());
1592
1593 if (!Act->BeginSourceFile(CI&: *Clang, Input: Clang->getFrontendOpts().Inputs[0])) {
1594 AST->transferASTDataFromCompilerInstance(CI&: *Clang);
1595 if (OwnAST && ErrAST)
1596 ErrAST->swap(u&: OwnAST);
1597
1598 return nullptr;
1599 }
1600
1601 if (Persistent && !TrackerAct) {
1602 Clang->getPreprocessor().addPPCallbacks(
1603 C: std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1604 args&: AST->getCurrentTopLevelHashValue()));
1605 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1606 if (Clang->hasASTConsumer())
1607 Consumers.push_back(x: Clang->takeASTConsumer());
1608 Consumers.push_back(x: std::make_unique<TopLevelDeclTrackerConsumer>(
1609 args&: *AST, args&: AST->getCurrentTopLevelHashValue()));
1610 Clang->setASTConsumer(
1611 std::make_unique<MultiplexConsumer>(args: std::move(Consumers)));
1612 }
1613 if (llvm::Error Err = Act->Execute()) {
1614 consumeError(Err: std::move(Err)); // FIXME this drops errors on the floor.
1615 AST->transferASTDataFromCompilerInstance(CI&: *Clang);
1616 if (OwnAST && ErrAST)
1617 ErrAST->swap(u&: OwnAST);
1618
1619 return nullptr;
1620 }
1621
1622 // Steal the created target, context, and preprocessor.
1623 AST->transferASTDataFromCompilerInstance(CI&: *Clang);
1624
1625 Act->EndSourceFile();
1626
1627 if (OwnAST)
1628 return OwnAST.release();
1629 else
1630 return AST;
1631}
1632
1633bool ASTUnit::LoadFromCompilerInvocation(
1634 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1635 unsigned PrecompilePreambleAfterNParses,
1636 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
1637 if (!Invocation)
1638 return true;
1639
1640 assert(VFS && "VFS is null");
1641
1642 // We'll manage file buffers ourselves.
1643 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1644 Invocation->getFrontendOpts().DisableFree = false;
1645 getDiagnostics().Reset();
1646 ProcessWarningOptions(Diags&: getDiagnostics(), Opts: Invocation->getDiagnosticOpts(),
1647 VFS&: *VFS);
1648
1649 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1650 if (PrecompilePreambleAfterNParses > 0) {
1651 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1652 OverrideMainBuffer =
1653 getMainBufferWithPrecompiledPreamble(PCHContainerOps, PreambleInvocationIn&: *Invocation, VFS);
1654 getDiagnostics().Reset();
1655 ProcessWarningOptions(Diags&: getDiagnostics(), Opts: Invocation->getDiagnosticOpts(),
1656 VFS&: *VFS);
1657 }
1658
1659 SimpleTimer ParsingTimer(WantTiming);
1660 ParsingTimer.setOutput("Parsing " + getMainFileName());
1661
1662 // Recover resources if we crash before exiting this method.
1663 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1664 MemBufferCleanup(OverrideMainBuffer.get());
1665
1666 return Parse(PCHContainerOps: std::move(PCHContainerOps), OverrideMainBuffer: std::move(OverrideMainBuffer), VFS);
1667}
1668
1669std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1670 std::shared_ptr<CompilerInvocation> CI,
1671 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1672 std::shared_ptr<DiagnosticOptions> DiagOpts,
1673 IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
1674 IntrusiveRefCntPtr<FileManager> FileMgr, bool OnlyLocalDecls,
1675 CaptureDiagsKind CaptureDiagnostics,
1676 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1677 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1678 bool UserFilesAreVolatile) {
1679 // Create the AST unit.
1680 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1681 ConfigureDiags(Diags, AST&: *AST, CaptureDiagnostics);
1682 *AST->CodeGenOpts = CI->getCodeGenOpts();
1683 AST->DiagOpts = DiagOpts;
1684 AST->Diagnostics = Diags;
1685 AST->OnlyLocalDecls = OnlyLocalDecls;
1686 AST->CaptureDiagnostics = CaptureDiagnostics;
1687 AST->TUKind = TUKind;
1688 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1689 AST->IncludeBriefCommentsInCodeCompletion
1690 = IncludeBriefCommentsInCodeCompletion;
1691 AST->Invocation = std::move(CI);
1692 AST->FileSystemOpts = FileMgr->getFileSystemOpts();
1693 AST->FileMgr = FileMgr;
1694 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1695
1696 // Recover resources if we crash before exiting this method.
1697 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1698 ASTUnitCleanup(AST.get());
1699 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1700 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1701 DiagCleanup(Diags.get());
1702
1703 if (AST->LoadFromCompilerInvocation(PCHContainerOps: std::move(PCHContainerOps),
1704 PrecompilePreambleAfterNParses,
1705 VFS: AST->FileMgr->getVirtualFileSystemPtr()))
1706 return nullptr;
1707 return AST;
1708}
1709
1710bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1711 ArrayRef<RemappedFile> RemappedFiles,
1712 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
1713 if (!Invocation)
1714 return true;
1715
1716 if (!VFS) {
1717 assert(FileMgr && "FileMgr is null on Reparse call");
1718 VFS = FileMgr->getVirtualFileSystemPtr();
1719 }
1720
1721 clearFileLevelDecls();
1722
1723 SimpleTimer ParsingTimer(WantTiming);
1724 ParsingTimer.setOutput("Reparsing " + getMainFileName());
1725
1726 // Remap files.
1727 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1728 for (const auto &RB : PPOpts.RemappedFileBuffers)
1729 delete RB.second;
1730
1731 Invocation->getPreprocessorOpts().clearRemappedFiles();
1732 for (const auto &RemappedFile : RemappedFiles) {
1733 Invocation->getPreprocessorOpts().addRemappedFile(From: RemappedFile.first,
1734 To: RemappedFile.second);
1735 }
1736
1737 // If we have a preamble file lying around, or if we might try to
1738 // build a precompiled preamble, do so now.
1739 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1740 if (Preamble || PreambleRebuildCountdown > 0)
1741 OverrideMainBuffer =
1742 getMainBufferWithPrecompiledPreamble(PCHContainerOps, PreambleInvocationIn&: *Invocation, VFS);
1743
1744 // Clear out the diagnostics state.
1745 FileMgr.reset();
1746 getDiagnostics().Reset();
1747 ProcessWarningOptions(Diags&: getDiagnostics(), Opts: Invocation->getDiagnosticOpts(),
1748 VFS&: *VFS);
1749 if (OverrideMainBuffer)
1750 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1751
1752 // Parse the sources
1753 bool Result =
1754 Parse(PCHContainerOps: std::move(PCHContainerOps), OverrideMainBuffer: std::move(OverrideMainBuffer), VFS);
1755
1756 // If we're caching global code-completion results, and the top-level
1757 // declarations have changed, clear out the code-completion cache.
1758 if (!Result && ShouldCacheCodeCompletionResults &&
1759 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1760 CacheCodeCompletionResults();
1761
1762 // We now need to clear out the completion info related to this translation
1763 // unit; it'll be recreated if necessary.
1764 CCTUInfo.reset();
1765
1766 return Result;
1767}
1768
1769void ASTUnit::ResetForParse() {
1770 SavedMainFileBuffer.reset();
1771
1772 SourceMgr.reset();
1773 TheSema.reset();
1774 Ctx.reset();
1775 PP.reset();
1776 Reader.reset();
1777
1778 TopLevelDecls.clear();
1779 clearFileLevelDecls();
1780}
1781
1782//----------------------------------------------------------------------------//
1783// Code completion
1784//----------------------------------------------------------------------------//
1785
1786namespace {
1787
1788 /// Code completion consumer that combines the cached code-completion
1789 /// results from an ASTUnit with the code-completion results provided to it,
1790 /// then passes the result on to
1791 class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
1792 uint64_t NormalContexts;
1793 ASTUnit &AST;
1794 CodeCompleteConsumer &Next;
1795
1796 public:
1797 AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
1798 const CodeCompleteOptions &CodeCompleteOpts)
1799 : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {
1800 // Compute the set of contexts in which we will look when we don't have
1801 // any information about the specific context.
1802 NormalContexts
1803 = (1LL << CodeCompletionContext::CCC_TopLevel)
1804 | (1LL << CodeCompletionContext::CCC_ObjCInterface)
1805 | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
1806 | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
1807 | (1LL << CodeCompletionContext::CCC_Statement)
1808 | (1LL << CodeCompletionContext::CCC_Expression)
1809 | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
1810 | (1LL << CodeCompletionContext::CCC_DotMemberAccess)
1811 | (1LL << CodeCompletionContext::CCC_ArrowMemberAccess)
1812 | (1LL << CodeCompletionContext::CCC_ObjCPropertyAccess)
1813 | (1LL << CodeCompletionContext::CCC_ObjCProtocolName)
1814 | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
1815 | (1LL << CodeCompletionContext::CCC_Recovery);
1816
1817 if (AST.getASTContext().getLangOpts().CPlusPlus)
1818 NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
1819 | (1LL << CodeCompletionContext::CCC_UnionTag)
1820 | (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
1821 }
1822
1823 void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
1824 CodeCompletionResult *Results,
1825 unsigned NumResults) override;
1826
1827 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
1828 OverloadCandidate *Candidates,
1829 unsigned NumCandidates,
1830 SourceLocation OpenParLoc,
1831 bool Braced) override {
1832 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
1833 OpenParLoc, Braced);
1834 }
1835
1836 CodeCompletionAllocator &getAllocator() override {
1837 return Next.getAllocator();
1838 }
1839
1840 CodeCompletionTUInfo &getCodeCompletionTUInfo() override {
1841 return Next.getCodeCompletionTUInfo();
1842 }
1843 };
1844
1845} // namespace
1846
1847/// Helper function that computes which global names are hidden by the
1848/// local code-completion results.
1849static void CalculateHiddenNames(const CodeCompletionContext &Context,
1850 CodeCompletionResult *Results,
1851 unsigned NumResults,
1852 ASTContext &Ctx,
1853 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
1854 bool OnlyTagNames = false;
1855 switch (Context.getKind()) {
1856 case CodeCompletionContext::CCC_Recovery:
1857 case CodeCompletionContext::CCC_TopLevel:
1858 case CodeCompletionContext::CCC_ObjCInterface:
1859 case CodeCompletionContext::CCC_ObjCImplementation:
1860 case CodeCompletionContext::CCC_ObjCIvarList:
1861 case CodeCompletionContext::CCC_ClassStructUnion:
1862 case CodeCompletionContext::CCC_Statement:
1863 case CodeCompletionContext::CCC_Expression:
1864 case CodeCompletionContext::CCC_ObjCMessageReceiver:
1865 case CodeCompletionContext::CCC_DotMemberAccess:
1866 case CodeCompletionContext::CCC_ArrowMemberAccess:
1867 case CodeCompletionContext::CCC_ObjCPropertyAccess:
1868 case CodeCompletionContext::CCC_Namespace:
1869 case CodeCompletionContext::CCC_Type:
1870 case CodeCompletionContext::CCC_Symbol:
1871 case CodeCompletionContext::CCC_SymbolOrNewName:
1872 case CodeCompletionContext::CCC_ParenthesizedExpression:
1873 case CodeCompletionContext::CCC_ObjCInterfaceName:
1874 case CodeCompletionContext::CCC_TopLevelOrExpression:
1875 break;
1876
1877 case CodeCompletionContext::CCC_EnumTag:
1878 case CodeCompletionContext::CCC_UnionTag:
1879 case CodeCompletionContext::CCC_ClassOrStructTag:
1880 OnlyTagNames = true;
1881 break;
1882
1883 case CodeCompletionContext::CCC_ObjCProtocolName:
1884 case CodeCompletionContext::CCC_MacroName:
1885 case CodeCompletionContext::CCC_MacroNameUse:
1886 case CodeCompletionContext::CCC_PreprocessorExpression:
1887 case CodeCompletionContext::CCC_PreprocessorDirective:
1888 case CodeCompletionContext::CCC_NaturalLanguage:
1889 case CodeCompletionContext::CCC_SelectorName:
1890 case CodeCompletionContext::CCC_TypeQualifiers:
1891 case CodeCompletionContext::CCC_Other:
1892 case CodeCompletionContext::CCC_OtherWithMacros:
1893 case CodeCompletionContext::CCC_ObjCInstanceMessage:
1894 case CodeCompletionContext::CCC_ObjCClassMessage:
1895 case CodeCompletionContext::CCC_ObjCCategoryName:
1896 case CodeCompletionContext::CCC_IncludedFile:
1897 case CodeCompletionContext::CCC_Attribute:
1898 case CodeCompletionContext::CCC_NewName:
1899 case CodeCompletionContext::CCC_ObjCClassForwardDecl:
1900 // We're looking for nothing, or we're looking for names that cannot
1901 // be hidden.
1902 return;
1903 }
1904
1905 using Result = CodeCompletionResult;
1906 for (unsigned I = 0; I != NumResults; ++I) {
1907 if (Results[I].Kind != Result::RK_Declaration)
1908 continue;
1909
1910 unsigned IDNS
1911 = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
1912
1913 bool Hiding = false;
1914 if (OnlyTagNames)
1915 Hiding = (IDNS & Decl::IDNS_Tag);
1916 else {
1917 unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
1918 Decl::IDNS_Namespace | Decl::IDNS_Ordinary |
1919 Decl::IDNS_NonMemberOperator);
1920 if (Ctx.getLangOpts().CPlusPlus)
1921 HiddenIDNS |= Decl::IDNS_Tag;
1922 Hiding = (IDNS & HiddenIDNS);
1923 }
1924
1925 if (!Hiding)
1926 continue;
1927
1928 DeclarationName Name = Results[I].Declaration->getDeclName();
1929 if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
1930 HiddenNames.insert(key: Identifier->getName());
1931 else
1932 HiddenNames.insert(key: Name.getAsString());
1933 }
1934}
1935
1936void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
1937 CodeCompletionContext Context,
1938 CodeCompletionResult *Results,
1939 unsigned NumResults) {
1940 // Merge the results we were given with the results we cached.
1941 bool AddedResult = false;
1942 uint64_t InContexts =
1943 Context.getKind() == CodeCompletionContext::CCC_Recovery
1944 ? NormalContexts : (1LL << Context.getKind());
1945 // Contains the set of names that are hidden by "local" completion results.
1946 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
1947 using Result = CodeCompletionResult;
1948 SmallVector<Result, 8> AllResults;
1949 for (ASTUnit::cached_completion_iterator
1950 C = AST.cached_completion_begin(),
1951 CEnd = AST.cached_completion_end();
1952 C != CEnd; ++C) {
1953 // If the context we are in matches any of the contexts we are
1954 // interested in, we'll add this result.
1955 if ((C->ShowInContexts & InContexts) == 0)
1956 continue;
1957
1958 // If we haven't added any results previously, do so now.
1959 if (!AddedResult) {
1960 CalculateHiddenNames(Context, Results, NumResults, Ctx&: S.Context,
1961 HiddenNames);
1962 AllResults.insert(I: AllResults.end(), From: Results, To: Results + NumResults);
1963 AddedResult = true;
1964 }
1965
1966 // Determine whether this global completion result is hidden by a local
1967 // completion result. If so, skip it.
1968 if (C->Kind != CXCursor_MacroDefinition &&
1969 HiddenNames.count(Key: C->Completion->getTypedText()))
1970 continue;
1971
1972 // Adjust priority based on similar type classes.
1973 unsigned Priority = C->Priority;
1974 CodeCompletionString *Completion = C->Completion;
1975 if (!Context.getPreferredType().isNull()) {
1976 if (C->Kind == CXCursor_MacroDefinition) {
1977 Priority = getMacroUsagePriority(MacroName: C->Completion->getTypedText(),
1978 LangOpts: S.getLangOpts(),
1979 PreferredTypeIsPointer: Context.getPreferredType()->isAnyPointerType());
1980 } else if (C->Type) {
1981 CanQualType Expected
1982 = S.Context.getCanonicalType(
1983 T: Context.getPreferredType().getUnqualifiedType());
1984 SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(T: Expected);
1985 if (ExpectedSTC == C->TypeClass) {
1986 // We know this type is similar; check for an exact match.
1987 llvm::StringMap<unsigned> &CachedCompletionTypes
1988 = AST.getCachedCompletionTypes();
1989 llvm::StringMap<unsigned>::iterator Pos
1990 = CachedCompletionTypes.find(Key: QualType(Expected).getAsString());
1991 if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
1992 Priority /= CCF_ExactTypeMatch;
1993 else
1994 Priority /= CCF_SimilarTypeMatch;
1995 }
1996 }
1997 }
1998
1999 // Adjust the completion string, if required.
2000 if (C->Kind == CXCursor_MacroDefinition &&
2001 Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
2002 // Create a new code-completion string that just contains the
2003 // macro name, without its arguments.
2004 CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
2005 CCP_CodePattern, C->Availability);
2006 Builder.AddTypedTextChunk(Text: C->Completion->getTypedText());
2007 Priority = CCP_CodePattern;
2008 Completion = Builder.TakeString();
2009 }
2010
2011 AllResults.push_back(Elt: Result(Completion, Priority, C->Kind,
2012 C->Availability));
2013 }
2014
2015 // If we did not add any cached completion results, just forward the
2016 // results we were given to the next consumer.
2017 if (!AddedResult) {
2018 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2019 return;
2020 }
2021
2022 Next.ProcessCodeCompleteResults(S, Context, Results: AllResults.data(),
2023 NumResults: AllResults.size());
2024}
2025
2026void ASTUnit::CodeComplete(
2027 StringRef File, unsigned Line, unsigned Column,
2028 ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
2029 bool IncludeCodePatterns, bool IncludeBriefComments,
2030 CodeCompleteConsumer &Consumer,
2031 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2032 llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diag, LangOptions &LangOpts,
2033 llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr,
2034 llvm::IntrusiveRefCntPtr<FileManager> FileMgr,
2035 SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
2036 SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers,
2037 std::unique_ptr<SyntaxOnlyAction> Act) {
2038 if (!Invocation)
2039 return;
2040
2041 SimpleTimer CompletionTimer(WantTiming);
2042 CompletionTimer.setOutput("Code completion @ " + File + ":" +
2043 Twine(Line) + ":" + Twine(Column));
2044
2045 auto CCInvocation = std::make_shared<CompilerInvocation>(args&: *Invocation);
2046
2047 FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
2048 CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
2049 PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
2050
2051 CodeCompleteOpts.IncludeMacros = IncludeMacros &&
2052 CachedCompletionResults.empty();
2053 CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
2054 CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
2055 CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
2056 CodeCompleteOpts.LoadExternal = Consumer.loadExternal();
2057 CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();
2058
2059 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2060
2061 FrontendOpts.CodeCompletionAt.FileName = std::string(File);
2062 FrontendOpts.CodeCompletionAt.Line = Line;
2063 FrontendOpts.CodeCompletionAt.Column = Column;
2064
2065 // Set the language options appropriately.
2066 LangOpts = CCInvocation->getLangOpts();
2067
2068 // Spell-checking and warnings are wasteful during code-completion.
2069 LangOpts.SpellChecking = false;
2070 CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
2071
2072 auto Clang = std::make_unique<CompilerInstance>(args: std::move(CCInvocation),
2073 args&: PCHContainerOps);
2074
2075 // Recover resources if we crash before exiting this method.
2076 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2077 CICleanup(Clang.get());
2078
2079 auto &Inv = Clang->getInvocation();
2080 OriginalSourceFile =
2081 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2082
2083 // Set up diagnostics, capturing any diagnostics produced.
2084 Clang->setDiagnostics(Diag);
2085 CaptureDroppedDiagnostics Capture(CaptureDiagsKind::All,
2086 Clang->getDiagnostics(),
2087 &StoredDiagnostics, nullptr);
2088 ProcessWarningOptions(Diags&: *Diag, Opts: Inv.getDiagnosticOpts(),
2089 VFS&: FileMgr->getVirtualFileSystem());
2090
2091 // Create the target instance.
2092 if (!Clang->createTarget()) {
2093 return;
2094 }
2095
2096 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2097 "Invocation must have exactly one source file!");
2098 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2099 InputKind::Source &&
2100 "FIXME: AST inputs not yet supported here!");
2101 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2102 Language::LLVM_IR &&
2103 "IR inputs not support here!");
2104
2105 // Use the source and file managers that we were given.
2106 Clang->setVirtualFileSystem(FileMgr->getVirtualFileSystemPtr());
2107 Clang->setFileManager(FileMgr);
2108 Clang->setSourceManager(SourceMgr);
2109
2110 // Remap files.
2111 PreprocessorOpts.clearRemappedFiles();
2112 PreprocessorOpts.RetainRemappedFileBuffers = true;
2113 for (const auto &RemappedFile : RemappedFiles) {
2114 PreprocessorOpts.addRemappedFile(From: RemappedFile.first, To: RemappedFile.second);
2115 OwnedBuffers.push_back(Elt: RemappedFile.second);
2116 }
2117
2118 // Use the code completion consumer we were given, but adding any cached
2119 // code-completion results.
2120 AugmentedCodeCompleteConsumer *AugmentedConsumer
2121 = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
2122 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2123
2124 auto getUniqueID =
2125 [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {
2126 if (auto Status = FileMgr->getVirtualFileSystem().status(Path: Filename))
2127 return Status->getUniqueID();
2128 return std::nullopt;
2129 };
2130
2131 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2132 if (LHS == RHS)
2133 return true;
2134 if (auto LHSID = getUniqueID(LHS))
2135 if (auto RHSID = getUniqueID(RHS))
2136 return *LHSID == *RHSID;
2137 return false;
2138 };
2139
2140 // If we have a precompiled preamble, try to use it. We only allow
2141 // the use of the precompiled preamble if we're if the completion
2142 // point is within the main file, after the end of the precompiled
2143 // preamble.
2144 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2145 if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {
2146 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2147 PCHContainerOps, PreambleInvocationIn&: Inv, VFS: FileMgr->getVirtualFileSystemPtr(), AllowRebuild: false,
2148 MaxLines: Line - 1);
2149 }
2150
2151 // If the main file has been overridden due to the use of a preamble,
2152 // make that override happen and introduce the preamble.
2153 if (OverrideMainBuffer) {
2154 assert(Preamble &&
2155 "No preamble was built, but OverrideMainBuffer is not null");
2156
2157 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
2158 FileMgr->getVirtualFileSystemPtr();
2159 Preamble->AddImplicitPreamble(CI&: Clang->getInvocation(), VFS,
2160 MainFileBuffer: OverrideMainBuffer.get());
2161 // FIXME: there is no way to update VFS if it was changed by
2162 // AddImplicitPreamble as FileMgr is accepted as a parameter by this method.
2163 // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the
2164 // PCH files are always readable.
2165 OwnedBuffers.push_back(Elt: OverrideMainBuffer.release());
2166 } else {
2167 PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
2168 PreprocessorOpts.PrecompiledPreambleBytes.second = false;
2169 }
2170
2171 // Disable the preprocessing record if modules are not enabled.
2172 if (!Clang->getLangOpts().Modules)
2173 PreprocessorOpts.DetailedRecord = false;
2174
2175 if (!Act)
2176 Act.reset(p: new SyntaxOnlyAction);
2177
2178 if (Act->BeginSourceFile(CI&: *Clang, Input: Clang->getFrontendOpts().Inputs[0])) {
2179 if (llvm::Error Err = Act->Execute()) {
2180 consumeError(Err: std::move(Err)); // FIXME this drops errors on the floor.
2181 }
2182 Act->EndSourceFile();
2183 }
2184}
2185
2186bool ASTUnit::Save(StringRef File) {
2187 if (HadModuleLoaderFatalFailure)
2188 return true;
2189
2190 // FIXME: Can we somehow regenerate the stat cache here, or do we need to
2191 // unconditionally create a stat cache when we parse the file?
2192
2193 if (llvm::Error Err = llvm::writeToOutput(
2194 OutputFileName: File, Write: [this](llvm::raw_ostream &Out) {
2195 return serialize(OS&: Out) ? llvm::make_error<llvm::StringError>(
2196 Args: "ASTUnit serialization failed",
2197 Args: llvm::inconvertibleErrorCode())
2198 : llvm::Error::success();
2199 })) {
2200 consumeError(Err: std::move(Err));
2201 return true;
2202 }
2203 return false;
2204}
2205
2206static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl<char> &Buffer,
2207 Sema &S, raw_ostream &OS) {
2208 Writer.WriteAST(Subject: &S, OutputFile: std::string(), WritingModule: nullptr, isysroot: "");
2209
2210 // Write the generated bitstream to "Out".
2211 if (!Buffer.empty())
2212 OS.write(Ptr: Buffer.data(), Size: Buffer.size());
2213
2214 return false;
2215}
2216
2217bool ASTUnit::serialize(raw_ostream &OS) {
2218 if (WriterData)
2219 return serializeUnit(Writer&: WriterData->Writer, Buffer&: WriterData->Buffer, S&: getSema(), OS);
2220
2221 SmallString<128> Buffer;
2222 llvm::BitstreamWriter Stream(Buffer);
2223 std::shared_ptr<ModuleCache> ModCache = createCrossProcessModuleCache();
2224 ASTWriter Writer(Stream, Buffer, *ModCache, *CodeGenOpts, {});
2225 return serializeUnit(Writer, Buffer, S&: getSema(), OS);
2226}
2227
2228void ASTUnit::addFileLevelDecl(Decl *D) {
2229 assert(D);
2230
2231 // We only care about local declarations.
2232 if (D->isFromASTFile())
2233 return;
2234
2235 SourceManager &SM = *SourceMgr;
2236 SourceLocation Loc = D->getLocation();
2237 if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))
2238 return;
2239
2240 // We only keep track of the file-level declarations of each file.
2241 if (!D->getLexicalDeclContext()->isFileContext())
2242 return;
2243
2244 SourceLocation FileLoc = SM.getFileLoc(Loc);
2245 assert(SM.isLocalSourceLocation(FileLoc));
2246 auto [FID, Offset] = SM.getDecomposedLoc(Loc: FileLoc);
2247 if (FID.isInvalid())
2248 return;
2249
2250 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2251 if (!Decls)
2252 Decls = std::make_unique<LocDeclsTy>();
2253
2254 std::pair<unsigned, Decl *> LocDecl(Offset, D);
2255
2256 if (Decls->empty() || Decls->back().first <= Offset) {
2257 Decls->push_back(Elt: LocDecl);
2258 return;
2259 }
2260
2261 LocDeclsTy::iterator I =
2262 llvm::upper_bound(Range&: *Decls, Value&: LocDecl, C: llvm::less_first());
2263
2264 Decls->insert(I, Elt: LocDecl);
2265}
2266
2267void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
2268 SmallVectorImpl<Decl *> &Decls) {
2269 if (File.isInvalid())
2270 return;
2271
2272 if (SourceMgr->isLoadedFileID(FID: File)) {
2273 assert(Ctx->getExternalSource() && "No external source!");
2274 return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
2275 Decls);
2276 }
2277
2278 FileDeclsTy::iterator I = FileDecls.find(Val: File);
2279 if (I == FileDecls.end())
2280 return;
2281
2282 LocDeclsTy &LocDecls = *I->second;
2283 if (LocDecls.empty())
2284 return;
2285
2286 LocDeclsTy::iterator BeginIt =
2287 llvm::partition_point(Range&: LocDecls, P: [=](std::pair<unsigned, Decl *> LD) {
2288 return LD.first < Offset;
2289 });
2290 if (BeginIt != LocDecls.begin())
2291 --BeginIt;
2292
2293 // If we are pointing at a top-level decl inside an objc container, we need
2294 // to backtrack until we find it otherwise we will fail to report that the
2295 // region overlaps with an objc container.
2296 while (BeginIt != LocDecls.begin() &&
2297 BeginIt->second->isTopLevelDeclInObjCContainer())
2298 --BeginIt;
2299
2300 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2301 Range&: LocDecls, Value: std::make_pair(x: Offset + Length, y: (Decl *)nullptr),
2302 C: llvm::less_first());
2303 if (EndIt != LocDecls.end())
2304 ++EndIt;
2305
2306 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2307 Decls.push_back(Elt: DIt->second);
2308}
2309
2310SourceLocation ASTUnit::getLocation(const FileEntry *File,
2311 unsigned Line, unsigned Col) const {
2312 const SourceManager &SM = getSourceManager();
2313 SourceLocation Loc = SM.translateFileLineCol(SourceFile: File, Line, Col);
2314 return SM.getMacroArgExpandedLocation(Loc);
2315}
2316
2317SourceLocation ASTUnit::getLocation(const FileEntry *File,
2318 unsigned Offset) const {
2319 const SourceManager &SM = getSourceManager();
2320 SourceLocation FileLoc = SM.translateFileLineCol(SourceFile: File, Line: 1, Col: 1);
2321 return SM.getMacroArgExpandedLocation(Loc: FileLoc.getLocWithOffset(Offset));
2322}
2323
2324/// If \arg Loc is a loaded location from the preamble, returns
2325/// the corresponding local location of the main file, otherwise it returns
2326/// \arg Loc.
2327SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) const {
2328 FileID PreambleID;
2329 if (SourceMgr)
2330 PreambleID = SourceMgr->getPreambleFileID();
2331
2332 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2333 return Loc;
2334
2335 unsigned Offs;
2336 if (SourceMgr->isInFileID(Loc, FID: PreambleID, RelativeOffset: &Offs) && Offs < Preamble->getBounds().Size) {
2337 SourceLocation FileLoc
2338 = SourceMgr->getLocForStartOfFile(FID: SourceMgr->getMainFileID());
2339 return FileLoc.getLocWithOffset(Offset: Offs);
2340 }
2341
2342 return Loc;
2343}
2344
2345/// If \arg Loc is a local location of the main file but inside the
2346/// preamble chunk, returns the corresponding loaded location from the
2347/// preamble, otherwise it returns \arg Loc.
2348SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) const {
2349 FileID PreambleID;
2350 if (SourceMgr)
2351 PreambleID = SourceMgr->getPreambleFileID();
2352
2353 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2354 return Loc;
2355
2356 unsigned Offs;
2357 if (SourceMgr->isInFileID(Loc, FID: SourceMgr->getMainFileID(), RelativeOffset: &Offs) &&
2358 Offs < Preamble->getBounds().Size) {
2359 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(FID: PreambleID);
2360 return FileLoc.getLocWithOffset(Offset: Offs);
2361 }
2362
2363 return Loc;
2364}
2365
2366bool ASTUnit::isInPreambleFileID(SourceLocation Loc) const {
2367 FileID FID;
2368 if (SourceMgr)
2369 FID = SourceMgr->getPreambleFileID();
2370
2371 if (Loc.isInvalid() || FID.isInvalid())
2372 return false;
2373
2374 return SourceMgr->isInFileID(Loc, FID);
2375}
2376
2377bool ASTUnit::isInMainFileID(SourceLocation Loc) const {
2378 FileID FID;
2379 if (SourceMgr)
2380 FID = SourceMgr->getMainFileID();
2381
2382 if (Loc.isInvalid() || FID.isInvalid())
2383 return false;
2384
2385 return SourceMgr->isInFileID(Loc, FID);
2386}
2387
2388SourceLocation ASTUnit::getEndOfPreambleFileID() const {
2389 FileID FID;
2390 if (SourceMgr)
2391 FID = SourceMgr->getPreambleFileID();
2392
2393 if (FID.isInvalid())
2394 return {};
2395
2396 return SourceMgr->getLocForEndOfFile(FID);
2397}
2398
2399SourceLocation ASTUnit::getStartOfMainFileID() const {
2400 FileID FID;
2401 if (SourceMgr)
2402 FID = SourceMgr->getMainFileID();
2403
2404 if (FID.isInvalid())
2405 return {};
2406
2407 return SourceMgr->getLocForStartOfFile(FID);
2408}
2409
2410llvm::iterator_range<PreprocessingRecord::iterator>
2411ASTUnit::getLocalPreprocessingEntities() const {
2412 if (isMainFileAST()) {
2413 serialization::ModuleFile &
2414 Mod = Reader->getModuleManager().getPrimaryModule();
2415 return Reader->getModulePreprocessedEntities(Mod);
2416 }
2417
2418 if (PreprocessingRecord *PPRec = PP->getPreprocessingRecord())
2419 return llvm::make_range(x: PPRec->local_begin(), y: PPRec->local_end());
2420
2421 return llvm::make_range(x: PreprocessingRecord::iterator(),
2422 y: PreprocessingRecord::iterator());
2423}
2424
2425bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) {
2426 if (isMainFileAST()) {
2427 serialization::ModuleFile &
2428 Mod = Reader->getModuleManager().getPrimaryModule();
2429 for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2430 if (!Fn(context, D))
2431 return false;
2432 }
2433
2434 return true;
2435 }
2436
2437 for (ASTUnit::top_level_iterator TL = top_level_begin(),
2438 TLEnd = top_level_end();
2439 TL != TLEnd; ++TL) {
2440 if (!Fn(context, *TL))
2441 return false;
2442 }
2443
2444 return true;
2445}
2446
2447std::optional<StringRef> ASTUnit::getPCHFile() {
2448 if (!Reader)
2449 return std::nullopt;
2450
2451 serialization::ModuleFile *Mod = nullptr;
2452 Reader->getModuleManager().visit(Visitor: [&Mod](serialization::ModuleFile &M) {
2453 switch (M.Kind) {
2454 case serialization::MK_ImplicitModule:
2455 case serialization::MK_ExplicitModule:
2456 case serialization::MK_PrebuiltModule:
2457 return true; // skip dependencies.
2458 case serialization::MK_PCH:
2459 Mod = &M;
2460 return true; // found it.
2461 case serialization::MK_Preamble:
2462 return false; // look in dependencies.
2463 case serialization::MK_MainFile:
2464 return false; // look in dependencies.
2465 }
2466
2467 return true;
2468 });
2469 if (Mod)
2470 return Mod->FileName;
2471
2472 return std::nullopt;
2473}
2474
2475bool ASTUnit::isModuleFile() const {
2476 return isMainFileAST() && getLangOpts().isCompilingModule();
2477}
2478
2479InputKind ASTUnit::getInputKind() const {
2480 auto &LangOpts = getLangOpts();
2481
2482 Language Lang;
2483 if (LangOpts.OpenCL)
2484 Lang = Language::OpenCL;
2485 else if (LangOpts.CUDA)
2486 Lang = Language::CUDA;
2487 else if (LangOpts.CPlusPlus)
2488 Lang = LangOpts.ObjC ? Language::ObjCXX : Language::CXX;
2489 else
2490 Lang = LangOpts.ObjC ? Language::ObjC : Language::C;
2491
2492 InputKind::Format Fmt = InputKind::Source;
2493 if (LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap)
2494 Fmt = InputKind::ModuleMap;
2495
2496 // We don't know if input was preprocessed. Assume not.
2497 bool PP = false;
2498
2499 return InputKind(Lang, Fmt, PP);
2500}
2501
2502#ifndef NDEBUG
2503ASTUnit::ConcurrencyState::ConcurrencyState() {
2504 Mutex = new std::recursive_mutex;
2505}
2506
2507ASTUnit::ConcurrencyState::~ConcurrencyState() {
2508 delete static_cast<std::recursive_mutex *>(Mutex);
2509}
2510
2511void ASTUnit::ConcurrencyState::start() {
2512 bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();
2513 assert(acquired && "Concurrent access to ASTUnit!");
2514}
2515
2516void ASTUnit::ConcurrencyState::finish() {
2517 static_cast<std::recursive_mutex *>(Mutex)->unlock();
2518}
2519
2520#else // NDEBUG
2521
2522ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }
2523ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2524void ASTUnit::ConcurrencyState::start() {}
2525void ASTUnit::ConcurrencyState::finish() {}
2526
2527#endif // NDEBUG
2528