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