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