65#include "llvm/ADT/ArrayRef.h"
66#include "llvm/ADT/DenseMap.h"
67#include "llvm/ADT/IntrusiveRefCntPtr.h"
68#include "llvm/ADT/STLExtras.h"
69#include "llvm/ADT/ScopeExit.h"
70#include "llvm/ADT/SmallVector.h"
71#include "llvm/ADT/StringMap.h"
72#include "llvm/ADT/StringRef.h"
73#include "llvm/ADT/StringSet.h"
74#include "llvm/ADT/Twine.h"
75#include "llvm/ADT/iterator_range.h"
76#include "llvm/Bitstream/BitstreamWriter.h"
77#include "llvm/Support/Allocator.h"
78#include "llvm/Support/CrashRecoveryContext.h"
79#include "llvm/Support/DJB.h"
80#include "llvm/Support/ErrorHandling.h"
81#include "llvm/Support/ErrorOr.h"
82#include "llvm/Support/MemoryBuffer.h"
83#include "llvm/Support/SaveAndRestore.h"
84#include "llvm/Support/Timer.h"
85#include "llvm/Support/VirtualFileSystem.h"
86#include "llvm/Support/raw_ostream.h"
101using namespace clang;
103using llvm::TimeRecord;
113 explicit SimpleTimer(
bool WantTiming) : WantTiming(WantTiming) {
115 Start = TimeRecord::getCurrentTime();
120 TimeRecord Elapsed = TimeRecord::getCurrentTime();
122 llvm::errs() << Output <<
':';
123 Elapsed.print(Elapsed, llvm::errs());
124 llvm::errs() <<
'\n';
128 void setOutput(
const Twine &Output) {
130 this->Output = Output.str();
137static std::unique_ptr<T>
valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val) {
140 return std::move(*Val);
147 Output = std::move(*Val);
153static std::unique_ptr<llvm::MemoryBuffer>
155 llvm::vfs::FileSystem *VFS,
156 StringRef FilePath,
bool isVolatile) {
162 llvm::MemoryBuffer *Buffer =
nullptr;
163 std::unique_ptr<llvm::MemoryBuffer> BufferOwner;
164 auto FileStatus = VFS->status(FilePath);
166 llvm::sys::fs::UniqueID MainFileID = FileStatus->getUniqueID();
169 for (
const auto &RF : PreprocessorOpts.RemappedFiles) {
170 std::string MPath(RF.first);
171 auto MPathStatus = VFS->status(MPath);
173 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
174 if (MainFileID == MID) {
176 BufferOwner =
valueOrNull(VFS->getBufferForFile(RF.second, -1,
true, isVolatile));
185 for (
const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
186 std::string MPath(RB.first);
187 auto MPathStatus = VFS->status(MPath);
189 llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
190 if (MainFileID == MID) {
193 Buffer =
const_cast<llvm::MemoryBuffer *
>(RB.second);
200 if (!Buffer && !BufferOwner) {
201 BufferOwner =
valueOrNull(VFS->getBufferForFile(FilePath, -1,
true, isVolatile));
210 return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);
222void ASTUnit::clearFileLevelDecls() {
237ASTUnit::ASTUnit(
bool _MainFileIsAST)
239 MainFileIsAST(_MainFileIsAST), WantTiming(getenv(
"LIBCLANG_TIMING")),
240 ShouldCacheCodeCompletionResults(
false),
241 IncludeBriefCommentsInCodeCompletion(
false), UserFilesAreVolatile(
false),
242 UnsafeToFree(
false) {
243 if (getenv(
"LIBCLANG_OBJTRACKING"))
253 clearFileLevelDecls();
259 if (Invocation && OwnsRemappedFileBuffers) {
261 for (
const auto &RB : PPOpts.RemappedFileBuffers)
265 ClearCachedCompletionResults();
267 if (getenv(
"LIBCLANG_OBJTRACKING"))
272 this->PP = std::move(PP);
277 "Bad context for source file");
285 bool &IsNestedNameSpecifier) {
286 IsNestedNameSpecifier =
false;
293 uint64_t Contexts = 0;
307 if (LangOpts.CPlusPlus)
316 if (
const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
318 if (ID->getDefinition())
329 if (LangOpts.CPlusPlus11)
330 IsNestedNameSpecifier =
true;
331 }
else if (
const auto *
Record = dyn_cast<RecordDecl>(ND)) {
337 if (LangOpts.CPlusPlus)
338 IsNestedNameSpecifier =
true;
340 IsNestedNameSpecifier =
true;
355 IsNestedNameSpecifier =
true;
361void ASTUnit::CacheCodeCompletionResults() {
365 SimpleTimer Timer(WantTiming);
366 Timer.setOutput(
"Cache global code completions for " +
getMainFileName());
369 ClearCachedCompletionResults();
372 using Result = CodeCompletionResult;
373 SmallVector<Result, 8> Results;
374 CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
375 CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator);
376 TheSema->CodeCompletion().GatherGlobalCodeCompletions(
377 *CachedCompletionAllocator, CCTUInfo, Results);
380 llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
383 for (
auto &R : Results) {
385 case Result::RK_Declaration: {
386 bool IsNestedNameSpecifier =
false;
388 CachedResult.
Completion = R.CreateCodeCompletionString(
389 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
390 IncludeBriefCommentsInCodeCompletion);
392 R.Declaration, Ctx->getLangOpts(), IsNestedNameSpecifier);
393 CachedResult.Priority = R.Priority;
394 CachedResult.Kind = R.CursorKind;
395 CachedResult.Availability = R.Availability;
402 CachedResult.Type = 0;
411 unsigned &TypeValue = CompletionTypes[CanUsageType];
412 if (TypeValue == 0) {
413 TypeValue = CompletionTypes.size();
414 CachedCompletionTypes[QualType(CanUsageType).getAsString()]
418 CachedResult.Type = TypeValue;
421 CachedCompletionResults.push_back(CachedResult);
424 if (TheSema->Context.getLangOpts().CPlusPlus && IsNestedNameSpecifier &&
425 !R.StartsNestedNameSpecifier) {
445 if (uint64_t RemainingContexts
446 = NNSContexts & ~CachedResult.ShowInContexts) {
450 R.StartsNestedNameSpecifier =
true;
451 CachedResult.Completion = R.CreateCodeCompletionString(
452 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
453 IncludeBriefCommentsInCodeCompletion);
454 CachedResult.ShowInContexts = RemainingContexts;
457 CachedResult.Type = 0;
458 CachedCompletionResults.push_back(CachedResult);
464 case Result::RK_Keyword:
465 case Result::RK_Pattern:
470 case Result::RK_Macro: {
472 CachedResult.
Completion = R.CreateCodeCompletionString(
473 *TheSema, CCContext, *CachedCompletionAllocator, CCTUInfo,
474 IncludeBriefCommentsInCodeCompletion);
475 CachedResult.ShowInContexts
489 CachedResult.Priority = R.Priority;
490 CachedResult.Kind = R.CursorKind;
491 CachedResult.Availability = R.Availability;
493 CachedResult.Type = 0;
494 CachedCompletionResults.push_back(CachedResult);
501 CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
504void ASTUnit::ClearCachedCompletionResults() {
505 CachedCompletionResults.clear();
506 CachedCompletionTypes.clear();
507 CachedCompletionAllocator =
nullptr;
515 HeaderSearchOptions &HSOpts;
516 std::string &SpecificModuleCachePath;
517 PreprocessorOptions &PPOpts;
518 LangOptions &LangOpts;
519 CodeGenOptions &CodeGenOpts;
520 TargetOptions &TargetOpts;
524 ASTInfoCollector(HeaderSearchOptions &HSOpts,
525 std::string &SpecificModuleCachePath,
526 PreprocessorOptions &PPOpts, LangOptions &LangOpts,
527 CodeGenOptions &CodeGenOpts, TargetOptions &TargetOpts,
529 : HSOpts(HSOpts), SpecificModuleCachePath(SpecificModuleCachePath),
530 PPOpts(PPOpts), LangOpts(LangOpts), CodeGenOpts(CodeGenOpts),
531 TargetOpts(TargetOpts), Counter(Counter) {}
533 bool ReadLanguageOptions(
const LangOptions &NewLangOpts,
534 StringRef ModuleFilename,
bool Complain,
535 bool AllowCompatibleDifferences)
override {
536 LangOpts = NewLangOpts;
540 bool ReadCodeGenOptions(
const CodeGenOptions &NewCodeGenOpts,
541 StringRef ModuleFilename,
bool Complain,
542 bool AllowCompatibleDifferences)
override {
543 CodeGenOpts = NewCodeGenOpts;
547 bool ReadHeaderSearchOptions(
const HeaderSearchOptions &NewHSOpts,
548 StringRef ModuleFilename,
549 StringRef NewSpecificModuleCachePath,
550 bool Complain)
override {
552 SpecificModuleCachePath = NewSpecificModuleCachePath;
556 bool ReadHeaderSearchPaths(
const HeaderSearchOptions &NewHSOpts,
557 bool Complain)
override {
564 bool ReadPreprocessorOptions(
const PreprocessorOptions &NewPPOpts,
565 StringRef ModuleFilename,
bool ReadMacros,
567 std::string &SuggestedPredefines)
override {
572 bool ReadTargetOptions(
const TargetOptions &NewTargetOpts,
573 StringRef ModuleFilename,
bool Complain,
574 bool AllowCompatibleDifferences)
override {
575 TargetOpts = NewTargetOpts;
579 void ReadCounter(
const serialization::ModuleFile &M,
580 unsigned NewCounter)
override {
581 Counter = NewCounter;
587 SmallVectorImpl<StoredDiagnostic> *StoredDiags;
588 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags;
589 bool CaptureNonErrorsFromIncludes =
true;
590 const LangOptions *LangOpts =
nullptr;
591 SourceManager *SourceMgr =
nullptr;
594 FilterAndStoreDiagnosticConsumer(
595 SmallVectorImpl<StoredDiagnostic> *StoredDiags,
596 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags,
597 bool CaptureNonErrorsFromIncludes)
598 : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
599 CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
600 assert((StoredDiags || StandaloneDiags) &&
601 "No output collections were passed to StoredDiagnosticConsumer.");
604 void BeginSourceFile(
const LangOptions &LangOpts,
605 const Preprocessor *PP =
nullptr)
override {
606 this->LangOpts = &LangOpts;
608 SourceMgr = &PP->getSourceManager();
612 const Diagnostic &Info)
override;
617class CaptureDroppedDiagnostics {
618 DiagnosticsEngine &Diags;
619 FilterAndStoreDiagnosticConsumer Client;
620 DiagnosticConsumer *PreviousClient =
nullptr;
621 std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
624 CaptureDroppedDiagnostics(
626 SmallVectorImpl<StoredDiagnostic> *StoredDiags,
627 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags)
629 Client(StoredDiags, StandaloneDiags,
630 CaptureDiagnostics !=
632 if (CaptureDiagnostics != CaptureDiagsKind::None ||
634 OwningPreviousClient = Diags.takeClient();
635 PreviousClient = Diags.getClient();
636 Diags.setClient(&Client, false);
640 ~CaptureDroppedDiagnostics() {
642 Diags.
setClient(PreviousClient, !!OwningPreviousClient.release());
660void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
676 StoredDiags->emplace_back(Level, Info);
677 ResultDiag = &StoredDiags->back();
680 if (StandaloneDiags) {
681 std::optional<StoredDiagnostic> StoredDiag;
683 StoredDiag.emplace(Level, Info);
684 ResultDiag = &*StoredDiag;
686 StandaloneDiags->push_back(
698 return &WriterData->Writer;
704 return &WriterData->Writer;
708std::unique_ptr<llvm::MemoryBuffer>
711 auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);
713 return std::move(*Buffer);
715 *ErrorStr = Buffer.getError().message();
723 assert(Diags.get() &&
"no DiagnosticsEngine was provided");
725 Diags->setClient(
new FilterAndStoreDiagnosticConsumer(
726 &AST.StoredDiagnostics,
nullptr,
733 std::shared_ptr<DiagnosticOptions> DiagOpts,
736 const LangOptions *ProvidedLangOpts,
bool OnlyLocalDecls,
738 bool UserFilesAreVolatile) {
739 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
true));
742 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
743 ASTUnitCleanup(AST.get());
745 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
746 DiagCleanup(Diags.get());
748 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
750 std::unique_ptr<LangOptions> LocalLangOpts;
752 if (ProvidedLangOpts)
753 return *ProvidedLangOpts;
754 LocalLangOpts = std::make_unique<LangOptions>();
755 return *LocalLangOpts;
758 AST->LangOpts = std::make_unique<LangOptions>(LangOpts);
759 AST->OnlyLocalDecls = OnlyLocalDecls;
760 AST->CaptureDiagnostics = CaptureDiagnostics;
761 AST->DiagOpts = DiagOpts;
762 AST->Diagnostics = Diags;
763 AST->UserFilesAreVolatile = UserFilesAreVolatile;
764 AST->HSOpts = std::make_unique<HeaderSearchOptions>(HSOpts);
765 AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.
getFormats().front());
766 AST->PPOpts = std::make_shared<PreprocessorOptions>();
767 AST->CodeGenOpts = std::make_unique<CodeGenOptions>();
768 AST->TargetOpts = std::make_shared<TargetOptions>();
773 std::string SpecificModuleCachePath;
774 unsigned Counter = 0;
778 ASTInfoCollector Collector(*AST->HSOpts, SpecificModuleCachePath,
779 *AST->PPOpts, *AST->LangOpts, *AST->CodeGenOpts,
780 *AST->TargetOpts, Counter);
782 Filename, TmpFileMgr, *AST->ModCache, PCHContainerRdr,
785 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
790 *AST->Diagnostics, std::move(VFS));
792 AST->FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOpts, VFS);
794 AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
795 AST->getDiagnostics(), AST->getFileManager(), UserFilesAreVolatile);
797 AST->HSOpts->PrebuiltModuleFiles = HSOpts.PrebuiltModuleFiles;
798 AST->HSOpts->PrebuiltModulePaths = HSOpts.PrebuiltModulePaths;
799 AST->HeaderInfo = std::make_unique<HeaderSearch>(
800 AST->getHeaderSearchOpts(), AST->getSourceManager(),
801 AST->getDiagnostics(), AST->getLangOpts(),
803 AST->HeaderInfo->setModuleCachePath(SpecificModuleCachePath);
805 AST->PP = std::make_shared<Preprocessor>(
806 *AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
807 AST->getSourceManager(), *AST->HeaderInfo, AST->ModuleLoader,
812 AST->Ctx = llvm::makeIntrusiveRefCnt<ASTContext>(
813 *AST->LangOpts, AST->getSourceManager(), AST->PP->getIdentifierTable(),
814 AST->PP->getSelectorTable(), AST->PP->getBuiltinInfo(),
815 AST->getTranslationUnitKind());
819 if (::getenv(
"LIBCLANG_DISABLE_PCH_VALIDATION"))
821 AST->Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
822 *AST->PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr,
823 *AST->CodeGenOpts,
ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
825 disableValid, AllowASTWithCompilerErrors);
832 AST->Ctx->setExternalSource(AST->Reader);
840 AST->Target->adjust(AST->PP->getDiagnostics(), *AST->LangOpts,
844 AST->PP->Initialize(*AST->Target);
846 AST->PP->setCounterValue(Counter);
850 AST->Ctx->InitBuiltinTypes(*AST->Target);
857 AST->Ctx->getCommentCommandTraits().registerCommentOptions(
858 AST->LangOpts->CommentOpts);
865 if (
auto FE = llvm::expectedToOptional(TmpFileMgr.
getSTDIN()))
867 auto Buf = llvm::MemoryBuffer::getMemBufferCopy(
868 (*BufRef)->getBuffer(), (*BufRef)->getBufferIdentifier());
869 AST->Reader->getModuleManager().addInMemoryBuffer(
"-", std::move(Buf));
873 AST->HSOpts->ForceCheckCXX20ModulesInputFiles =
874 HSOpts.ForceCheckCXX20ModulesInputFiles;
887 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
894 AST->HSOpts->UserEntries = HSOpts.UserEntries;
895 AST->HSOpts->SystemHeaderPrefixes = HSOpts.SystemHeaderPrefixes;
896 AST->HSOpts->VFSOverlayFiles = HSOpts.VFSOverlayFiles;
897 AST->LangOpts->PICLevel = LangOpts.PICLevel;
898 AST->LangOpts->PIE = LangOpts.PIE;
900 AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile());
902 Module *M = AST->HeaderInfo->lookupModule(AST->getLangOpts().CurrentModule);
903 if (M && AST->getLangOpts().isCompilingModule() && M->
isNamedModule())
904 AST->Ctx->setCurrentNamedModule(M);
912 AST->TheSema = std::make_unique<Sema>(*AST->PP, *AST->Ctx, *AST->Consumer);
913 AST->TheSema->Initialize();
914 AST->Reader->InitializeSema(*AST->TheSema);
918 AST->getDiagnostics().getClient()->BeginSourceFile(AST->PP->getLangOpts(),
933class MacroDefinitionTrackerPPCallbacks :
public PPCallbacks {
937 explicit MacroDefinitionTrackerPPCallbacks(
unsigned &Hash) : Hash(Hash) {}
939 void MacroDefined(
const Token &MacroNameTok,
940 const MacroDirective *MD)
override {
959 if (
const auto *ND = dyn_cast<NamedDecl>(D)) {
960 if (
const auto *EnumD = dyn_cast<EnumDecl>(D)) {
963 if (!EnumD->isScoped()) {
964 for (
const auto *EI : EnumD->enumerators()) {
965 if (EI->getIdentifier())
966 Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);
971 if (ND->getIdentifier())
972 Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);
974 std::string NameStr = Name.getAsString();
975 Hash = llvm::djbHash(NameStr, Hash);
980 if (
const auto *ImportD = dyn_cast<ImportDecl>(D)) {
981 if (
const Module *Mod = ImportD->getImportedModule()) {
982 std::string ModName = Mod->getFullModuleName();
983 Hash = llvm::djbHash(ModName, Hash);
991class TopLevelDeclTrackerConsumer :
public ASTConsumer {
996 TopLevelDeclTrackerConsumer(ASTUnit &_Unit,
unsigned &Hash)
997 : Unit(_Unit), Hash(Hash) {
1001 void handleTopLevelDecl(Decl *D) {
1015 handleFileLevelDecl(D);
1018 void handleFileLevelDecl(Decl *D) {
1020 if (
auto *NSD = dyn_cast<NamespaceDecl>(D)) {
1021 for (
auto *I : NSD->decls())
1022 handleFileLevelDecl(I);
1026 bool HandleTopLevelDecl(DeclGroupRef D)
override {
1027 for (
auto *TopLevelDecl : D)
1028 handleTopLevelDecl(TopLevelDecl);
1033 void HandleInterestingDecl(DeclGroupRef)
override {}
1035 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D)
override {
1036 for (
auto *TopLevelDecl : D)
1037 handleTopLevelDecl(TopLevelDecl);
1040 ASTMutationListener *GetASTMutationListener()
override {
1044 ASTDeserializationListener *GetASTDeserializationListener()
override {
1053 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
1054 StringRef InFile)
override {
1056 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1058 return std::make_unique<TopLevelDeclTrackerConsumer>(
1063 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
1065 bool hasCodeCompletionSupport()
const override {
return false; }
1074 unsigned getHash()
const {
return Hash; }
1076 std::vector<Decl *> takeTopLevelDecls() {
return std::move(TopLevelDecls); }
1078 std::vector<LocalDeclID> takeTopLevelDeclIDs() {
1079 return std::move(TopLevelDeclIDs);
1082 void AfterPCHEmitted(ASTWriter &Writer)
override {
1083 TopLevelDeclIDs.reserve(TopLevelDecls.size());
1084 for (
const auto *D : TopLevelDecls) {
1086 if (D->isInvalidDecl())
1088 TopLevelDeclIDs.push_back(Writer.
getDeclID(D));
1092 void HandleTopLevelDecl(DeclGroupRef DG)
override {
1093 for (
auto *D : DG) {
1101 TopLevelDecls.push_back(D);
1105 std::unique_ptr<PPCallbacks> createPPCallbacks()
override {
1106 return std::make_unique<MacroDefinitionTrackerPPCallbacks>(Hash);
1111 std::vector<Decl *> TopLevelDecls;
1112 std::vector<LocalDeclID> TopLevelDeclIDs;
1113 llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags;
1137 for (
auto &SD : StoredDiagnostics) {
1138 if (SD.getLocation().isValid()) {
1140 SD.setLocation(Loc);
1150bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1151 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
1157 assert(VFS == &FileMgr->getVirtualFileSystem() &&
1158 "VFS passed to Parse and VFS in FileMgr are different");
1160 CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
1161 if (OverrideMainBuffer) {
1163 "No preamble was built, but OverrideMainBuffer is not null");
1164 Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());
1169 auto Clang = std::make_unique<CompilerInstance>(CCInvocation,
1170 std::move(PCHContainerOps));
1173 auto CleanOnError = llvm::make_scope_exit([&]() {
1175 SavedMainFileBuffer =
nullptr;
1179 transferASTDataFromCompilerInstance(*Clang);
1180 FailedParseDiagnostics.swap(StoredDiagnostics);
1181 StoredDiagnostics.clear();
1182 NumStoredDiagnosticsFromDriver = 0;
1188 if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS) {
1189 Clang->setVirtualFileSystem(std::move(VFS));
1190 Clang->setFileManager(FileMgr);
1192 Clang->setVirtualFileSystem(std::move(VFS));
1193 Clang->createFileManager();
1194 FileMgr = Clang->getFileManagerPtr();
1198 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1199 CICleanup(Clang.get());
1201 OriginalSourceFile =
1202 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1209 if (!Clang->createTarget())
1212 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1213 "Invocation must have exactly one source file!");
1214 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1216 "FIXME: AST inputs not yet supported here!");
1217 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1219 "IR inputs not support here!");
1223 std::make_unique<LangOptions>(Clang->getInvocation().getLangOpts());
1224 FileSystemOpts = Clang->getFileSystemOpts();
1228 SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
1230 if (!OverrideMainBuffer) {
1232 TopLevelDeclsInPreamble.clear();
1240 if (OverrideMainBuffer) {
1249 SavedMainFileBuffer = std::move(OverrideMainBuffer);
1252 std::unique_ptr<TopLevelDeclTrackerAction> Act(
1253 new TopLevelDeclTrackerAction(*
this));
1256 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1257 ActCleanup(Act.get());
1259 if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
1262 if (SavedMainFileBuffer)
1264 PreambleDiagnostics, StoredDiagnostics);
1266 PreambleSrcLocCache.clear();
1268 if (llvm::Error Err = Act->Execute()) {
1269 consumeError(std::move(Err));
1273 transferASTDataFromCompilerInstance(*Clang);
1275 Act->EndSourceFile();
1277 FailedParseDiagnostics.clear();
1279 CleanOnError.release();
1284static std::pair<unsigned, unsigned>
1288 unsigned Offset =
SM.getFileOffset(FileRange.
getBegin());
1289 unsigned EndOffset =
SM.getFileOffset(FileRange.
getEnd());
1290 return std::make_pair(Offset, EndOffset);
1317 OutDiag.
Filename = std::string(
SM.getFilename(FileLoc));
1321 for (
const auto &Range : InDiag.
getRanges())
1323 for (
const auto &FixIt : InDiag.
getFixIts())
1349std::unique_ptr<llvm::MemoryBuffer>
1350ASTUnit::getMainBufferWithPrecompiledPreamble(
1351 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1354 unsigned MaxLines) {
1357 std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
1359 MainFilePath, UserFilesAreVolatile);
1360 if (!MainFileBuffer)
1364 PreambleInvocationIn.
getLangOpts(), *MainFileBuffer, MaxLines);
1369 if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,
1380 PreambleRebuildCountdown = 1;
1381 return MainFileBuffer;
1384 PreambleDiagnostics.clear();
1385 TopLevelDeclsInPreamble.clear();
1386 PreambleSrcLocCache.clear();
1387 PreambleRebuildCountdown = 1;
1394 if (PreambleRebuildCountdown > 1) {
1395 --PreambleRebuildCountdown;
1399 assert(!Preamble &&
"No Preamble should be stored at that point");
1407 SmallVector<StandaloneDiagnostic, 4> NewPreambleDiagsStandalone;
1408 SmallVector<StoredDiagnostic, 4> NewPreambleDiags;
1409 ASTUnitPreambleCallbacks Callbacks;
1411 std::optional<CaptureDroppedDiagnostics>
Capture;
1413 Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags,
1414 &NewPreambleDiagsStandalone);
1417 SimpleTimer PreambleTimer(WantTiming);
1418 PreambleTimer.setOutput(
"Precompiling preamble");
1420 const bool PreviousSkipFunctionBodies =
1426 PreambleInvocationIn, MainFileBuffer.get(), Bounds, Diagnostics, VFS,
1427 PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath,
1431 PreviousSkipFunctionBodies;
1434 Preamble = std::move(*NewPreamble);
1435 PreambleRebuildCountdown = 1;
1440 PreambleRebuildCountdown = 1;
1450 llvm_unreachable(
"unexpected BuildPreambleError");
1454 assert(Preamble &&
"Preamble wasn't built");
1456 TopLevelDecls.clear();
1457 TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();
1458 PreambleTopLevelHashValue = Callbacks.getHash();
1463 StoredDiagnostics = std::move(NewPreambleDiags);
1464 PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);
1469 if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {
1470 CompletionCacheTopLevelHashValue = 0;
1471 PreambleTopLevelHashValue = CurrentTopLevelHashValue;
1474 return MainFileBuffer;
1477void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
1478 assert(Preamble &&
"Should only be called when preamble was built");
1480 std::vector<Decl *> Resolved;
1481 Resolved.reserve(TopLevelDeclsInPreamble.size());
1483 serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule();
1484 for (
const auto TopLevelDecl : TopLevelDeclsInPreamble) {
1487 if (Decl *D = Reader->GetLocalDecl(MF, TopLevelDecl))
1488 Resolved.push_back(D);
1490 TopLevelDeclsInPreamble.clear();
1491 TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
1517 if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
1522 return Input.
getBuffer().getBufferIdentifier();
1527 SourceMgr->getFileEntryRefForID(SourceMgr->getMainFileID()))
1528 return FE->getName();
1539 Mod = Reader->getModuleManager().getPrimaryModule();
1543std::unique_ptr<ASTUnit>
1545 std::shared_ptr<DiagnosticOptions> DiagOpts,
1548 bool UserFilesAreVolatile) {
1549 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
false));
1550 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1553 AST->DiagOpts = DiagOpts;
1554 AST->Diagnostics = Diags;
1555 AST->FileSystemOpts = CI->getFileSystemOpts();
1556 AST->Invocation = std::move(CI);
1558 llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
1559 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1560 AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
1561 AST->getDiagnostics(), *AST->FileMgr, UserFilesAreVolatile);
1568 std::shared_ptr<CompilerInvocation> CI,
1569 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1570 std::shared_ptr<DiagnosticOptions> DiagOpts,
1572 ASTUnit *Unit,
bool Persistent, StringRef ResourceFilesPath,
1574 unsigned PrecompilePreambleAfterNParses,
bool CacheCodeCompletionResults,
1575 bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
1576 assert(CI &&
"A CompilerInvocation is required");
1578 std::unique_ptr<ASTUnit> OwnAST;
1579 ASTUnit *AST = Unit;
1583 create(CI, DiagOpts, Diags, CaptureDiagnostics, UserFilesAreVolatile);
1589 if (!ResourceFilesPath.empty()) {
1591 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1593 AST->OnlyLocalDecls = OnlyLocalDecls;
1594 AST->CaptureDiagnostics = CaptureDiagnostics;
1595 if (PrecompilePreambleAfterNParses > 0)
1596 AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1598 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1599 AST->IncludeBriefCommentsInCodeCompletion =
false;
1602 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1603 ASTUnitCleanup(OwnAST.get());
1605 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1606 DiagCleanup(Diags.get());
1609 CI->getPreprocessorOpts().RetainRemappedFileBuffers =
true;
1610 CI->getFrontendOpts().DisableFree =
false;
1615 auto Clang = std::make_unique<CompilerInstance>(std::move(CI),
1616 std::move(PCHContainerOps));
1619 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1620 CICleanup(Clang.get());
1622 AST->OriginalSourceFile =
1623 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1630 if (!Clang->createTarget())
1633 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1634 "Invocation must have exactly one source file!");
1635 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1637 "FIXME: AST inputs not yet supported here!");
1638 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1640 "IR inputs not support here!");
1643 AST->TheSema.reset();
1646 AST->Reader =
nullptr;
1657 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1659 TrackerAct.reset(
new TopLevelDeclTrackerAction(*AST));
1660 Act = TrackerAct.get();
1664 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1665 ActCleanup(TrackerAct.get());
1667 if (!Act->
BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
1668 AST->transferASTDataFromCompilerInstance(*Clang);
1669 if (OwnAST && ErrAST)
1670 ErrAST->swap(OwnAST);
1675 if (Persistent && !TrackerAct) {
1676 Clang->getPreprocessor().addPPCallbacks(
1677 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1679 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1680 if (Clang->hasASTConsumer())
1681 Consumers.push_back(Clang->takeASTConsumer());
1682 Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(
1684 Clang->setASTConsumer(
1685 std::make_unique<MultiplexConsumer>(std::move(Consumers)));
1687 if (llvm::Error Err = Act->
Execute()) {
1688 consumeError(std::move(Err));
1689 AST->transferASTDataFromCompilerInstance(*Clang);
1690 if (OwnAST && ErrAST)
1691 ErrAST->swap(OwnAST);
1697 AST->transferASTDataFromCompilerInstance(*Clang);
1702 return OwnAST.release();
1707bool ASTUnit::LoadFromCompilerInvocation(
1708 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1709 unsigned PrecompilePreambleAfterNParses,
1714 assert(VFS &&
"VFS is null");
1717 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers =
true;
1718 Invocation->getFrontendOpts().DisableFree =
false;
1723 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1724 if (PrecompilePreambleAfterNParses > 0) {
1725 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1726 OverrideMainBuffer =
1727 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1733 SimpleTimer ParsingTimer(WantTiming);
1737 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1738 MemBufferCleanup(OverrideMainBuffer.get());
1740 return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1743std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1744 std::shared_ptr<CompilerInvocation> CI,
1745 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1746 std::shared_ptr<DiagnosticOptions> DiagOpts,
1751 bool CacheCodeCompletionResults,
bool IncludeBriefCommentsInCodeCompletion,
1752 bool UserFilesAreVolatile) {
1754 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
false));
1755 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1756 AST->DiagOpts = DiagOpts;
1757 AST->Diagnostics = Diags;
1758 AST->OnlyLocalDecls = OnlyLocalDecls;
1759 AST->CaptureDiagnostics = CaptureDiagnostics;
1760 AST->TUKind = TUKind;
1761 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1762 AST->IncludeBriefCommentsInCodeCompletion
1763 = IncludeBriefCommentsInCodeCompletion;
1764 AST->Invocation = std::move(CI);
1765 AST->FileSystemOpts = FileMgr->getFileSystemOpts();
1766 AST->FileMgr = FileMgr;
1767 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1770 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1771 ASTUnitCleanup(AST.get());
1773 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1774 DiagCleanup(Diags.get());
1776 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1777 PrecompilePreambleAfterNParses,
1778 AST->FileMgr->getVirtualFileSystemPtr()))
1784 const char **ArgBegin,
const char **ArgEnd,
1785 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1786 std::shared_ptr<DiagnosticOptions> DiagOpts,
1788 bool StorePreamblesInMemory, StringRef PreambleStoragePath,
1792 bool CacheCodeCompletionResults,
bool IncludeBriefCommentsInCodeCompletion,
1794 bool SingleFileParse,
bool UserFilesAreVolatile,
bool ForSerialization,
1795 bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,
1796 std::unique_ptr<ASTUnit> *ErrAST,
1798 assert(Diags.get() &&
"no DiagnosticsEngine was provided");
1804 VFS = llvm::vfs::createPhysicalFileSystem();
1808 std::shared_ptr<CompilerInvocation> CI;
1811 CaptureDroppedDiagnostics
Capture(CaptureDiagnostics, *Diags,
1812 &StoredDiagnostics,
nullptr);
1816 CIOpts.
Diags = Diags;
1825 CI->getPreprocessorOpts().addRemappedFile(
RemappedFile.first,
1830 PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
1831 PPOpts.SingleFileParseMode = SingleFileParse;
1832 PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
1835 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1837 CI->getFrontendOpts().SkipFunctionBodies =
1841 CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
1844 std::unique_ptr<ASTUnit> AST;
1845 AST.reset(
new ASTUnit(
false));
1846 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
1847 AST->StoredDiagnostics.swap(StoredDiagnostics);
1848 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1849 AST->DiagOpts = DiagOpts;
1850 AST->Diagnostics = Diags;
1851 AST->FileSystemOpts = CI->getFileSystemOpts();
1852 AST->CodeGenOpts = std::make_unique<CodeGenOptions>(CI->getCodeGenOpts());
1855 llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
1856 AST->StorePreamblesInMemory = StorePreamblesInMemory;
1857 AST->PreambleStoragePath = PreambleStoragePath;
1859 AST->OnlyLocalDecls = OnlyLocalDecls;
1860 AST->CaptureDiagnostics = CaptureDiagnostics;
1861 AST->TUKind = TUKind;
1862 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1863 AST->IncludeBriefCommentsInCodeCompletion
1864 = IncludeBriefCommentsInCodeCompletion;
1865 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1866 AST->Invocation = CI;
1867 AST->SkipFunctionBodies = SkipFunctionBodies;
1868 if (ForSerialization)
1869 AST->WriterData.reset(
new ASTWriterData(*AST->ModCache, *AST->CodeGenOpts));
1875 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1876 ASTUnitCleanup(AST.get());
1878 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1879 PrecompilePreambleAfterNParses,
1884 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
1900 assert(FileMgr &&
"FileMgr is null on Reparse call");
1901 VFS = FileMgr->getVirtualFileSystemPtr();
1904 clearFileLevelDecls();
1906 SimpleTimer ParsingTimer(WantTiming);
1911 for (
const auto &RB : PPOpts.RemappedFileBuffers)
1916 Invocation->getPreprocessorOpts().addRemappedFile(
RemappedFile.first,
1922 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1923 if (Preamble || PreambleRebuildCountdown > 0)
1924 OverrideMainBuffer =
1925 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1932 if (OverrideMainBuffer)
1937 Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1941 if (!
Result && ShouldCacheCodeCompletionResults &&
1942 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1943 CacheCodeCompletionResults();
1953 SavedMainFileBuffer.reset();
1961 TopLevelDecls.clear();
1962 clearFileLevelDecls();
1975 uint64_t NormalContexts;
2008 unsigned NumResults)
override;
2010 void ProcessOverloadCandidates(
Sema &S,
unsigned CurrentArg,
2012 unsigned NumCandidates,
2014 bool Braced)
override {
2015 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
2016 OpenParLoc, Braced);
2019 CodeCompletionAllocator &getAllocator()
override {
2020 return Next.getAllocator();
2023 CodeCompletionTUInfo &getCodeCompletionTUInfo()
override {
2024 return Next.getCodeCompletionTUInfo();
2034 unsigned NumResults,
2036 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
2037 bool OnlyTagNames =
false;
2038 switch (Context.getKind()) {
2063 OnlyTagNames =
true;
2089 for (
unsigned I = 0; I != NumResults; ++I) {
2090 if (Results[I].Kind != Result::RK_Declaration)
2096 bool Hiding =
false;
2105 Hiding = (IDNS & HiddenIDNS);
2113 HiddenNames.insert(Identifier->getName());
2119void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(
Sema &S,
2122 unsigned NumResults) {
2124 bool AddedResult =
false;
2127 ? NormalContexts : (1LL << Context.getKind());
2129 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
2138 if ((
C->ShowInContexts & InContexts) == 0)
2145 AllResults.insert(AllResults.end(), Results, Results + NumResults);
2152 HiddenNames.count(
C->Completion->getTypedText()))
2156 unsigned Priority =
C->Priority;
2158 if (!Context.getPreferredType().isNull()) {
2162 Context.getPreferredType()->isAnyPointerType());
2163 }
else if (
C->Type) {
2166 Context.getPreferredType().getUnqualifiedType());
2168 if (ExpectedSTC ==
C->TypeClass) {
2170 llvm::StringMap<unsigned> &CachedCompletionTypes
2172 llvm::StringMap<unsigned>::iterator Pos
2174 if (Pos != CachedCompletionTypes.end() && Pos->second ==
C->Type)
2189 Builder.AddTypedTextChunk(
C->Completion->getTypedText());
2191 Completion = Builder.TakeString();
2194 AllResults.push_back(
Result(Completion, Priority,
C->Kind,
2201 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2205 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
2212 bool IncludeCodePatterns,
bool IncludeBriefComments,
2214 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2220 std::unique_ptr<SyntaxOnlyAction> Act) {
2224 SimpleTimer CompletionTimer(WantTiming);
2225 CompletionTimer.setOutput(
"Code completion @ " +
File +
":" +
2228 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
2235 CachedCompletionResults.empty();
2237 CodeCompleteOpts.
IncludeGlobals = CachedCompletionResults.empty();
2239 CodeCompleteOpts.
LoadExternal = Consumer.loadExternal();
2242 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2249 LangOpts = CCInvocation->getLangOpts();
2252 LangOpts.SpellChecking =
false;
2253 CCInvocation->getDiagnosticOpts().IgnoreWarnings =
true;
2255 auto Clang = std::make_unique<CompilerInstance>(std::move(CCInvocation),
2259 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2260 CICleanup(Clang.get());
2262 auto &Inv = Clang->getInvocation();
2263 OriginalSourceFile =
2264 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2267 Clang->setDiagnostics(
Diag);
2269 Clang->getDiagnostics(),
2270 &StoredDiagnostics,
nullptr);
2272 FileMgr->getVirtualFileSystem());
2275 if (!Clang->createTarget()) {
2279 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2280 "Invocation must have exactly one source file!");
2281 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2283 "FIXME: AST inputs not yet supported here!");
2284 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2286 "IR inputs not support here!");
2289 Clang->setVirtualFileSystem(FileMgr->getVirtualFileSystemPtr());
2290 Clang->setFileManager(FileMgr);
2291 Clang->setSourceManager(SourceMgr);
2303 AugmentedCodeCompleteConsumer *AugmentedConsumer
2304 =
new AugmentedCodeCompleteConsumer(*
this, Consumer, CodeCompleteOpts);
2305 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2308 [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {
2309 if (
auto Status = FileMgr->getVirtualFileSystem().status(Filename))
2310 return Status->getUniqueID();
2311 return std::nullopt;
2314 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2317 if (
auto LHSID = getUniqueID(LHS))
2318 if (
auto RHSID = getUniqueID(RHS))
2319 return *LHSID == *RHSID;
2327 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2328 if (Preamble &&
Line > 1 && hasSameUniqueID(
File, OriginalSourceFile)) {
2329 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2330 PCHContainerOps, Inv, FileMgr->getVirtualFileSystemPtr(),
false,
2336 if (OverrideMainBuffer) {
2338 "No preamble was built, but OverrideMainBuffer is not null");
2341 FileMgr->getVirtualFileSystemPtr();
2342 Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
2343 OverrideMainBuffer.get());
2348 OwnedBuffers.push_back(OverrideMainBuffer.release());
2355 if (!Clang->getLangOpts().Modules)
2361 if (Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
2362 if (llvm::Error Err = Act->Execute()) {
2363 consumeError(std::move(Err));
2365 Act->EndSourceFile();
2370 if (HadModuleLoaderFatalFailure)
2376 if (llvm::Error Err = llvm::writeToOutput(
2377 File, [
this](llvm::raw_ostream &Out) {
2378 return serialize(Out) ? llvm::make_error<llvm::StringError>(
2379 "ASTUnit serialization failed",
2380 llvm::inconvertibleErrorCode())
2381 : llvm::Error::success();
2383 consumeError(std::move(Err));
2390 Sema &S, raw_ostream &OS) {
2391 Writer.
WriteAST(&S, std::string(),
nullptr,
"");
2394 if (!Buffer.empty())
2395 OS.write(Buffer.data(), Buffer.size());
2405 llvm::BitstreamWriter Stream(Buffer);
2407 ASTWriter Writer(Stream, Buffer, *ModCache, *CodeGenOpts, {});
2411void ASTUnit::TranslateStoredDiagnostics(
2421 Result.reserve(Diags.size());
2423 for (
const auto &SD : Diags) {
2425 if (SD.Filename.empty())
2427 auto FE =
FileMgr.getOptionalFileRef(SD.Filename);
2431 auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
2432 if (ItFileID == PreambleSrcLocCache.end()) {
2434 FileLoc =
SrcMgr.getLocForStartOfFile(FID);
2435 PreambleSrcLocCache[SD.Filename] = FileLoc;
2437 FileLoc = ItFileID->getValue();
2443 FullSourceLoc Loc(L, SrcMgr);
2445 SmallVector<CharSourceRange, 4> Ranges;
2446 Ranges.reserve(SD.Ranges.size());
2447 for (
const auto &Range : SD.Ranges) {
2453 SmallVector<FixItHint, 2> FixIts;
2454 FixIts.reserve(SD.FixIts.size());
2455 for (
const auto &FixIt : SD.FixIts) {
2456 FixIts.push_back(FixItHint());
2457 FixItHint &FH = FixIts.back();
2464 Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
2465 SD.Message, Loc, Ranges, FixIts));
2479 if (Loc.
isInvalid() || !
SM.isLocalSourceLocation(Loc))
2487 assert(
SM.isLocalSourceLocation(FileLoc));
2488 auto [FID, Offset] =
SM.getDecomposedLoc(FileLoc);
2492 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2494 Decls = std::make_unique<LocDeclsTy>();
2496 std::pair<unsigned, Decl *> LocDecl(Offset, D);
2498 if (Decls->empty() || Decls->back().first <= Offset) {
2499 Decls->push_back(LocDecl);
2503 LocDeclsTy::iterator I =
2504 llvm::upper_bound(*Decls, LocDecl, llvm::less_first());
2506 Decls->insert(I, LocDecl);
2511 if (
File.isInvalid())
2514 if (SourceMgr->isLoadedFileID(
File)) {
2515 assert(Ctx->getExternalSource() &&
"No external source!");
2516 return Ctx->getExternalSource()->FindFileRegionDecls(
File, Offset, Length,
2520 FileDeclsTy::iterator I = FileDecls.find(
File);
2521 if (I == FileDecls.end())
2524 LocDeclsTy &LocDecls = *I->second;
2525 if (LocDecls.empty())
2528 LocDeclsTy::iterator BeginIt =
2529 llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {
2530 return LD.first < Offset;
2532 if (BeginIt != LocDecls.begin())
2538 while (BeginIt != LocDecls.begin() &&
2539 BeginIt->second->isTopLevelDeclInObjCContainer())
2542 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2543 LocDecls, std::make_pair(Offset + Length, (
Decl *)
nullptr),
2544 llvm::less_first());
2545 if (EndIt != LocDecls.end())
2548 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2549 Decls.push_back(DIt->second);
2553 unsigned Line,
unsigned Col)
const {
2556 return SM.getMacroArgExpandedLocation(Loc);
2560 unsigned Offset)
const {
2572 PreambleID = SourceMgr->getPreambleFileID();
2578 if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {
2580 = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());
2593 PreambleID = SourceMgr->getPreambleFileID();
2599 if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&
2600 Offs < Preamble->getBounds().Size) {
2601 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);
2611 FID = SourceMgr->getPreambleFileID();
2616 return SourceMgr->isInFileID(Loc, FID);
2622 FID = SourceMgr->getMainFileID();
2627 return SourceMgr->isInFileID(Loc, FID);
2633 FID = SourceMgr->getPreambleFileID();
2638 return SourceMgr->getLocForEndOfFile(FID);
2644 FID = SourceMgr->getMainFileID();
2649 return SourceMgr->getLocForStartOfFile(FID);
2652llvm::iterator_range<PreprocessingRecord::iterator>
2656 Mod = Reader->getModuleManager().getPrimaryModule();
2657 return Reader->getModulePreprocessedEntities(Mod);
2661 return llvm::make_range(PPRec->local_begin(), PPRec->local_end());
2670 Mod = Reader->getModuleManager().getPrimaryModule();
2671 for (
const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2672 if (!Fn(context, D))
2681 TL != TLEnd; ++TL) {
2682 if (!Fn(context, *TL))
2691 return std::nullopt;
2714 return std::nullopt;
2725 if (LangOpts.OpenCL)
2727 else if (LangOpts.CUDA)
2729 else if (LangOpts.CPlusPlus)
2745ASTUnit::ConcurrencyState::ConcurrencyState() {
2746 Mutex =
new std::recursive_mutex;
2749ASTUnit::ConcurrencyState::~ConcurrencyState() {
2750 delete static_cast<std::recursive_mutex *
>(Mutex);
2753void ASTUnit::ConcurrencyState::start() {
2754 bool acquired =
static_cast<std::recursive_mutex *
>(Mutex)->try_lock();
2755 assert(acquired &&
"Concurrent access to ASTUnit!");
2758void ASTUnit::ConcurrencyState::finish() {
2759 static_cast<std::recursive_mutex *
>(Mutex)->unlock();
2764ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex =
nullptr; }
2765ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2766void ASTUnit::ConcurrencyState::start() {}
2767void ASTUnit::ConcurrencyState::finish() {}
Defines the clang::ASTContext interface.
static void checkAndSanitizeDiags(SmallVectorImpl< StoredDiagnostic > &StoredDiagnostics, SourceManager &SM)
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.
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.
static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash)
Add the given declaration to the hash of all top-level entities.
static bool moveOnNoError(llvm::ErrorOr< T > Val, T &Output)
static std::unique_ptr< T > valueOrNull(llvm::ErrorOr< std::unique_ptr< T > > Val)
static std::pair< unsigned, unsigned > makeStandaloneRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
static bool serializeUnit(ASTWriter &Writer, SmallVectorImpl< char > &Buffer, Sema &S, raw_ostream &OS)
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 ...
const unsigned DefaultPreambleRebuildInterval
After failing to build a precompiled preamble (due to errors in the source that occurs in the preambl...
static void checkAndRemoveNonDriverDiags(SmallVectorImpl< StoredDiagnostic > &StoredDiags)
static bool isInMainFile(const clang::Diagnostic &D)
static ASTUnit::StandaloneDiagnostic makeStandaloneDiagnostic(const LangOptions &LangOpts, const StoredDiagnostic &InDiag)
static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag)
static std::atomic< unsigned > ActiveASTUnitObjects
Tracks the number of ASTUnit objects that are currently active.
static ASTUnit::StandaloneFixIt makeStandaloneFixIt(const SourceManager &SM, const LangOptions &LangOpts, const FixItHint &InFix)
static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash)
Add the given macro to the hash of all top-level entities.
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.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
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
Defines the clang::Module class, which describes a module in the source code.
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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
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.
@ ARR_None
The client can't handle any AST loading failures.
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.
@ ConfigurationMismatch
The AST file was written with a different language/target configuration.
@ OutOfDate
The AST file is out-of-date relative to its input files, and needs to be regenerated.
@ Failure
The AST file itself appears corrupted.
@ VersionMismatch
The AST file was written by a different version of Clang.
@ HadErrors
The AST file has errors.
@ Missing
The AST file was missing.
Utility class for loading a ASTContext from an AST file.
unsigned & getCurrentTopLevelHashValue()
Retrieve a reference to the current top-level name hash value.
void enableSourceFileDiagnostics()
Enable source-range based diagnostic messages.
void addFileLevelDecl(Decl *D)
Add a new local file-level declaration.
const FileManager & getFileManager() const
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.
cached_completion_iterator cached_completion_end()
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.
bool serialize(raw_ostream &OS)
Serialize this translation unit with the given output stream.
ASTDeserializationListener * getDeserializationListener()
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...
std::unique_ptr< llvm::MemoryBuffer > getBufferForFile(StringRef Filename, std::string *ErrorStr=nullptr)
llvm::StringMap< unsigned > & getCachedCompletionTypes()
Retrieve the mapping from formatted type names to unique type identifiers.
const DiagnosticsEngine & getDiagnostics() const
SourceLocation getLocation(const FileEntry *File, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
void ResetForParse()
Free data that will be re-generated on the next parse.
llvm::IntrusiveRefCntPtr< SourceManager > getSourceManagerPtr()
InputKind getInputKind() const
Determine the input kind this AST unit represents.
OptionalFileEntryRef getPCHFile()
Get the PCH file if one was included.
StringRef getMainFileName() const
SourceLocation mapLocationToPreamble(SourceLocation Loc) const
If Loc is a local location of the main file but inside the preamble chunk, returns the corresponding ...
cached_completion_iterator cached_completion_begin()
const LangOptions & getLangOpts() const
bool isMainFileAST() const
std::vector< Decl * >::iterator top_level_iterator
const SourceManager & getSourceManager() const
SourceLocation getEndOfPreambleFileID() const
std::vector< CachedCodeCompletionResult >::iterator cached_completion_iterator
llvm::IntrusiveRefCntPtr< DiagnosticsEngine > getDiagnosticsPtr()
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...
@ LoadASTOnly
Load the AST, but do not restore Sema state.
@ LoadEverything
Load everything, including Sema.
top_level_iterator top_level_end()
SourceLocation getStartOfMainFileID() const
IntrusiveRefCntPtr< ASTReader > getASTReader() const
IntrusiveRefCntPtr< FileManager > getFileManagerPtr()
bool(*)(void *context, const Decl *D) DeclVisitorFn
Type for a function iterating over a number of declarations.
bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn)
Iterate over local declarations (locally parsed if this is a parsed source file or the loaded declara...
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr()
llvm::iterator_range< PreprocessingRecord::iterator > getLocalPreprocessingEntities() const
Returns an iterator range for the local preprocessing entities of the local Preprocessor,...
top_level_iterator top_level_begin()
ASTMutationListener * getASTMutationListener()
TranslationUnitKind getTranslationUnitKind() const
Determine what kind of translation unit this AST represents.
static std::unique_ptr< ASTUnit > LoadFromCommandLine(const char **ArgBegin, const char **ArgEnd, std::shared_ptr< PCHContainerOperations > PCHContainerOps, std::shared_ptr< DiagnosticOptions > DiagOpts, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, StringRef ResourceFilesPath, bool StorePreamblesInMemory=false, StringRef PreambleStoragePath=StringRef(), bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, ArrayRef< RemappedFile > RemappedFiles={}, bool RemappedFilesKeepOriginalName=true, unsigned PrecompilePreambleAfterNParses=0, TranslationUnitKind TUKind=TU_Complete, bool CacheCodeCompletionResults=false, bool IncludeBriefCommentsInCodeCompletion=false, bool AllowPCHWithCompilerErrors=false, SkipFunctionBodiesScope SkipFunctionBodies=SkipFunctionBodiesScope::None, bool SingleFileParse=false, bool UserFilesAreVolatile=false, bool ForSerialization=false, bool RetainExcludedConditionalBlocks=false, std::optional< StringRef > ModuleFormat=std::nullopt, std::unique_ptr< ASTUnit > *ErrAST=nullptr, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
LoadFromCommandLine - Create an ASTUnit from a vector of command line arguments, which must specify e...
void setPreprocessor(std::shared_ptr< Preprocessor > pp)
StringRef getASTFileName() const
If this ASTUnit came from an AST file, returns the filename for it.
bool Save(StringRef File)
Save this translation unit to a file with the given name.
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.
void addTopLevelDecl(Decl *D)
Add a new top-level declaration.
bool isInMainFileID(SourceLocation Loc) const
bool isModuleFile() const
Returns true if the ASTUnit was constructed from a serialized module file.
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.
const ASTContext & getASTContext() const
bool isInPreambleFileID(SourceLocation Loc) const
SourceLocation mapLocationFromPreamble(SourceLocation Loc) const
If Loc is a loaded location from the preamble, returns the corresponding local location of the main f...
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.
Writes an AST file containing the contents of a translation unit.
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, bool ShouldCacheASTInMemory=false)
Write a precompiled header or a module with the AST produced by the Sema object, or a dependency scan...
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
SourceLocation getEnd() const
SourceLocation getBegin() const
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.
@ CCC_ObjCClassForwardDecl
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
bool hasASTContext() 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.
bool hasPreprocessor() const
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...
bool isFileContext() const
bool isTranslationUnit() const
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.
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
unsigned getIdentifierNamespace() const
SourceLocation getLocation() const
@ IDNS_NonMemberOperator
This declaration is a C++ operator declared in a non-class context.
@ IDNS_Ordinary
Ordinary names.
@ IDNS_Type
Types, declared with 'struct foo', typedefs, etc.
@ IDNS_Member
Members, declared with object declarations within tag definitions.
@ IDNS_Namespace
Namespaces, declared with 'namespace foo {}'.
@ IDNS_Tag
Tags, declared with 'struct foo;' and referenced with 'struct foo'.
DeclContext * getDeclContext()
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
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.
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
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.
void setNumWarnings(unsigned NumWarnings)
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
Level
The level of the diagnostic, after it has been through mapping.
DiagnosticConsumer * getClient()
unsigned getNumWarnings() const
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).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
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.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
bool BeforePreviousInsertions
CharSourceRange RemoveRange
Code that should be replaced to correct the error.
CharSourceRange InsertFromRange
Code in the specific range that should be inserted in the insertion location.
std::string CodeToInsert
The actual code to insert at the insertion location, as a string.
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.
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.
const SourceManager & getManager() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
@ 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?
static CharSourceRange makeFileCharRange(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Accepts a range and returns a character range with file locations.
The module cache used for compiling modules implicitly.
Describes a module or submodule.
bool isNamedModule() const
Does this Module is a named module of a standard named module?
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
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.
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 RemappedFilesKeepOriginalName
True if the SourceManager should report the original file name for contents of files that were remapp...
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 clearRemappedFiles()
void addRemappedFile(StringRef From, StringRef To)
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Sema - This implements semantic analysis and AST building for C.
const LangOptions & getLangOpts() const
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...
ArrayRef< FixItHint > getFixIts() const
ArrayRef< CharSourceRange > getRanges() const
DiagnosticsEngine::Level getLevel() const
const FullSourceLoc & getLocation() const
StringRef getMessage() const
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, TargetOptions &Opts)
Construct a target for the given options.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
Information about a module that has been loaded by the ASTReader.
FileEntryRef File
The file entry for the module file.
std::string FileName
The file name of the module file.
ModuleKind Kind
The type of this module.
@ CXCursor_MacroDefinition
Defines the clang::TargetInfo interface.
Public enums and private classes that are part of the SourceManager implementation.
@ FixIt
Parse and apply any fixits to the source.
@ MK_PCH
File is a PCH file treated as such.
@ MK_Preamble
File is a PCH file treated as the preamble.
@ MK_MainFile
File is a PCH file treated as the actual main file.
@ MK_ExplicitModule
File is an explicitly-loaded module.
@ MK_ImplicitModule
File is an implicitly-loaded module.
@ MK_PrebuiltModule
File is from a prebuilt module path.
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)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
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.
SkipFunctionBodiesScope
Enumerates the available scopes for skipping function bodies.
@ Parse
Parse the block; this code is always used.
std::unique_ptr< CompilerInvocation > createInvocation(ArrayRef< const char * > Args, CreateInvocationOptions Opts={})
Interpret clang arguments in preparation to parse a file.
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.
SimplifiedTypeClass
A simplified classification of types used when determining "similar" types for code completion.
const FunctionProtoType * T
CaptureDiagsKind
Enumerates the available kinds for capturing diagnostics.
@ AllWithoutNonErrorsFromIncludes
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
IntrusiveRefCntPtr< ModuleCache > createCrossProcessModuleCache()
Creates new ModuleCache backed by a file system directory that may be operated on by multiple process...
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...
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.
@ CouldntCreateTargetInfo
llvm::StringRef getAsString(SyncScope S)
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.
llvm::BitstreamWriter Stream
SmallString< 128 > Buffer
ASTWriterData(ModuleCache &ModCache, const CodeGenOptions &CGOpts)
A cached code-completion result, which may be introduced in one of many different contexts.
CodeCompletionString * Completion
The code-completion string corresponding to this completion result.
DiagnosticsEngine::Level Level
std::vector< std::pair< unsigned, unsigned > > Ranges
std::vector< StandaloneFixIt > FixIts
std::pair< unsigned, unsigned > InsertFromRange
std::pair< unsigned, unsigned > RemoveRange
bool BeforePreviousInsertions
Optional inputs to createInvocation.
IntrusiveRefCntPtr< DiagnosticsEngine > Diags
Receives diagnostics encountered while parsing command-line flags.
bool ProbePrecompiled
Allow the driver to probe the filesystem for PCH files.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS
Used e.g.
OverloadCandidate - A single candidate in an overload set (C++ 13.3).
unsigned Size
Size of the preamble in bytes.
Describes how types, statements, expressions, and declarations should be printed.