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