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