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;
517 HeaderSearchOptions &HSOpts;
518 PreprocessorOptions &PPOpts;
519 LangOptions &LangOpt;
520 CodeGenOptions &CodeGenOpts;
521 std::shared_ptr<TargetOptions> &TargetOpts;
522 IntrusiveRefCntPtr<TargetInfo> &
Target;
524 bool InitializedLanguage =
false;
525 bool InitializedHeaderSearchPaths =
false;
528 ASTInfoCollector(Preprocessor &PP, ASTContext *Context,
529 HeaderSearchOptions &HSOpts, PreprocessorOptions &PPOpts,
530 LangOptions &LangOpt, CodeGenOptions &CodeGenOpts,
531 std::shared_ptr<TargetOptions> &TargetOpts,
532 IntrusiveRefCntPtr<TargetInfo> &
Target,
unsigned &Counter)
533 : PP(PP), Context(Context), HSOpts(HSOpts), PPOpts(PPOpts),
534 LangOpt(LangOpt), CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts),
537 bool ReadLanguageOptions(
const LangOptions &LangOpts,
538 StringRef ModuleFilename,
bool Complain,
539 bool AllowCompatibleDifferences)
override {
540 if (InitializedLanguage)
546 auto PICLevel = LangOpt.PICLevel;
547 auto PIE = LangOpt.PIE;
551 LangOpt.PICLevel = PICLevel;
554 InitializedLanguage =
true;
560 bool ReadCodeGenOptions(
const CodeGenOptions &CGOpts,
561 StringRef ModuleFilename,
bool Complain,
562 bool AllowCompatibleDifferences)
override {
563 this->CodeGenOpts = CGOpts;
567 bool ReadHeaderSearchOptions(
const HeaderSearchOptions &HSOpts,
568 StringRef ModuleFilename,
569 StringRef SpecificModuleCachePath,
570 bool Complain)
override {
572 auto ForceCheckCXX20ModulesInputFiles =
578 this->HSOpts = HSOpts;
580 ForceCheckCXX20ModulesInputFiles;
585 bool ReadHeaderSearchPaths(
const HeaderSearchOptions &HSOpts,
586 bool Complain)
override {
587 if (InitializedHeaderSearchPaths)
601 InitializedHeaderSearchPaths =
true;
606 bool ReadPreprocessorOptions(
const PreprocessorOptions &PPOpts,
607 StringRef ModuleFilename,
bool ReadMacros,
609 std::string &SuggestedPredefines)
override {
610 this->PPOpts = PPOpts;
614 bool ReadTargetOptions(
const TargetOptions &TargetOpts,
615 StringRef ModuleFilename,
bool Complain,
616 bool AllowCompatibleDifferences)
override {
621 this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
629 void ReadCounter(
const serialization::ModuleFile &M,
630 unsigned Value)
override {
636 if (!
Target || !InitializedLanguage)
666 SmallVectorImpl<StoredDiagnostic> *StoredDiags;
667 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags;
668 bool CaptureNonErrorsFromIncludes =
true;
669 const LangOptions *LangOpts =
nullptr;
670 SourceManager *SourceMgr =
nullptr;
673 FilterAndStoreDiagnosticConsumer(
674 SmallVectorImpl<StoredDiagnostic> *StoredDiags,
675 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags,
676 bool CaptureNonErrorsFromIncludes)
677 : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
678 CaptureNonErrorsFromIncludes(CaptureNonErrorsFromIncludes) {
679 assert((StoredDiags || StandaloneDiags) &&
680 "No output collections were passed to StoredDiagnosticConsumer.");
683 void BeginSourceFile(
const LangOptions &LangOpts,
684 const Preprocessor *PP =
nullptr)
override {
685 this->LangOpts = &LangOpts;
691 const Diagnostic &Info)
override;
696class CaptureDroppedDiagnostics {
697 DiagnosticsEngine &Diags;
698 FilterAndStoreDiagnosticConsumer Client;
699 DiagnosticConsumer *PreviousClient =
nullptr;
700 std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
703 CaptureDroppedDiagnostics(
705 SmallVectorImpl<StoredDiagnostic> *StoredDiags,
706 SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags)
708 Client(StoredDiags, StandaloneDiags,
709 CaptureDiagnostics !=
711 if (CaptureDiagnostics != CaptureDiagsKind::None ||
713 OwningPreviousClient = Diags.takeClient();
714 PreviousClient = Diags.getClient();
715 Diags.setClient(&Client, false);
719 ~CaptureDroppedDiagnostics() {
721 Diags.
setClient(PreviousClient, !!OwningPreviousClient.release());
739void FilterAndStoreDiagnosticConsumer::HandleDiagnostic(
755 StoredDiags->emplace_back(Level, Info);
756 ResultDiag = &StoredDiags->back();
759 if (StandaloneDiags) {
760 std::optional<StoredDiagnostic> StoredDiag;
762 StoredDiag.emplace(Level, Info);
763 ResultDiag = &*StoredDiag;
765 StandaloneDiags->push_back(
777 return &WriterData->Writer;
783 return &WriterData->Writer;
787std::unique_ptr<llvm::MemoryBuffer>
790 auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);
792 return std::move(*Buffer);
794 *ErrorStr = Buffer.getError().message();
802 assert(Diags.get() &&
"no DiagnosticsEngine was provided");
804 Diags->setClient(
new FilterAndStoreDiagnosticConsumer(
805 &AST.StoredDiagnostics,
nullptr,
812 std::shared_ptr<DiagnosticOptions> DiagOpts,
817 bool UserFilesAreVolatile) {
818 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
true));
821 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
822 ASTUnitCleanup(AST.get());
824 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
825 DiagCleanup(Diags.get());
827 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
829 AST->LangOpts = LangOpts ? std::make_unique<LangOptions>(*LangOpts)
830 : std::make_unique<LangOptions>();
831 AST->OnlyLocalDecls = OnlyLocalDecls;
832 AST->CaptureDiagnostics = CaptureDiagnostics;
833 AST->DiagOpts = DiagOpts;
834 AST->Diagnostics = Diags;
835 AST->FileMgr = llvm::makeIntrusiveRefCnt<FileManager>(FileSystemOpts, VFS);
836 AST->UserFilesAreVolatile = UserFilesAreVolatile;
837 AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
838 AST->getDiagnostics(), AST->getFileManager(), UserFilesAreVolatile);
840 AST->HSOpts = std::make_unique<HeaderSearchOptions>(HSOpts);
841 AST->HSOpts->ModuleFormat = std::string(PCHContainerRdr.
getFormats().front());
842 AST->HeaderInfo.reset(
new HeaderSearch(AST->getHeaderSearchOpts(),
843 AST->getSourceManager(),
844 AST->getDiagnostics(),
847 AST->PPOpts = std::make_shared<PreprocessorOptions>();
853 AST->PP = std::make_shared<Preprocessor>(
854 *AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
855 AST->getSourceManager(), HeaderInfo, AST->ModuleLoader,
861 AST->Ctx = llvm::makeIntrusiveRefCnt<ASTContext>(
862 *AST->LangOpts, AST->getSourceManager(), PP.getIdentifierTable(),
863 PP.getSelectorTable(), PP.getBuiltinInfo(),
864 AST->getTranslationUnitKind());
868 if (::getenv(
"LIBCLANG_DISABLE_PCH_VALIDATION"))
870 AST->Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
871 PP, *AST->ModCache, AST->Ctx.get(), PCHContainerRdr, *AST->CodeGenOpts,
872 ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
874 disableValid, AllowASTWithCompilerErrors);
876 unsigned Counter = 0;
877 AST->Reader->setListener(std::make_unique<ASTInfoCollector>(
878 *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
879 *AST->CodeGenOpts, AST->TargetOpts, AST->Target, Counter));
887 AST->Ctx->setExternalSource(AST->Reader);
900 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
904 AST->OriginalSourceFile = std::string(AST->Reader->getOriginalSourceFile());
906 PP.setCounterValue(Counter);
908 Module *M = HeaderInfo.lookupModule(AST->getLangOpts().CurrentModule);
909 if (M && AST->getLangOpts().isCompilingModule() && M->
isNamedModule())
910 AST->Ctx->setCurrentNamedModule(M);
918 AST->TheSema.reset(
new Sema(PP, *AST->Ctx, *AST->Consumer));
919 AST->TheSema->Initialize();
920 AST->Reader->InitializeSema(*AST->TheSema);
924 AST->getDiagnostics().getClient()->BeginSourceFile(PP.getLangOpts(), &PP);
938class MacroDefinitionTrackerPPCallbacks :
public PPCallbacks {
942 explicit MacroDefinitionTrackerPPCallbacks(
unsigned &Hash) : Hash(Hash) {}
944 void MacroDefined(
const Token &MacroNameTok,
945 const MacroDirective *MD)
override {
964 if (
const auto *ND = dyn_cast<NamedDecl>(D)) {
965 if (
const auto *EnumD = dyn_cast<EnumDecl>(D)) {
968 if (!EnumD->isScoped()) {
969 for (
const auto *EI : EnumD->enumerators()) {
970 if (EI->getIdentifier())
971 Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);
976 if (ND->getIdentifier())
977 Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);
979 std::string NameStr = Name.getAsString();
980 Hash = llvm::djbHash(NameStr, Hash);
985 if (
const auto *ImportD = dyn_cast<ImportDecl>(D)) {
986 if (
const Module *Mod = ImportD->getImportedModule()) {
987 std::string ModName = Mod->getFullModuleName();
988 Hash = llvm::djbHash(ModName, Hash);
996class TopLevelDeclTrackerConsumer :
public ASTConsumer {
1001 TopLevelDeclTrackerConsumer(ASTUnit &_Unit,
unsigned &Hash)
1002 : Unit(_Unit), Hash(Hash) {
1006 void handleTopLevelDecl(Decl *D) {
1020 handleFileLevelDecl(D);
1023 void handleFileLevelDecl(Decl *D) {
1025 if (
auto *NSD = dyn_cast<NamespaceDecl>(D)) {
1026 for (
auto *I : NSD->decls())
1027 handleFileLevelDecl(I);
1031 bool HandleTopLevelDecl(DeclGroupRef D)
override {
1032 for (
auto *TopLevelDecl : D)
1033 handleTopLevelDecl(TopLevelDecl);
1038 void HandleInterestingDecl(DeclGroupRef)
override {}
1040 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D)
override {
1041 for (
auto *TopLevelDecl : D)
1042 handleTopLevelDecl(TopLevelDecl);
1045 ASTMutationListener *GetASTMutationListener()
override {
1049 ASTDeserializationListener *GetASTDeserializationListener()
override {
1058 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
1059 StringRef InFile)
override {
1061 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1063 return std::make_unique<TopLevelDeclTrackerConsumer>(
1068 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
1070 bool hasCodeCompletionSupport()
const override {
return false; }
1079 unsigned getHash()
const {
return Hash; }
1081 std::vector<Decl *> takeTopLevelDecls() {
return std::move(TopLevelDecls); }
1083 std::vector<LocalDeclID> takeTopLevelDeclIDs() {
1084 return std::move(TopLevelDeclIDs);
1087 void AfterPCHEmitted(ASTWriter &Writer)
override {
1088 TopLevelDeclIDs.reserve(TopLevelDecls.size());
1089 for (
const auto *D : TopLevelDecls) {
1091 if (D->isInvalidDecl())
1093 TopLevelDeclIDs.push_back(Writer.
getDeclID(D));
1097 void HandleTopLevelDecl(DeclGroupRef DG)
override {
1098 for (
auto *D : DG) {
1106 TopLevelDecls.push_back(D);
1110 std::unique_ptr<PPCallbacks> createPPCallbacks()
override {
1111 return std::make_unique<MacroDefinitionTrackerPPCallbacks>(Hash);
1116 std::vector<Decl *> TopLevelDecls;
1117 std::vector<LocalDeclID> TopLevelDeclIDs;
1118 llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags;
1142 for (
auto &SD : StoredDiagnostics) {
1143 if (SD.getLocation().isValid()) {
1145 SD.setLocation(Loc);
1155bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1156 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer,
1162 assert(VFS == &FileMgr->getVirtualFileSystem() &&
1163 "VFS passed to Parse and VFS in FileMgr are different");
1165 CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
1166 if (OverrideMainBuffer) {
1168 "No preamble was built, but OverrideMainBuffer is not null");
1169 Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());
1174 auto Clang = std::make_unique<CompilerInstance>(CCInvocation,
1175 std::move(PCHContainerOps));
1178 auto CleanOnError = llvm::make_scope_exit([&]() {
1180 SavedMainFileBuffer =
nullptr;
1184 transferASTDataFromCompilerInstance(*Clang);
1185 FailedParseDiagnostics.swap(StoredDiagnostics);
1186 StoredDiagnostics.clear();
1187 NumStoredDiagnosticsFromDriver = 0;
1193 if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS) {
1194 Clang->setVirtualFileSystem(std::move(VFS));
1195 Clang->setFileManager(FileMgr);
1197 Clang->setVirtualFileSystem(std::move(VFS));
1198 Clang->createFileManager();
1199 FileMgr = Clang->getFileManagerPtr();
1203 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1204 CICleanup(Clang.get());
1206 OriginalSourceFile =
1207 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1214 if (!Clang->createTarget())
1217 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1218 "Invocation must have exactly one source file!");
1219 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1221 "FIXME: AST inputs not yet supported here!");
1222 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1224 "IR inputs not support here!");
1228 std::make_unique<LangOptions>(Clang->getInvocation().getLangOpts());
1229 FileSystemOpts = Clang->getFileSystemOpts();
1233 SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
1235 if (!OverrideMainBuffer) {
1237 TopLevelDeclsInPreamble.clear();
1245 if (OverrideMainBuffer) {
1254 SavedMainFileBuffer = std::move(OverrideMainBuffer);
1257 std::unique_ptr<TopLevelDeclTrackerAction> Act(
1258 new TopLevelDeclTrackerAction(*
this));
1261 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1262 ActCleanup(Act.get());
1264 if (!Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
1267 if (SavedMainFileBuffer)
1269 PreambleDiagnostics, StoredDiagnostics);
1271 PreambleSrcLocCache.clear();
1273 if (llvm::Error Err = Act->Execute()) {
1274 consumeError(std::move(Err));
1278 transferASTDataFromCompilerInstance(*Clang);
1280 Act->EndSourceFile();
1282 FailedParseDiagnostics.clear();
1284 CleanOnError.release();
1289static std::pair<unsigned, unsigned>
1293 unsigned Offset =
SM.getFileOffset(FileRange.
getBegin());
1294 unsigned EndOffset =
SM.getFileOffset(FileRange.
getEnd());
1295 return std::make_pair(Offset, EndOffset);
1322 OutDiag.
Filename = std::string(
SM.getFilename(FileLoc));
1326 for (
const auto &Range : InDiag.
getRanges())
1328 for (
const auto &FixIt : InDiag.
getFixIts())
1354std::unique_ptr<llvm::MemoryBuffer>
1355ASTUnit::getMainBufferWithPrecompiledPreamble(
1356 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1359 unsigned MaxLines) {
1362 std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
1364 MainFilePath, UserFilesAreVolatile);
1365 if (!MainFileBuffer)
1369 PreambleInvocationIn.
getLangOpts(), *MainFileBuffer, MaxLines);
1374 if (Preamble->CanReuse(PreambleInvocationIn, *MainFileBuffer, Bounds,
1385 PreambleRebuildCountdown = 1;
1386 return MainFileBuffer;
1389 PreambleDiagnostics.clear();
1390 TopLevelDeclsInPreamble.clear();
1391 PreambleSrcLocCache.clear();
1392 PreambleRebuildCountdown = 1;
1399 if (PreambleRebuildCountdown > 1) {
1400 --PreambleRebuildCountdown;
1404 assert(!Preamble &&
"No Preamble should be stored at that point");
1412 SmallVector<StandaloneDiagnostic, 4> NewPreambleDiagsStandalone;
1413 SmallVector<StoredDiagnostic, 4> NewPreambleDiags;
1414 ASTUnitPreambleCallbacks Callbacks;
1416 std::optional<CaptureDroppedDiagnostics>
Capture;
1418 Capture.emplace(CaptureDiagnostics, *Diagnostics, &NewPreambleDiags,
1419 &NewPreambleDiagsStandalone);
1422 SimpleTimer PreambleTimer(WantTiming);
1423 PreambleTimer.setOutput(
"Precompiling preamble");
1425 const bool PreviousSkipFunctionBodies =
1431 PreambleInvocationIn, MainFileBuffer.get(), Bounds, Diagnostics, VFS,
1432 PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath,
1436 PreviousSkipFunctionBodies;
1439 Preamble = std::move(*NewPreamble);
1440 PreambleRebuildCountdown = 1;
1445 PreambleRebuildCountdown = 1;
1455 llvm_unreachable(
"unexpected BuildPreambleError");
1459 assert(Preamble &&
"Preamble wasn't built");
1461 TopLevelDecls.clear();
1462 TopLevelDeclsInPreamble = Callbacks.takeTopLevelDeclIDs();
1463 PreambleTopLevelHashValue = Callbacks.getHash();
1468 StoredDiagnostics = std::move(NewPreambleDiags);
1469 PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);
1474 if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) {
1475 CompletionCacheTopLevelHashValue = 0;
1476 PreambleTopLevelHashValue = CurrentTopLevelHashValue;
1479 return MainFileBuffer;
1482void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
1483 assert(Preamble &&
"Should only be called when preamble was built");
1485 std::vector<Decl *> Resolved;
1486 Resolved.reserve(TopLevelDeclsInPreamble.size());
1488 serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule();
1489 for (
const auto TopLevelDecl : TopLevelDeclsInPreamble) {
1492 if (Decl *D = Reader->GetLocalDecl(MF, TopLevelDecl))
1493 Resolved.push_back(D);
1495 TopLevelDeclsInPreamble.clear();
1496 TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end());
1522 if (Invocation && !Invocation->getFrontendOpts().Inputs.empty()) {
1527 return Input.
getBuffer().getBufferIdentifier();
1532 SourceMgr->getFileEntryRefForID(SourceMgr->getMainFileID()))
1533 return FE->getName();
1544 Mod = Reader->getModuleManager().getPrimaryModule();
1548std::unique_ptr<ASTUnit>
1550 std::shared_ptr<DiagnosticOptions> DiagOpts,
1553 bool UserFilesAreVolatile) {
1554 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
false));
1555 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1558 AST->DiagOpts = DiagOpts;
1559 AST->Diagnostics = Diags;
1560 AST->FileSystemOpts = CI->getFileSystemOpts();
1561 AST->Invocation = std::move(CI);
1563 llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
1564 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1565 AST->SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
1566 AST->getDiagnostics(), *AST->FileMgr, UserFilesAreVolatile);
1573 std::shared_ptr<CompilerInvocation> CI,
1574 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1575 std::shared_ptr<DiagnosticOptions> DiagOpts,
1577 ASTUnit *Unit,
bool Persistent, StringRef ResourceFilesPath,
1579 unsigned PrecompilePreambleAfterNParses,
bool CacheCodeCompletionResults,
1580 bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
1581 assert(CI &&
"A CompilerInvocation is required");
1583 std::unique_ptr<ASTUnit> OwnAST;
1584 ASTUnit *AST = Unit;
1588 create(CI, DiagOpts, Diags, CaptureDiagnostics, UserFilesAreVolatile);
1594 if (!ResourceFilesPath.empty()) {
1596 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1598 AST->OnlyLocalDecls = OnlyLocalDecls;
1599 AST->CaptureDiagnostics = CaptureDiagnostics;
1600 if (PrecompilePreambleAfterNParses > 0)
1601 AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1603 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1604 AST->IncludeBriefCommentsInCodeCompletion =
false;
1607 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1608 ASTUnitCleanup(OwnAST.get());
1610 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1611 DiagCleanup(Diags.get());
1614 CI->getPreprocessorOpts().RetainRemappedFileBuffers =
true;
1615 CI->getFrontendOpts().DisableFree =
false;
1620 auto Clang = std::make_unique<CompilerInstance>(std::move(CI),
1621 std::move(PCHContainerOps));
1624 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
1625 CICleanup(Clang.get());
1627 AST->OriginalSourceFile =
1628 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
1635 if (!Clang->createTarget())
1638 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
1639 "Invocation must have exactly one source file!");
1640 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
1642 "FIXME: AST inputs not yet supported here!");
1643 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
1645 "IR inputs not support here!");
1648 AST->TheSema.reset();
1651 AST->Reader =
nullptr;
1661 std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
1663 TrackerAct.reset(
new TopLevelDeclTrackerAction(*AST));
1664 Act = TrackerAct.get();
1668 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
1669 ActCleanup(TrackerAct.get());
1671 if (!Act->
BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
1672 AST->transferASTDataFromCompilerInstance(*Clang);
1673 if (OwnAST && ErrAST)
1674 ErrAST->swap(OwnAST);
1679 if (Persistent && !TrackerAct) {
1680 Clang->getPreprocessor().addPPCallbacks(
1681 std::make_unique<MacroDefinitionTrackerPPCallbacks>(
1683 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1684 if (Clang->hasASTConsumer())
1685 Consumers.push_back(Clang->takeASTConsumer());
1686 Consumers.push_back(std::make_unique<TopLevelDeclTrackerConsumer>(
1688 Clang->setASTConsumer(
1689 std::make_unique<MultiplexConsumer>(std::move(Consumers)));
1691 if (llvm::Error Err = Act->
Execute()) {
1692 consumeError(std::move(Err));
1693 AST->transferASTDataFromCompilerInstance(*Clang);
1694 if (OwnAST && ErrAST)
1695 ErrAST->swap(OwnAST);
1701 AST->transferASTDataFromCompilerInstance(*Clang);
1706 return OwnAST.release();
1711bool ASTUnit::LoadFromCompilerInvocation(
1712 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1713 unsigned PrecompilePreambleAfterNParses,
1718 assert(VFS &&
"VFS is null");
1721 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers =
true;
1722 Invocation->getFrontendOpts().DisableFree =
false;
1727 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1728 if (PrecompilePreambleAfterNParses > 0) {
1729 PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
1730 OverrideMainBuffer =
1731 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1737 SimpleTimer ParsingTimer(WantTiming);
1741 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
1742 MemBufferCleanup(OverrideMainBuffer.get());
1744 return Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1747std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
1748 std::shared_ptr<CompilerInvocation> CI,
1749 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1750 std::shared_ptr<DiagnosticOptions> DiagOpts,
1755 bool CacheCodeCompletionResults,
bool IncludeBriefCommentsInCodeCompletion,
1756 bool UserFilesAreVolatile) {
1758 std::unique_ptr<ASTUnit> AST(
new ASTUnit(
false));
1759 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1760 AST->DiagOpts = DiagOpts;
1761 AST->Diagnostics = Diags;
1762 AST->OnlyLocalDecls = OnlyLocalDecls;
1763 AST->CaptureDiagnostics = CaptureDiagnostics;
1764 AST->TUKind = TUKind;
1765 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1766 AST->IncludeBriefCommentsInCodeCompletion
1767 = IncludeBriefCommentsInCodeCompletion;
1768 AST->Invocation = std::move(CI);
1769 AST->FileSystemOpts = FileMgr->getFileSystemOpts();
1770 AST->FileMgr = FileMgr;
1771 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1774 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1775 ASTUnitCleanup(AST.get());
1777 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
1778 DiagCleanup(Diags.get());
1780 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1781 PrecompilePreambleAfterNParses,
1782 AST->FileMgr->getVirtualFileSystemPtr()))
1788 const char **ArgBegin,
const char **ArgEnd,
1789 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
1790 std::shared_ptr<DiagnosticOptions> DiagOpts,
1792 bool StorePreamblesInMemory, StringRef PreambleStoragePath,
1796 bool CacheCodeCompletionResults,
bool IncludeBriefCommentsInCodeCompletion,
1798 bool SingleFileParse,
bool UserFilesAreVolatile,
bool ForSerialization,
1799 bool RetainExcludedConditionalBlocks, std::optional<StringRef> ModuleFormat,
1800 std::unique_ptr<ASTUnit> *ErrAST,
1802 assert(Diags.get() &&
"no DiagnosticsEngine was provided");
1808 VFS = llvm::vfs::createPhysicalFileSystem();
1812 std::shared_ptr<CompilerInvocation> CI;
1815 CaptureDroppedDiagnostics
Capture(CaptureDiagnostics, *Diags,
1816 &StoredDiagnostics,
nullptr);
1820 CIOpts.
Diags = Diags;
1829 CI->getPreprocessorOpts().addRemappedFile(
RemappedFile.first,
1834 PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
1835 PPOpts.SingleFileParseMode = SingleFileParse;
1836 PPOpts.RetainExcludedConditionalBlocks = RetainExcludedConditionalBlocks;
1839 CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
1841 CI->getFrontendOpts().SkipFunctionBodies =
1845 CI->getHeaderSearchOpts().ModuleFormat = std::string(*ModuleFormat);
1848 std::unique_ptr<ASTUnit> AST;
1849 AST.reset(
new ASTUnit(
false));
1850 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
1851 AST->StoredDiagnostics.swap(StoredDiagnostics);
1852 ConfigureDiags(Diags, *AST, CaptureDiagnostics);
1853 AST->DiagOpts = DiagOpts;
1854 AST->Diagnostics = Diags;
1855 AST->FileSystemOpts = CI->getFileSystemOpts();
1856 AST->CodeGenOpts = std::make_unique<CodeGenOptions>(CI->getCodeGenOpts());
1859 llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
1860 AST->StorePreamblesInMemory = StorePreamblesInMemory;
1861 AST->PreambleStoragePath = PreambleStoragePath;
1863 AST->OnlyLocalDecls = OnlyLocalDecls;
1864 AST->CaptureDiagnostics = CaptureDiagnostics;
1865 AST->TUKind = TUKind;
1866 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
1867 AST->IncludeBriefCommentsInCodeCompletion
1868 = IncludeBriefCommentsInCodeCompletion;
1869 AST->UserFilesAreVolatile = UserFilesAreVolatile;
1870 AST->Invocation = CI;
1871 AST->SkipFunctionBodies = SkipFunctionBodies;
1872 if (ForSerialization)
1873 AST->WriterData.reset(
new ASTWriterData(*AST->ModCache, *AST->CodeGenOpts));
1879 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
1880 ASTUnitCleanup(AST.get());
1882 if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
1883 PrecompilePreambleAfterNParses,
1888 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
1904 assert(FileMgr &&
"FileMgr is null on Reparse call");
1905 VFS = FileMgr->getVirtualFileSystemPtr();
1908 clearFileLevelDecls();
1910 SimpleTimer ParsingTimer(WantTiming);
1915 for (
const auto &RB : PPOpts.RemappedFileBuffers)
1920 Invocation->getPreprocessorOpts().addRemappedFile(
RemappedFile.first,
1926 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
1927 if (Preamble || PreambleRebuildCountdown > 0)
1928 OverrideMainBuffer =
1929 getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
1936 if (OverrideMainBuffer)
1941 Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
1945 if (!
Result && ShouldCacheCodeCompletionResults &&
1946 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
1947 CacheCodeCompletionResults();
1957 SavedMainFileBuffer.reset();
1965 TopLevelDecls.clear();
1966 clearFileLevelDecls();
1979 uint64_t NormalContexts;
2012 unsigned NumResults)
override;
2014 void ProcessOverloadCandidates(
Sema &S,
unsigned CurrentArg,
2016 unsigned NumCandidates,
2018 bool Braced)
override {
2019 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates,
2020 OpenParLoc, Braced);
2023 CodeCompletionAllocator &getAllocator()
override {
2024 return Next.getAllocator();
2027 CodeCompletionTUInfo &getCodeCompletionTUInfo()
override {
2028 return Next.getCodeCompletionTUInfo();
2038 unsigned NumResults,
2040 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){
2041 bool OnlyTagNames =
false;
2042 switch (Context.getKind()) {
2067 OnlyTagNames =
true;
2093 for (
unsigned I = 0; I != NumResults; ++I) {
2094 if (Results[I].Kind != Result::RK_Declaration)
2100 bool Hiding =
false;
2109 Hiding = (IDNS & HiddenIDNS);
2117 HiddenNames.insert(Identifier->getName());
2123void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(
Sema &S,
2126 unsigned NumResults) {
2128 bool AddedResult =
false;
2131 ? NormalContexts : (1LL << Context.getKind());
2133 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
2142 if ((
C->ShowInContexts & InContexts) == 0)
2149 AllResults.insert(AllResults.end(), Results, Results + NumResults);
2156 HiddenNames.count(
C->Completion->getTypedText()))
2160 unsigned Priority =
C->Priority;
2162 if (!Context.getPreferredType().isNull()) {
2166 Context.getPreferredType()->isAnyPointerType());
2167 }
else if (
C->Type) {
2170 Context.getPreferredType().getUnqualifiedType());
2172 if (ExpectedSTC ==
C->TypeClass) {
2174 llvm::StringMap<unsigned> &CachedCompletionTypes
2176 llvm::StringMap<unsigned>::iterator Pos
2178 if (Pos != CachedCompletionTypes.end() && Pos->second ==
C->Type)
2193 Builder.AddTypedTextChunk(
C->Completion->getTypedText());
2195 Completion = Builder.TakeString();
2198 AllResults.push_back(
Result(Completion, Priority,
C->Kind,
2205 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
2209 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
2216 bool IncludeCodePatterns,
bool IncludeBriefComments,
2218 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
2224 std::unique_ptr<SyntaxOnlyAction> Act) {
2228 SimpleTimer CompletionTimer(WantTiming);
2229 CompletionTimer.setOutput(
"Code completion @ " +
File +
":" +
2232 auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
2239 CachedCompletionResults.empty();
2241 CodeCompleteOpts.
IncludeGlobals = CachedCompletionResults.empty();
2243 CodeCompleteOpts.
LoadExternal = Consumer.loadExternal();
2246 assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
2253 LangOpts = CCInvocation->getLangOpts();
2256 LangOpts.SpellChecking =
false;
2257 CCInvocation->getDiagnosticOpts().IgnoreWarnings =
true;
2259 auto Clang = std::make_unique<CompilerInstance>(std::move(CCInvocation),
2263 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
2264 CICleanup(Clang.get());
2266 auto &Inv = Clang->getInvocation();
2267 OriginalSourceFile =
2268 std::string(Clang->getFrontendOpts().Inputs[0].getFile());
2271 Clang->setDiagnostics(
Diag);
2273 Clang->getDiagnostics(),
2274 &StoredDiagnostics,
nullptr);
2276 FileMgr->getVirtualFileSystem());
2279 if (!Clang->createTarget()) {
2283 assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
2284 "Invocation must have exactly one source file!");
2285 assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
2287 "FIXME: AST inputs not yet supported here!");
2288 assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
2290 "IR inputs not support here!");
2293 Clang->setFileManager(FileMgr);
2294 Clang->setSourceManager(SourceMgr);
2306 AugmentedCodeCompleteConsumer *AugmentedConsumer
2307 =
new AugmentedCodeCompleteConsumer(*
this, Consumer, CodeCompleteOpts);
2308 Clang->setCodeCompletionConsumer(AugmentedConsumer);
2311 [&FileMgr](StringRef Filename) -> std::optional<llvm::sys::fs::UniqueID> {
2312 if (
auto Status = FileMgr->getVirtualFileSystem().status(Filename))
2313 return Status->getUniqueID();
2314 return std::nullopt;
2317 auto hasSameUniqueID = [getUniqueID](StringRef LHS, StringRef RHS) {
2320 if (
auto LHSID = getUniqueID(LHS))
2321 if (
auto RHSID = getUniqueID(RHS))
2322 return *LHSID == *RHSID;
2330 std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
2331 if (Preamble &&
Line > 1 && hasSameUniqueID(
File, OriginalSourceFile)) {
2332 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
2333 PCHContainerOps, Inv, FileMgr->getVirtualFileSystemPtr(),
false,
2339 if (OverrideMainBuffer) {
2341 "No preamble was built, but OverrideMainBuffer is not null");
2344 FileMgr->getVirtualFileSystemPtr();
2345 Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
2346 OverrideMainBuffer.get());
2351 OwnedBuffers.push_back(OverrideMainBuffer.release());
2358 if (!Clang->getLangOpts().Modules)
2364 if (Act->BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
2365 if (llvm::Error Err = Act->Execute()) {
2366 consumeError(std::move(Err));
2368 Act->EndSourceFile();
2373 if (HadModuleLoaderFatalFailure)
2379 if (llvm::Error Err = llvm::writeToOutput(
2380 File, [
this](llvm::raw_ostream &Out) {
2381 return serialize(Out) ? llvm::make_error<llvm::StringError>(
2382 "ASTUnit serialization failed",
2383 llvm::inconvertibleErrorCode())
2384 : llvm::Error::success();
2386 consumeError(std::move(Err));
2393 Sema &S, raw_ostream &OS) {
2394 Writer.
WriteAST(&S, std::string(),
nullptr,
"");
2397 if (!Buffer.empty())
2398 OS.write(Buffer.data(), Buffer.size());
2408 llvm::BitstreamWriter Stream(Buffer);
2410 ASTWriter Writer(Stream, Buffer, *ModCache, *CodeGenOpts, {});
2414void ASTUnit::TranslateStoredDiagnostics(
2424 Result.reserve(Diags.size());
2426 for (
const auto &SD : Diags) {
2428 if (SD.Filename.empty())
2430 auto FE =
FileMgr.getOptionalFileRef(SD.Filename);
2434 auto ItFileID = PreambleSrcLocCache.find(SD.Filename);
2435 if (ItFileID == PreambleSrcLocCache.end()) {
2437 FileLoc =
SrcMgr.getLocForStartOfFile(FID);
2438 PreambleSrcLocCache[SD.Filename] = FileLoc;
2440 FileLoc = ItFileID->getValue();
2446 FullSourceLoc Loc(L, SrcMgr);
2448 SmallVector<CharSourceRange, 4> Ranges;
2449 Ranges.reserve(SD.Ranges.size());
2450 for (
const auto &Range : SD.Ranges) {
2456 SmallVector<FixItHint, 2> FixIts;
2457 FixIts.reserve(SD.FixIts.size());
2458 for (
const auto &FixIt : SD.FixIts) {
2459 FixIts.push_back(FixItHint());
2460 FixItHint &FH = FixIts.back();
2467 Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
2468 SD.Message, Loc, Ranges, FixIts));
2482 if (Loc.
isInvalid() || !
SM.isLocalSourceLocation(Loc))
2490 assert(
SM.isLocalSourceLocation(FileLoc));
2491 auto [FID, Offset] =
SM.getDecomposedLoc(FileLoc);
2495 std::unique_ptr<LocDeclsTy> &Decls = FileDecls[FID];
2497 Decls = std::make_unique<LocDeclsTy>();
2499 std::pair<unsigned, Decl *> LocDecl(Offset, D);
2501 if (Decls->empty() || Decls->back().first <= Offset) {
2502 Decls->push_back(LocDecl);
2506 LocDeclsTy::iterator I =
2507 llvm::upper_bound(*Decls, LocDecl, llvm::less_first());
2509 Decls->insert(I, LocDecl);
2514 if (
File.isInvalid())
2517 if (SourceMgr->isLoadedFileID(
File)) {
2518 assert(Ctx->getExternalSource() &&
"No external source!");
2519 return Ctx->getExternalSource()->FindFileRegionDecls(
File, Offset, Length,
2523 FileDeclsTy::iterator I = FileDecls.find(
File);
2524 if (I == FileDecls.end())
2527 LocDeclsTy &LocDecls = *I->second;
2528 if (LocDecls.empty())
2531 LocDeclsTy::iterator BeginIt =
2532 llvm::partition_point(LocDecls, [=](std::pair<unsigned, Decl *> LD) {
2533 return LD.first < Offset;
2535 if (BeginIt != LocDecls.begin())
2541 while (BeginIt != LocDecls.begin() &&
2542 BeginIt->second->isTopLevelDeclInObjCContainer())
2545 LocDeclsTy::iterator EndIt = llvm::upper_bound(
2546 LocDecls, std::make_pair(Offset + Length, (
Decl *)
nullptr),
2547 llvm::less_first());
2548 if (EndIt != LocDecls.end())
2551 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
2552 Decls.push_back(DIt->second);
2556 unsigned Line,
unsigned Col)
const {
2559 return SM.getMacroArgExpandedLocation(Loc);
2563 unsigned Offset)
const {
2575 PreambleID = SourceMgr->getPreambleFileID();
2581 if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble->getBounds().Size) {
2583 = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID());
2596 PreambleID = SourceMgr->getPreambleFileID();
2602 if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) &&
2603 Offs < Preamble->getBounds().Size) {
2604 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID);
2614 FID = SourceMgr->getPreambleFileID();
2619 return SourceMgr->isInFileID(Loc, FID);
2625 FID = SourceMgr->getMainFileID();
2630 return SourceMgr->isInFileID(Loc, FID);
2636 FID = SourceMgr->getPreambleFileID();
2641 return SourceMgr->getLocForEndOfFile(FID);
2647 FID = SourceMgr->getMainFileID();
2652 return SourceMgr->getLocForStartOfFile(FID);
2655llvm::iterator_range<PreprocessingRecord::iterator>
2659 Mod = Reader->getModuleManager().getPrimaryModule();
2660 return Reader->getModulePreprocessedEntities(Mod);
2664 return llvm::make_range(PPRec->local_begin(), PPRec->local_end());
2673 Mod = Reader->getModuleManager().getPrimaryModule();
2674 for (
const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
2675 if (!Fn(context, D))
2684 TL != TLEnd; ++TL) {
2685 if (!Fn(context, *TL))
2694 return std::nullopt;
2717 return std::nullopt;
2728 if (LangOpts.OpenCL)
2730 else if (LangOpts.CUDA)
2732 else if (LangOpts.CPlusPlus)
2748ASTUnit::ConcurrencyState::ConcurrencyState() {
2749 Mutex =
new std::recursive_mutex;
2752ASTUnit::ConcurrencyState::~ConcurrencyState() {
2753 delete static_cast<std::recursive_mutex *
>(Mutex);
2756void ASTUnit::ConcurrencyState::start() {
2757 bool acquired =
static_cast<std::recursive_mutex *
>(Mutex)->try_lock();
2758 assert(acquired &&
"Concurrent access to ASTUnit!");
2761void ASTUnit::ConcurrencyState::finish() {
2762 static_cast<std::recursive_mutex *
>(Mutex)->unlock();
2767ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex =
nullptr; }
2768ASTUnit::ConcurrencyState::~ConcurrencyState() {}
2769void ASTUnit::ConcurrencyState::start() {}
2770void 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::Target Target
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 ...
void InitBuiltinTypes(const TargetInfo &Target, const TargetInfo *AuxTarget=nullptr)
Initialize built-in types.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
comments::CommandTraits & getCommentCommandTraits() const
const LangOptions & getLangOpts() const
void setPrintingPolicy(const clang::PrintingPolicy &Policy)
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.
@ 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...
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 and virtual file system.
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::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
void setVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
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...
CommentOptions CommentOpts
Options for parsing comments.
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)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
SourceManager & getSourceManager() const
FileManager & getFileManager() const
void Initialize(const TargetInfo &Target, const TargetInfo *AuxTarget=nullptr)
Initialize the preprocessor using information about the target.
DiagnosticsEngine & getDiagnostics() const
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.