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 // libclang and other ASTUnit clients query documentation comments after
1537 // parsing, so keep them in the AST.
1538 CI->getLangOpts().CommentOpts.RetainComments = true;
1539 CI->getFrontendOpts().DisableFree = false;
1540 ProcessWarningOptions(Diags&: AST->getDiagnostics(), Opts: CI->getDiagnosticOpts(),
1541 VFS&: AST->getFileManager().getVirtualFileSystem());
1542
1543 // Create the compiler instance to use for building the AST.
1544 auto Clang = std::make_unique<CompilerInstance>(args: std::move(CI),
1545 args: std::move(PCHContainerOps));
1546
1547 // Recover resources if we crash before exiting this method.
1548 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1549 CICleanup(Clang.get());
1550
1551 AST->OriginalSourceFile =
1552 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1553
1554 // Set up diagnostics, capturing any diagnostics that would
1555 // otherwise be dropped.
1556 Clang->setDiagnostics(AST->getDiagnosticsPtr());
1557
1558 // Create the target instance.
1559 if (!Clang->createTarget())
1560 return nullptr;
1561
1562 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1563 "Invocation must have exactly one source file!");
1564 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1565 InputKind::Source &&
1566 "FIXME: AST inputs not yet supported here!");
1567 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1568 Language::LLVM_IR &&
1569 "IR inputs not support here!");
1570
1571 // Configure the various subsystems.
1572 AST->TheSema.reset();
1573 AST->Ctx = nullptr;
1574 AST->PP = nullptr;
1575 AST->Reader = nullptr;
1576
1577 // Create a file manager object to provide access to and cache the filesystem.
1578 Clang->setVirtualFileSystem(AST->getVirtualFileSystemPtr());
1579 Clang->setFileManager(AST->getFileManagerPtr());
1580
1581 // Create the source manager.
1582 Clang->setSourceManager(AST->getSourceManagerPtr());
1583
1584 FrontendAction *Act = Action;
1585
1586 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1587 if (!Act) {
1588 TrackerAct.reset(p: new TopLevelDeclTrackerAction(*AST));
1589 Act = TrackerAct.get();
1590 }
1591
1592 // Recover resources if we crash before exiting this method.
1593 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1594 ActCleanup(TrackerAct.get());
1595
1596 if (!Act->BeginSourceFile(CI&: *Clang, Input: Clang->getFrontendOpts().Inputs[0])) {
1597 AST->transferASTDataFromCompilerInstance(CI&: *Clang);
1598 if (OwnAST && ErrAST)
1599 ErrAST->swap(u&: OwnAST);
1600
1601 return nullptr;
1602 }
1603
1604 if (Persistent && !TrackerAct) {
1605 Clang->getPreprocessor().addPPCallbacks(
1606 C: std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1607 args&: AST->getCurrentTopLevelHashValue()));
1608 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1609 if (Clang->hasASTConsumer())
1610 Consumers.push_back(x: Clang->takeASTConsumer());
1611 Consumers.push_back(x: std::make_unique<TopLevelDeclTrackerConsumer>(
1612 args&: *AST, args&: AST->getCurrentTopLevelHashValue()));
1613 Clang->setASTConsumer(
1614 std::make_unique<MultiplexConsumer>(args: std::move(Consumers)));
1615 }
1616 if (llvm::Error Err = Act->Execute()) {
1617 consumeError(Err: std::move(Err)); // FIXME this drops errors on the floor.
1618 AST->transferASTDataFromCompilerInstance(CI&: *Clang);
1619 if (OwnAST && ErrAST)
1620 ErrAST->swap(u&: OwnAST);
1621
1622 return nullptr;
1623 }
1624
1625 // Steal the created target, context, and preprocessor.
1626 AST->transferASTDataFromCompilerInstance(CI&: *Clang);
1627
1628 Act->EndSourceFile();
1629
1630 if (OwnAST)
1631 return OwnAST.release();
1632 else
1633 return AST;
1634}
1635
1636bool ASTUnit::LoadFromCompilerInvocation(
1637 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1638 unsigned PrecompilePreambleAfterNParses,
1639 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
1640 if (!Invocation)
1641 return true;
1642
1643 assert(VFS && "VFS is null");
1644
1645 // We'll manage file buffers ourselves.
1646 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true;
1647 // libclang and other ASTUnit clients query documentation comments after
1648 // parsing, so keep them in the AST.
1649 Invocation->getLangOpts().CommentOpts.RetainComments = true;
1650 Invocation->getFrontendOpts().DisableFree = false;
1651 getDiagnostics().Reset();
1652 ProcessWarningOptions(Diags&: getDiagnostics(), Opts: Invocation->getDiagnosticOpts(),
1653 VFS&: *VFS);
1654
1655 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1656 if (PrecompilePreambleAfterNParses > 0) {
1657 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1658 OverrideMainBuffer =
1659 getMainBufferWithPrecompiledPreamble(PCHContainerOps, PreambleInvocationIn&: *Invocation, VFS);
1660 getDiagnostics().Reset();
1661 ProcessWarningOptions(Diags&: getDiagnostics(), Opts: Invocation->getDiagnosticOpts(),
1662 VFS&: *VFS);
1663 }
1664
1665 SimpleTimer ParsingTimer(WantTiming);
1666 ParsingTimer.setOutput("Parsing " + getMainFileName());
1667
1668 // Recover resources if we crash before exiting this method.
1669 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1670 MemBufferCleanup(OverrideMainBuffer.get());
1671
1672 return Parse(PCHContainerOps: std::move(PCHContainerOps), OverrideMainBuffer: std::move(OverrideMainBuffer), VFS);
1673}
1674
1675std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1676 std::shared_ptr<CompilerInvocation> CI,
1677 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1678 std::shared_ptr<DiagnosticOptions> DiagOpts,
1679 IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
1680 IntrusiveRefCntPtr<FileManager> FileMgr, bool OnlyLocalDecls,
1681 CaptureDiagsKind CaptureDiagnostics,
1682 unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
1683 bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
1684 bool UserFilesAreVolatile) {
1685 // Create the AST unit.
1686 std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
1687 ConfigureDiags(Diags, AST&: *AST, CaptureDiagnostics);
1688 *AST->CodeGenOpts = CI->getCodeGenOpts();
1689 AST->DiagOpts = DiagOpts;
1690 AST->Diagnostics = Diags;
1691 AST->OnlyLocalDecls = OnlyLocalDecls;
1692 AST->CaptureDiagnostics = CaptureDiagnostics;
1693 AST->TUKind = TUKind;
1694 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1695 AST->IncludeBriefCommentsInCodeCompletion
1696 = IncludeBriefCommentsInCodeCompletion;
1697 AST->Invocation = std::move(CI);
1698 AST->FileSystemOpts = FileMgr->getFileSystemOpts();
1699 AST->FileMgr = FileMgr;
1700 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1701
1702 // Recover resources if we crash before exiting this method.
1703 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1704 ASTUnitCleanup(AST.get());
1705 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
1706 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1707 DiagCleanup(Diags.get());
1708
1709 if (AST->LoadFromCompilerInvocation(PCHContainerOps: std::move(PCHContainerOps),
1710 PrecompilePreambleAfterNParses,
1711 VFS: AST->FileMgr->getVirtualFileSystemPtr()))
1712 return nullptr;
1713 return AST;
1714}
1715
1716bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1717 ArrayRef<RemappedFile> RemappedFiles,
1718 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
1719 if (!Invocation)
1720 return true;
1721
1722 if (!VFS) {
1723 assert(FileMgr && "FileMgr is null on Reparse call");
1724 VFS = FileMgr->getVirtualFileSystemPtr();
1725 }
1726
1727 clearFileLevelDecls();
1728
1729 SimpleTimer ParsingTimer(WantTiming);
1730 ParsingTimer.setOutput("Reparsing " + getMainFileName());
1731
1732 // Remap files.
1733 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1734 for (const auto &RB : PPOpts.RemappedFileBuffers)
1735 delete RB.second;
1736
1737 Invocation->getPreprocessorOpts().clearRemappedFiles();
1738 for (const auto &RemappedFile : RemappedFiles) {
1739 Invocation->getPreprocessorOpts().addRemappedFile(From: RemappedFile.first,
1740 To: RemappedFile.second);
1741 }
1742
1743 // If we have a preamble file lying around, or if we might try to
1744 // build a precompiled preamble, do so now.
1745 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1746 if (Preamble || PreambleRebuildCountdown > 0)
1747 OverrideMainBuffer =
1748 getMainBufferWithPrecompiledPreamble(PCHContainerOps, PreambleInvocationIn&: *Invocation, VFS);
1749
1750 // Clear out the diagnostics state.
1751 FileMgr.reset();
1752 getDiagnostics().Reset();
1753 ProcessWarningOptions(Diags&: getDiagnostics(), Opts: Invocation->getDiagnosticOpts(),
1754 VFS&: *VFS);
1755 if (OverrideMainBuffer)
1756 getDiagnostics().setNumWarnings(NumWarningsInPreamble);
1757
1758 // Parse the sources
1759 bool Result =
1760 Parse(PCHContainerOps: std::move(PCHContainerOps), OverrideMainBuffer: std::move(OverrideMainBuffer), VFS);
1761
1762 // If we're caching global code-completion results, and the top-level
1763 // declarations have changed, clear out the code-completion cache.
1764 if (!Result && ShouldCacheCodeCompletionResults &&
1765 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1766 CacheCodeCompletionResults();
1767
1768 // We now need to clear out the completion info related to this translation
1769 // unit; it'll be recreated if necessary.
1770 CCTUInfo.reset();
1771
1772 return Result;
1773}
1774
1775void ASTUnit::ResetForParse() {
1776 SavedMainFileBuffer.reset();
1777
1778 SourceMgr.reset();
1779 TheSema.reset();
1780 Ctx.reset();
1781 PP.reset();
1782 Reader.reset();
1783
1784 TopLevelDecls.clear();
1785 clearFileLevelDecls();
1786}
1787
1788//----------------------------------------------------------------------------//
1789// Code completion
1790//----------------------------------------------------------------------------//
1791
1792namespace {
1793
1794 /// Code completion consumer that combines the cached code-completion
1795 /// results from an ASTUnit with the code-completion results provided to it,
1796 /// then passes the result on to
1797 class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
1798 uint64_t NormalContexts;
1799 ASTUnit &AST;
1800 CodeCompleteConsumer &Next;
1801
1802 public:
1803 AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
1804 const CodeCompleteOptions &CodeCompleteOpts)
1805 : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {
1806 // Compute the set of contexts in which we will look when we don't have
1807 // any information about the specific context.
1808 NormalContexts
1809 = (1LL << CodeCompletionContext::CCC_TopLevel)
1810 | (1LL << CodeCompletionContext::CCC_ObjCInterface)
1811 | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
1812 | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
1813 | (1LL << CodeCompletionContext::CCC_Statement)
1814 | (1LL << CodeCompletionContext::CCC_Expression)
1815 | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
1816 | (1LL << CodeCompletionContext::CCC_DotMemberAccess)
1817 | (1LL << CodeCompletionContext::CCC_ArrowMemberAccess)
1818 | (1LL << CodeCompletionContext::CCC_ObjCPropertyAccess)
1819 | (1LL << CodeCompletionContext::CCC_ObjCProtocolName)
1820 | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
1821 | (1LL << CodeCompletionContext::CCC_Recovery);
1822
1823 if (AST.getASTContext().getLangOpts().CPlusPlus)
1824 NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
1825 | (1LL << CodeCompletionContext::CCC_UnionTag)
1826 | (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
1827 }
1828
1829 void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
1830 CodeCompletionResult *Results,
1831 unsigned NumResults) override;
1832
1833 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
1834 OverloadCandidate *Candidates,
1835 unsigned NumCandidates,
1836 SourceLocation OpenParLoc,
1837 bool Braced) override {
1838 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
1839 OpenParLoc, Braced);
1840 }
1841
1842 CodeCompletionAllocator &getAllocator() override {
1843 return Next.getAllocator();
1844 }
1845
1846 CodeCompletionTUInfo &getCodeCompletionTUInfo() override {
1847 return Next.getCodeCompletionTUInfo();
1848 }
1849 };
1850
1851} // namespace
1852
1853/// Helper function that computes which global names are hidden by the
1854/// local code-completion results.
1855static void CalculateHiddenNames(const CodeCompletionContext &Context,
1856 CodeCompletionResult *Results,
1857 unsigned NumResults,
1858 ASTContext &Ctx,
1859 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
1860 bool OnlyTagNames = false;
1861 switch (Context.getKind()) {
1862 case CodeCompletionContext::CCC_Recovery:
1863 case CodeCompletionContext::CCC_TopLevel:
1864 case CodeCompletionContext::CCC_ObjCInterface:
1865 case CodeCompletionContext::CCC_ObjCImplementation:
1866 case CodeCompletionContext::CCC_ObjCIvarList:
1867 case CodeCompletionContext::CCC_ClassStructUnion:
1868 case CodeCompletionContext::CCC_Statement:
1869 case CodeCompletionContext::CCC_Expression:
1870 case CodeCompletionContext::CCC_ObjCMessageReceiver:
1871 case CodeCompletionContext::CCC_DotMemberAccess:
1872 case CodeCompletionContext::CCC_ArrowMemberAccess:
1873 case CodeCompletionContext::CCC_ObjCPropertyAccess:
1874 case CodeCompletionContext::CCC_Namespace:
1875 case CodeCompletionContext::CCC_Type:
1876 case CodeCompletionContext::CCC_Symbol:
1877 case CodeCompletionContext::CCC_SymbolOrNewName:
1878 case CodeCompletionContext::CCC_ParenthesizedExpression:
1879 case CodeCompletionContext::CCC_ObjCInterfaceName:
1880 case CodeCompletionContext::CCC_TopLevelOrExpression:
1881 break;
1882
1883 case CodeCompletionContext::CCC_EnumTag:
1884 case CodeCompletionContext::CCC_UnionTag:
1885 case CodeCompletionContext::CCC_ClassOrStructTag:
1886 OnlyTagNames = true;
1887 break;
1888
1889 case CodeCompletionContext::CCC_ObjCProtocolName:
1890 case CodeCompletionContext::CCC_MacroName:
1891 case CodeCompletionContext::CCC_MacroNameUse:
1892 case CodeCompletionContext::CCC_PreprocessorExpression:
1893 case CodeCompletionContext::CCC_PreprocessorDirective:
1894 case CodeCompletionContext::CCC_NaturalLanguage:
1895 case CodeCompletionContext::CCC_SelectorName:
1896 case CodeCompletionContext::CCC_TypeQualifiers:
1897 case CodeCompletionContext::CCC_Other:
1898 case CodeCompletionContext::CCC_OtherWithMacros:
1899 case CodeCompletionContext::CCC_ObjCInstanceMessage:
1900 case CodeCompletionContext::CCC_ObjCClassMessage:
1901 case CodeCompletionContext::CCC_ObjCCategoryName:
1902 case CodeCompletionContext::CCC_IncludedFile:
1903 case CodeCompletionContext::CCC_Attribute:
1904 case CodeCompletionContext::CCC_NewName:
1905 case CodeCompletionContext::CCC_ObjCClassForwardDecl:
1906 // We're looking for nothing, or we're looking for names that cannot
1907 // be hidden.
1908 return;
1909 }
1910
1911 using Result = CodeCompletionResult;
1912 for (unsigned I = 0; I != NumResults; ++I) {
1913 if (Results[I].Kind != Result::RK_Declaration)
1914 continue;
1915
1916 unsigned IDNS
1917 = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
1918
1919 bool Hiding = false;
1920 if (OnlyTagNames)
1921 Hiding = (IDNS & Decl::IDNS_Tag);
1922 else {
1923 unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
1924 Decl::IDNS_Namespace | Decl::IDNS_Ordinary |
1925 Decl::IDNS_NonMemberOperator);
1926 if (Ctx.getLangOpts().CPlusPlus)
1927 HiddenIDNS |= Decl::IDNS_Tag;
1928 Hiding = (IDNS & HiddenIDNS);
1929 }
1930
1931 if (!Hiding)
1932 continue;
1933
1934 DeclarationName Name = Results[I].Declaration->getDeclName();
1935 if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
1936 HiddenNames.insert(key: Identifier->getName());
1937 else
1938 HiddenNames.insert(key: Name.getAsString());
1939 }
1940}
1941
1942void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
1943 CodeCompletionContext Context,
1944 CodeCompletionResult *Results,
1945 unsigned NumResults) {
1946 // Merge the results we were given with the results we cached.
1947 bool AddedResult = false;
1948 uint64_t InContexts =
1949 Context.getKind() == CodeCompletionContext::CCC_Recovery
1950 ? NormalContexts : (1LL << Context.getKind());
1951 // Contains the set of names that are hidden by "local" completion results.
1952 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
1953 using Result = CodeCompletionResult;
1954 SmallVector<Result, 8> AllResults;
1955 for (ASTUnit::cached_completion_iterator
1956 C = AST.cached_completion_begin(),
1957 CEnd = AST.cached_completion_end();
1958 C != CEnd; ++C) {
1959 // If the context we are in matches any of the contexts we are
1960 // interested in, we'll add this result.
1961 if ((C->ShowInContexts & InContexts) == 0)
1962 continue;
1963
1964 // If we haven't added any results previously, do so now.
1965 if (!AddedResult) {
1966 CalculateHiddenNames(Context, Results, NumResults, Ctx&: S.Context,
1967 HiddenNames);
1968 AllResults.insert(I: AllResults.end(), From: Results, To: Results + NumResults);
1969 AddedResult = true;
1970 }
1971
1972 // Determine whether this global completion result is hidden by a local
1973 // completion result. If so, skip it.
1974 if (C->Kind != CXCursor_MacroDefinition &&
1975 HiddenNames.count(Key: C->Completion->getTypedText()))
1976 continue;
1977
1978 // Adjust priority based on similar type classes.
1979 unsigned Priority = C->Priority;
1980 CodeCompletionString *Completion = C->Completion;
1981 if (!Context.getPreferredType().isNull()) {
1982 if (C->Kind == CXCursor_MacroDefinition) {
1983 Priority = getMacroUsagePriority(MacroName: C->Completion->getTypedText(),
1984 LangOpts: S.getLangOpts(),
1985 PreferredTypeIsPointer: Context.getPreferredType()->isAnyPointerType());
1986 } else if (C->Type) {
1987 CanQualType Expected
1988 = S.Context.getCanonicalType(
1989 T: Context.getPreferredType().getUnqualifiedType());
1990 SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(T: Expected);
1991 if (ExpectedSTC == C->TypeClass) {
1992 // We know this type is similar; check for an exact match.
1993 llvm::StringMap<unsigned> &CachedCompletionTypes
1994 = AST.getCachedCompletionTypes();
1995 llvm::StringMap<unsigned>::iterator Pos
1996 = CachedCompletionTypes.find(Key: QualType(Expected).getAsString());
1997 if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type)
1998 Priority /= CCF_ExactTypeMatch;
1999 else
2000 Priority /= CCF_SimilarTypeMatch;
2001 }
2002 }
2003 }
2004
2005 // Adjust the completion string, if required.
2006 if (C->Kind == CXCursor_MacroDefinition &&
2007 Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
2008 // Create a new code-completion string that just contains the
2009 // macro name, without its arguments.
2010 CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(),
2011 CCP_CodePattern, C->Availability);
2012 Builder.AddTypedTextChunk(Text: C->Completion->getTypedText());
2013 Priority = CCP_CodePattern;
2014 Completion = Builder.TakeString();
2015 }
2016
2017 AllResults.push_back(Elt: Result(Completion, Priority, C->Kind,
2018 C->Availability));
2019 }
2020
2021 // If we did not add any cached completion results, just forward the
2022 // results we were given to the next consumer.
2023 if (!AddedResult) {
2024 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2025 return;
2026 }
2027
2028 Next.ProcessCodeCompleteResults(S, Context, Results: AllResults.data(),
2029 NumResults: AllResults.size());
2030}
2031
2032void ASTUnit::CodeComplete(
2033 StringRef File, unsigned Line, unsigned Column,
2034 ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
2035 bool IncludeCodePatterns, bool IncludeBriefComments,
2036 CodeCompleteConsumer &Consumer,
2037 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2038 llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diag, LangOptions &LangOpts,
2039 llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr,
2040 llvm::IntrusiveRefCntPtr<FileManager> FileMgr,
2041 SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
2042 SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers,
2043 std::unique_ptr<SyntaxOnlyAction> Act) {
2044 if (!Invocation)
2045 return;
2046
2047 SimpleTimer CompletionTimer(WantTiming);
2048 CompletionTimer.setOutput("Code completion @ " + File + ":" +
2049 Twine(Line) + ":" + Twine(Column));
2050
2051 auto CCInvocation = std::make_shared<CompilerInvocation>(args&: *Invocation);
2052
2053 FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts();
2054 CodeCompleteOptions &CodeCompleteOpts = FrontendOpts.CodeCompleteOpts;
2055 PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts();
2056
2057 CodeCompleteOpts.IncludeMacros = IncludeMacros &&
2058 CachedCompletionResults.empty();
2059 CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
2060 CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
2061 CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
2062 CodeCompleteOpts.LoadExternal = Consumer.loadExternal();
2063 CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();
2064
2065 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2066
2067 FrontendOpts.CodeCompletionAt.FileName = std::string(File);
2068 FrontendOpts.CodeCompletionAt.Line = Line;
2069 FrontendOpts.CodeCompletionAt.Column = Column;
2070
2071 // Set the language options appropriately.
2072 LangOpts = CCInvocation->getLangOpts();
2073
2074 // Spell-checking and warnings are wasteful during code-completion.
2075 LangOpts.SpellChecking = false;
2076 CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
2077
2078 auto Clang = std::make_unique<CompilerInstance>(args: std::move(CCInvocation),
2079 args&: PCHContainerOps);
2080
2081 // Recover resources if we crash before exiting this method.
2082 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2083 CICleanup(Clang.get());
2084
2085 auto &Inv = Clang->getInvocation();
2086 OriginalSourceFile =
2087 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2088
2089 // Set up diagnostics, capturing any diagnostics produced.
2090 Clang->setDiagnostics(Diag);
2091 CaptureDroppedDiagnostics Capture(CaptureDiagsKind::All,
2092 Clang->getDiagnostics(),
2093 &StoredDiagnostics, nullptr);
2094 ProcessWarningOptions(Diags&: *Diag, Opts: Inv.getDiagnosticOpts(),
2095 VFS&: FileMgr->getVirtualFileSystem());
2096
2097 // Create the target instance.
2098 if (!Clang->createTarget()) {
2099 return;
2100 }
2101
2102 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2103 "Invocation must have exactly one source file!");
2104 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2105 InputKind::Source &&
2106 "FIXME: AST inputs not yet supported here!");
2107 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2108 Language::LLVM_IR &&
2109 "IR inputs not support here!");
2110
2111 // Use the source and file managers that we were given.
2112 Clang->setVirtualFileSystem(FileMgr->getVirtualFileSystemPtr());
2113 Clang->setFileManager(FileMgr);
2114 Clang->setSourceManager(SourceMgr);
2115
2116 // Remap files.
2117 PreprocessorOpts.clearRemappedFiles();
2118 PreprocessorOpts.RetainRemappedFileBuffers = true;
2119 for (const auto &RemappedFile : RemappedFiles) {
2120 PreprocessorOpts.addRemappedFile(From: RemappedFile.first, To: RemappedFile.second);
2121 OwnedBuffers.push_back(Elt: RemappedFile.second);
2122 }
2123
2124 // Use the code completion consumer we were given, but adding any cached
2125 // code-completion results.
2126 AugmentedCodeCompleteConsumer *AugmentedConsumer
2127 = new AugmentedCodeCompleteConsumer(*this, Consumer, CodeCompleteOpts);
2128 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2129
2130 auto getUniqueID =
2131 [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {
2132 if (auto Status = FileMgr->getVirtualFileSystem().status(Path: Filename))
2133 return Status->getUniqueID();
2134 return std::nullopt;
2135 };
2136
2137 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2138 if (LHS == RHS)
2139 return true;
2140 if (auto LHSID = getUniqueID(LHS))
2141 if (auto RHSID = getUniqueID(RHS))
2142 return *LHSID == *RHSID;
2143 return false;
2144 };
2145
2146 // If we have a precompiled preamble, try to use it. We only allow
2147 // the use of the precompiled preamble if we're if the completion
2148 // point is within the main file, after the end of the precompiled
2149 // preamble.
2150 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2151 if (Preamble && Line > 1 && hasSameUniqueID(File, OriginalSourceFile)) {
2152 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2153 PCHContainerOps, PreambleInvocationIn&: Inv, VFS: FileMgr->getVirtualFileSystemPtr(), AllowRebuild: false,
2154 MaxLines: Line - 1);
2155 }
2156
2157 // If the main file has been overridden due to the use of a preamble,
2158 // make that override happen and introduce the preamble.
2159 if (OverrideMainBuffer) {
2160 assert(Preamble &&
2161 "No preamble was built, but OverrideMainBuffer is not null");
2162
2163 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
2164 FileMgr->getVirtualFileSystemPtr();
2165 Preamble->AddImplicitPreamble(CI&: Clang->getInvocation(), VFS,
2166 MainFileBuffer: OverrideMainBuffer.get());
2167 // FIXME: there is no way to update VFS if it was changed by
2168 // AddImplicitPreamble as FileMgr is accepted as a parameter by this method.
2169 // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the
2170 // PCH files are always readable.
2171 OwnedBuffers.push_back(Elt: OverrideMainBuffer.release());
2172 } else {
2173 PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
2174 PreprocessorOpts.PrecompiledPreambleBytes.second = false;
2175 }
2176
2177 // Disable the preprocessing record if modules are not enabled.
2178 if (!Clang->getLangOpts().Modules)
2179 PreprocessorOpts.DetailedRecord = false;
2180
2181 if (!Act)
2182 Act.reset(p: new SyntaxOnlyAction);
2183
2184 if (Act->BeginSourceFile(CI&: *Clang, Input: Clang->getFrontendOpts().Inputs[0])) {
2185 if (llvm::Error Err = Act->Execute()) {
2186 consumeError(Err: std::move(Err)); // FIXME this drops errors on the floor.
2187 }
2188 Act->EndSourceFile();
2189 }
2190}
2191
2192bool ASTUnit::Save(StringRef File) {
2193 if (HadModuleLoaderFatalFailure)
2194 return true;
2195
2196 // FIXME: Can we somehow regenerate the stat cache here, or do we need to
2197 // unconditionally create a stat cache when we parse the file?
2198
2199 if (llvm::Error Err = llvm::writeToOutput(
2200 OutputFileName: File, Write: [this](llvm::raw_ostream &Out) {
2201 return serialize(OS&: Out) ? llvm::make_error<llvm::StringError>(
2202 Args: "ASTUnit serialization failed",
2203 Args: llvm::inconvertibleErrorCode())
2204 : llvm::Error::success();
2205 })) {
2206 consumeError(Err: std::move(Err));
2207 return true;
2208 }
2209 return false;
2210}
2211
2212static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl<char> &Buffer,
2213 Sema &S, raw_ostream &OS) {
2214 Writer.WriteAST(Subject: &S, OutputFile: std::string(), WritingModule: nullptr, isysroot: "");
2215
2216 // Write the generated bitstream to "Out".
2217 if (!Buffer.empty())
2218 OS.write(Ptr: Buffer.data(), Size: Buffer.size());
2219
2220 return false;
2221}
2222
2223bool ASTUnit::serialize(raw_ostream &OS) {
2224 if (WriterData)
2225 return serializeUnit(Writer&: WriterData->Writer, Buffer&: WriterData->Buffer, S&: getSema(), OS);
2226
2227 SmallString<128> Buffer;
2228 llvm::BitstreamWriter Stream(Buffer);
2229 std::shared_ptr<ModuleCache> ModCache = createCrossProcessModuleCache();
2230 ASTWriter Writer(Stream, Buffer, *ModCache, *CodeGenOpts, {});
2231 return serializeUnit(Writer, Buffer, S&: getSema(), OS);
2232}
2233
2234void ASTUnit::addFileLevelDecl(Decl *D) {
2235 assert(D);
2236
2237 // We only care about local declarations.
2238 if (D->isFromASTFile())
2239 return;
2240
2241 SourceManager &SM = *SourceMgr;
2242 SourceLocation Loc = D->getLocation();
2243 if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc))
2244 return;
2245
2246 // We only keep track of the file-level declarations of each file.
2247 if (!D->getLexicalDeclContext()->isFileContext())
2248 return;
2249
2250 SourceLocation FileLoc = SM.getFileLoc(Loc);
2251 assert(SM.isLocalSourceLocation(FileLoc));
2252 auto [FID, Offset] = SM.getDecomposedLoc(Loc: FileLoc);
2253 if (FID.isInvalid())
2254 return;
2255
2256 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2257 if (!Decls)
2258 Decls = std::make_unique<LocDeclsTy>();
2259
2260 std::pair<unsigned, Decl *> LocDecl(Offset, D);
2261
2262 if (Decls->empty() || Decls->back().first <= Offset) {
2263 Decls->push_back(Elt: LocDecl);
2264 return;
2265 }
2266
2267 LocDeclsTy::iterator I =
2268 llvm::upper_bound(Range&: *Decls, Value&: LocDecl, C: llvm::less_first());
2269
2270 Decls->insert(I, Elt: LocDecl);
2271}
2272
2273void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
2274 SmallVectorImpl<Decl *> &Decls) {
2275 if (File.isInvalid())
2276 return;
2277
2278 if (SourceMgr->isLoadedFileID(FID: File)) {
2279 assert(Ctx->getExternalSource() && "No external source!");
2280 return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length,
2281 Decls);
2282 }
2283
2284 FileDeclsTy::iterator I = FileDecls.find(Val: File);
2285 if (I == FileDecls.end())
2286 return;
2287
2288 LocDeclsTy &LocDecls = *I->second;
2289 if (LocDecls.empty())
2290 return;
2291
2292 LocDeclsTy::iterator BeginIt =
2293 llvm::partition_point(Range&: LocDecls, P: [=](std::pair<unsigned, Decl *> LD) {
2294 return LD.first < Offset;
2295 });
2296 if (BeginIt != LocDecls.begin())
2297 --BeginIt;
2298
2299 // If we are pointing at a top-level decl inside an objc container, we need
2300 // to backtrack until we find it otherwise we will fail to report that the
2301 // region overlaps with an objc container.
2302 while (BeginIt != LocDecls.begin() &&
2303 BeginIt->second->isTopLevelDeclInObjCContainer())
2304 --BeginIt;
2305
2306 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2307 Range&: LocDecls, Value: std::make_pair(x: Offset + Length, y: (Decl *)nullptr),
2308 C: llvm::less_first());
2309 if (EndIt != LocDecls.end())
2310 ++EndIt;
2311
2312 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2313 Decls.push_back(Elt: DIt->second);
2314}
2315
2316SourceLocation ASTUnit::getLocation(const FileEntry *File,
2317 unsigned Line, unsigned Col) const {
2318 const SourceManager &SM = getSourceManager();
2319 SourceLocation Loc = SM.translateFileLineCol(SourceFile: File, Line, Col);
2320 return SM.getMacroArgExpandedLocation(Loc);
2321}
2322
2323SourceLocation ASTUnit::getLocation(const FileEntry *File,
2324 unsigned Offset) const {
2325 const SourceManager &SM = getSourceManager();
2326 SourceLocation FileLoc = SM.translateFileLineCol(SourceFile: File, Line: 1, Col: 1);
2327 return SM.getMacroArgExpandedLocation(Loc: FileLoc.getLocWithOffset(Offset));
2328}
2329
2330/// If \arg Loc is a loaded location from the preamble, returns
2331/// the corresponding local location of the main file, otherwise it returns
2332/// \arg Loc.
2333SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) const {
2334 FileID PreambleID;
2335 if (SourceMgr)
2336 PreambleID = SourceMgr->getPreambleFileID();
2337
2338 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2339 return Loc;
2340
2341 unsigned Offs;
2342 if (SourceMgr->isInFileID(Loc, FID: PreambleID, RelativeOffset: &Offs) && Offs < Preamble->getBounds().Size) {
2343 SourceLocation FileLoc
2344 = SourceMgr->getLocForStartOfFile(FID: SourceMgr->getMainFileID());
2345 return FileLoc.getLocWithOffset(Offset: Offs);
2346 }
2347
2348 return Loc;
2349}
2350
2351/// If \arg Loc is a local location of the main file but inside the
2352/// preamble chunk, returns the corresponding loaded location from the
2353/// preamble, otherwise it returns \arg Loc.
2354SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) const {
2355 FileID PreambleID;
2356 if (SourceMgr)
2357 PreambleID = SourceMgr->getPreambleFileID();
2358
2359 if (Loc.isInvalid() || !Preamble || PreambleID.isInvalid())
2360 return Loc;
2361
2362 unsigned Offs;
2363 if (SourceMgr->isInFileID(Loc, FID: SourceMgr->getMainFileID(), RelativeOffset: &Offs) &&
2364 Offs < Preamble->getBounds().Size) {
2365 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(FID: PreambleID);
2366 return FileLoc.getLocWithOffset(Offset: Offs);
2367 }
2368
2369 return Loc;
2370}
2371
2372bool ASTUnit::isInPreambleFileID(SourceLocation Loc) const {
2373 FileID FID;
2374 if (SourceMgr)
2375 FID = SourceMgr->getPreambleFileID();
2376
2377 if (Loc.isInvalid() || FID.isInvalid())
2378 return false;
2379
2380 return SourceMgr->isInFileID(Loc, FID);
2381}
2382
2383bool ASTUnit::isInMainFileID(SourceLocation Loc) const {
2384 FileID FID;
2385 if (SourceMgr)
2386 FID = SourceMgr->getMainFileID();
2387
2388 if (Loc.isInvalid() || FID.isInvalid())
2389 return false;
2390
2391 return SourceMgr->isInFileID(Loc, FID);
2392}
2393
2394SourceLocation ASTUnit::getEndOfPreambleFileID() const {
2395 FileID FID;
2396 if (SourceMgr)
2397 FID = SourceMgr->getPreambleFileID();
2398
2399 if (FID.isInvalid())
2400 return {};
2401
2402 return SourceMgr->getLocForEndOfFile(FID);
2403}
2404
2405SourceLocation ASTUnit::getStartOfMainFileID() const {
2406 FileID FID;
2407 if (SourceMgr)
2408 FID = SourceMgr->getMainFileID();
2409
2410 if (FID.isInvalid())
2411 return {};
2412
2413 return SourceMgr->getLocForStartOfFile(FID);
2414}
2415
2416llvm::iterator_range<PreprocessingRecord::iterator>
2417ASTUnit::getLocalPreprocessingEntities() const {
2418 if (isMainFileAST()) {
2419 serialization::ModuleFile &
2420 Mod = Reader->getModuleManager().getPrimaryModule();
2421 return Reader->getModulePreprocessedEntities(Mod);
2422 }
2423
2424 if (PreprocessingRecord *PPRec = PP->getPreprocessingRecord())
2425 return llvm::make_range(x: PPRec->local_begin(), y: PPRec->local_end());
2426
2427 return llvm::make_range(x: PreprocessingRecord::iterator(),
2428 y: PreprocessingRecord::iterator());
2429}
2430
2431bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) {
2432 if (isMainFileAST()) {
2433 serialization::ModuleFile &
2434 Mod = Reader->getModuleManager().getPrimaryModule();
2435 for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2436 if (!Fn(context, D))
2437 return false;
2438 }
2439
2440 return true;
2441 }
2442
2443 for (ASTUnit::top_level_iterator TL = top_level_begin(),
2444 TLEnd = top_level_end();
2445 TL != TLEnd; ++TL) {
2446 if (!Fn(context, *TL))
2447 return false;
2448 }
2449
2450 return true;
2451}
2452
2453std::optional<StringRef> ASTUnit::getPCHFile() {
2454 if (!Reader)
2455 return std::nullopt;
2456
2457 serialization::ModuleFile *Mod = nullptr;
2458 Reader->getModuleManager().visit(Visitor: [&Mod](serialization::ModuleFile &M) {
2459 switch (M.Kind) {
2460 case serialization::MK_ImplicitModule:
2461 case serialization::MK_ExplicitModule:
2462 case serialization::MK_PrebuiltModule:
2463 return true; // skip dependencies.
2464 case serialization::MK_PCH:
2465 Mod = &M;
2466 return true; // found it.
2467 case serialization::MK_Preamble:
2468 return false; // look in dependencies.
2469 case serialization::MK_MainFile:
2470 return false; // look in dependencies.
2471 }
2472
2473 return true;
2474 });
2475 if (Mod)
2476 return Mod->FileName;
2477
2478 return std::nullopt;
2479}
2480
2481bool ASTUnit::isModuleFile() const {
2482 return isMainFileAST() && getLangOpts().isCompilingModule();
2483}
2484
2485InputKind ASTUnit::getInputKind() const {
2486 auto &LangOpts = getLangOpts();
2487
2488 Language Lang;
2489 if (LangOpts.OpenCL)
2490 Lang = Language::OpenCL;
2491 else if (LangOpts.CUDA)
2492 Lang = Language::CUDA;
2493 else if (LangOpts.CPlusPlus)
2494 Lang = LangOpts.ObjC ? Language::ObjCXX : Language::CXX;
2495 else
2496 Lang = LangOpts.ObjC ? Language::ObjC : Language::C;
2497
2498 InputKind::Format Fmt = InputKind::Source;
2499 if (LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap)
2500 Fmt = InputKind::ModuleMap;
2501
2502 // We don't know if input was preprocessed. Assume not.
2503 bool PP = false;
2504
2505 return InputKind(Lang, Fmt, PP);
2506}
2507
2508#ifndef NDEBUG
2509ASTUnit::ConcurrencyState::ConcurrencyState() {
2510 Mutex = new std::recursive_mutex;
2511}
2512
2513ASTUnit::ConcurrencyState::~ConcurrencyState() {
2514 delete static_cast<std::recursive_mutex *>(Mutex);
2515}
2516
2517void ASTUnit::ConcurrencyState::start() {
2518 bool acquired = static_cast<std::recursive_mutex *>(Mutex)->try_lock();
2519 assert(acquired && "Concurrent access to ASTUnit!");
2520}
2521
2522void ASTUnit::ConcurrencyState::finish() {
2523 static_cast<std::recursive_mutex *>(Mutex)->unlock();
2524}
2525
2526#else // NDEBUG
2527
2528ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }
2529ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2530void ASTUnit::ConcurrencyState::start() {}
2531void ASTUnit::ConcurrencyState::finish() {}
2532
2533#endif // NDEBUG
2534