23#include "clang/Config/config.h"
44#include "llvm/ADT/IntrusiveRefCntPtr.h"
45#include "llvm/ADT/STLExtras.h"
46#include "llvm/ADT/ScopeExit.h"
47#include "llvm/ADT/Statistic.h"
48#include "llvm/Config/llvm-config.h"
49#include "llvm/Plugins/PassPlugin.h"
50#include "llvm/Support/AdvisoryLock.h"
51#include "llvm/Support/BuryPointer.h"
52#include "llvm/Support/CrashRecoveryContext.h"
53#include "llvm/Support/Errc.h"
54#include "llvm/Support/FileSystem.h"
55#include "llvm/Support/MemoryBuffer.h"
56#include "llvm/Support/Path.h"
57#include "llvm/Support/Signals.h"
58#include "llvm/Support/TimeProfiler.h"
59#include "llvm/Support/Timer.h"
60#include "llvm/Support/VirtualFileSystem.h"
61#include "llvm/Support/VirtualOutputBackends.h"
62#include "llvm/Support/VirtualOutputError.h"
63#include "llvm/Support/raw_ostream.h"
64#include "llvm/TargetParser/Host.h"
71CompilerInstance::CompilerInstance(
72 std::shared_ptr<CompilerInvocation> Invocation,
73 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
76 Invocation(
std::move(Invocation)),
78 ThePCHContainerOperations(
std::move(PCHContainerOps)) {
79 assert(this->Invocation &&
"Invocation must not be null");
83 assert(OutputFiles.empty() &&
"Still output files in flight?");
87 return (BuildGlobalModuleIndex ||
88 (TheASTReader && TheASTReader->isGlobalIndexUnavailable() &&
90 !DisableGeneratingGlobalModuleIndex;
95 Diagnostics = std::move(
Value);
99 OwnedVerboseOutputStream.reset();
100 VerboseOutputStream = &
Value;
104 OwnedVerboseOutputStream.swap(
Value);
105 VerboseOutputStream = OwnedVerboseOutputStream.get();
123 auto &TO = AuxTargetOpts = std::make_unique<TargetOptions>();
164 assert(
Value ==
nullptr ||
166 FileMgr = std::move(
Value);
171 SourceMgr = std::move(
Value);
175 PP = std::move(
Value);
180 Context = std::move(
Value);
182 if (Context && Consumer)
191 Consumer = std::move(
Value);
193 if (Context && Consumer)
198 CompletionConsumer.reset(
Value);
202 return std::move(TheSema);
209 assert(ModCache.get() == &Reader->getModuleManager().getModuleCache() &&
210 "Expected ASTReader to use the same PCM cache");
211 TheASTReader = std::move(Reader);
214std::shared_ptr<ModuleDependencyCollector>
216 return ModuleDepCollector;
220 std::shared_ptr<ModuleDependencyCollector> Collector) {
221 ModuleDepCollector = std::move(Collector);
225 std::shared_ptr<ModuleDependencyCollector> MDC) {
228 for (
auto &Name : HeaderMapFileNames)
233 std::shared_ptr<ModuleDependencyCollector> MDC) {
240 auto PCHDir =
FileMgr.getOptionalDirectoryRef(PCHInclude);
242 MDC->addFile(PCHInclude);
248 llvm::sys::path::native(PCHDir->getName(), DirNative);
249 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
251 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
252 Dir != DirEnd && !EC; Dir.increment(EC)) {
261 MDC->addFile(Dir->path());
266 std::shared_ptr<ModuleDependencyCollector> MDC) {
270 if (
auto *RedirectingVFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&VFS))
271 llvm::vfs::collectVFSEntries(*RedirectingVFS, VFSEntries);
274 for (
auto &E : VFSEntries)
275 MDC->addFile(E.VPath, E.RPath);
289 llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(std::move(VFS));
297 std::unique_ptr<raw_ostream> StreamOwner;
298 raw_ostream *OS = &llvm::errs();
301 auto FileOS = std::make_unique<llvm::raw_fd_ostream>(
303 llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
305 Diags.
Report(diag::warn_fe_cc_log_diagnostics_failure)
308 FileOS->SetUnbuffered();
310 StreamOwner = std::move(FileOS);
315 auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
316 std::move(StreamOwner));
330 StringRef OutputFile) {
331 auto SerializedConsumer =
336 Diags.
takeClient(), std::move(SerializedConsumer)));
339 Diags.
getClient(), std::move(SerializedConsumer)));
344 bool ShouldOwnClient) {
353 auto Diags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(
359 Diags->setClient(Client, ShouldOwnClient);
366 if (Opts.VerifyDiagnostics)
385 assert(VFS &&
"CompilerInstance needs a VFS for creating FileManager");
392 assert(Diagnostics &&
"DiagnosticsEngine needed for creating SourceManager");
393 assert(FileMgr &&
"FileManager needed for creating SourceManager");
394 SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
getDiagnostics(),
408 FileMgr.getVirtualFileRef(RB.first, RB.second->getBufferSize(), 0);
415 SourceMgr.overrideFileContents(FromFile, RB.second->getMemBufferRef());
417 SourceMgr.overrideFileContents(
418 FromFile, std::unique_ptr<llvm::MemoryBuffer>(RB.second));
426 Diags.
Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
436 SourceMgr.overrideFileContents(FromFile, *ToFile);
439 SourceMgr.setOverridenFilesKeepOriginalName(
449 TheASTReader.reset();
455 PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOpts(),
464 PP->createPreprocessingRecord();
468 PP->getFileManager(), PPOpts);
477 const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple();
478 if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA &&
479 PP->getAuxTargetInfo())
480 HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple();
483 PP->getLangOpts(), *HeaderSearchTriple);
487 if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
489 PP->getHeaderSearchInfo().setModuleHash(ModuleHash);
490 PP->getHeaderSearchInfo().setModuleCachePath(
505 ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
511 if (ModuleDepCollector) {
522 for (
auto &Listener : DependencyCollectors)
523 Listener->attachToPreprocessor(*PP);
530 if (OutputPath ==
"-")
543 if (GetDependencyDirectives)
544 PP->setDependencyDirectivesGetter(*GetDependencyDirectives);
548 assert(FileMgr &&
"Specific module cache path requires a FileManager");
553 SpecificModuleCache);
555 llvm::sys::path::append(SpecificModuleCache, ModuleHash);
556 return std::string(SpecificModuleCache);
563 auto Context = llvm::makeIntrusiveRefCnt<ASTContext>(
564 getLangOpts(), PP.getSourceManager(), PP.getIdentifierTable(),
565 PP.getSelectorTable(), PP.getBuiltinInfo(), PP.TUKind);
582 void ReadModuleName(StringRef ModuleName)
override {
585 LoadedModules.push_back(ModuleName.str());
590 for (
const std::string &LoadedModule : LoadedModules)
593 LoadedModules.clear();
596 void markAllUnavailable() {
597 for (
const std::string &LoadedModule : LoadedModules) {
600 M->HasIncompatibleModuleFile =
true;
604 SmallVector<Module *, 2> Stack;
606 while (!Stack.empty()) {
607 Module *Current = Stack.pop_back_val();
611 llvm::append_range(Stack, SubmodulesRange);
615 LoadedModules.clear();
622 bool AllowPCHWithCompilerErrors,
void *DeserializationListener,
623 bool OwnDeserializationListener) {
630 DeserializationListener, OwnDeserializationListener,
Preamble,
635 StringRef Path, StringRef Sysroot,
640 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
641 ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
642 void *DeserializationListener,
bool OwnDeserializationListener,
643 bool Preamble,
bool UseGlobalModuleIndex) {
645 PP.getHeaderSearchInfo().getHeaderSearchOpts();
647 auto Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
648 PP, ModCache, &Context, PCHContainerRdr, CodeGenOpts, Extensions,
649 Sysroot.empty() ?
"" : Sysroot.data(), DisableValidation,
650 AllowPCHWithCompilerErrors,
false,
657 Context.setExternalSource(Reader);
659 Reader->setDeserializationListener(
661 OwnDeserializationListener);
663 for (
auto &Listener : DependencyCollectors)
664 Listener->attachToASTReader(*Reader);
666 auto Listener = std::make_unique<ReadModuleNames>(PP);
667 auto &ListenerRef = *Listener;
669 std::move(Listener));
671 switch (Reader->ReadAST(Path,
679 PP.setPredefines(Reader->getSuggestedPredefines());
680 ListenerRef.registerAll();
696 ListenerRef.markAllUnavailable();
697 Context.setExternalSource(
nullptr);
723 if (!CompletionConsumer) {
736 timerGroup.reset(
new llvm::TimerGroup(
"clang",
"Clang time report"));
737 FrontendTimer.reset(
new llvm::Timer(
"frontend",
"Front end", *timerGroup));
757 TUKind, CompletionConsumer));
763 if (ExternalSemaSrc) {
764 TheSema->addExternalSource(ExternalSemaSrc);
765 ExternalSemaSrc->InitializeSema(*TheSema);
771 (void)TheSema->APINotes.loadCurrentModuleAPINotes(
783 for (
auto &O : OutputFiles)
784 llvm::handleAllErrors(
786 [&](
const llvm::vfs::TempFileOutputError &E) {
787 getDiagnostics().Report(diag::err_unable_to_rename_temp)
788 << E.getTempPath() << E.getOutputPath()
789 << E.convertToErrorCode().message();
791 [&](
const llvm::vfs::OutputError &E) {
792 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
793 << E.getOutputPath() << E.convertToErrorCode().message();
795 [&](
const llvm::ErrorInfoBase &EIB) {
796 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
797 << O.getPath() << EIB.message();
801 if (DeleteBuiltModules) {
802 for (
auto &
Module : BuiltModules)
803 llvm::sys::fs::remove(
Module.second);
804 BuiltModules.clear();
809 bool Binary, StringRef InFile, StringRef Extension,
bool RemoveFileOnSignal,
810 bool CreateMissingDirectories,
bool ForceUseTemporary) {
812 std::optional<SmallString<128>> PathStorage;
813 if (OutputPath.empty()) {
814 if (InFile ==
"-" || Extension.empty()) {
817 PathStorage.emplace(InFile);
818 llvm::sys::path::replace_extension(*PathStorage, Extension);
819 OutputPath = *PathStorage;
825 CreateMissingDirectories);
829 return std::make_unique<llvm::raw_null_ostream>();
836 assert(!OutputMgr &&
"Already has an output manager");
837 OutputMgr = std::move(NewOutputs);
841 assert(!OutputMgr &&
"Already has an output manager");
842 OutputMgr = llvm::makeIntrusiveRefCnt<llvm::vfs::OnDiskOutputBackend>();
856std::unique_ptr<raw_pwrite_stream>
858 bool RemoveFileOnSignal,
bool UseTemporary,
859 bool CreateMissingDirectories) {
861 createOutputFileImpl(OutputPath,
Binary, RemoveFileOnSignal, UseTemporary,
862 CreateMissingDirectories);
864 return std::move(*OS);
866 << OutputPath << errorToErrorCode(OS.takeError()).message();
871CompilerInstance::createOutputFileImpl(StringRef OutputPath,
bool Binary,
872 bool RemoveFileOnSignal,
874 bool CreateMissingDirectories) {
875 assert((!CreateMissingDirectories || UseTemporary) &&
876 "CreateMissingDirectories is only allowed when using temporary files");
880 std::optional<SmallString<128>> AbsPath;
881 if (OutputPath !=
"-" && !llvm::sys::path::is_absolute(OutputPath)) {
883 "File Manager is required to fix up relative path.\n");
885 AbsPath.emplace(OutputPath);
887 OutputPath = *AbsPath;
895 .setDiscardOnSignal(RemoveFileOnSignal)
896 .setAtomicWrite(UseTemporary)
897 .setImplyCreateDirectories(UseTemporary && CreateMissingDirectories));
899 return O.takeError();
901 O->discardOnDestroy([](llvm::Error E) { consumeError(std::move(E)); });
902 OutputFiles.push_back(std::move(*O));
903 return OutputFiles.back().createProxy();
925 SourceMgr.setMainFileID(SourceMgr.createFileID(Input.
getBuffer(), Kind));
926 assert(SourceMgr.getMainFileID().isValid() &&
927 "Couldn't establish MainFileID!");
931 StringRef InputFile = Input.
getFile();
934 auto FileOrErr = InputFile ==
"-"
936 : FileMgr.getFileRef(InputFile,
true);
938 auto EC = llvm::errorToErrorCode(FileOrErr.takeError());
939 if (InputFile !=
"-")
940 Diags.
Report(diag::err_fe_error_reading) << InputFile << EC.message();
942 Diags.
Report(diag::err_fe_error_reading_stdin) << EC.message();
946 SourceMgr.setMainFileID(
949 assert(SourceMgr.getMainFileID().isValid() &&
950 "Couldn't establish MainFileID!");
957 assert(
hasDiagnostics() &&
"Diagnostics engine is not initialized!");
959 assert(!
getFrontendOpts().ShowVersion &&
"Client must handle '-version'!");
966 auto FinishDiagnosticClient = llvm::make_scope_exit([&]() {
985 OS <<
"clang -cc1 version " CLANG_VERSION_STRING <<
" based upon LLVM "
986 << LLVM_VERSION_STRING <<
" default target "
987 << llvm::sys::getDefaultTargetTriple() <<
"\n";
990 llvm::EnableStatistics(
false);
1004 if (llvm::Error Err = Act.
Execute()) {
1005 consumeError(std::move(Err));
1018 llvm::PrintStatistics(OS);
1021 if (!StatsFile.empty()) {
1022 llvm::sys::fs::OpenFlags FileFlags = llvm::sys::fs::OF_TextWithCRLF;
1024 FileFlags |= llvm::sys::fs::OF_Append;
1027 std::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, FileFlags);
1030 << StatsFile << EC.message();
1032 llvm::PrintStatisticsJSON(*StatS);
1051 OS << NumWarnings <<
" warning" << (NumWarnings == 1 ?
"" :
"s");
1052 if (NumWarnings && NumErrors)
1055 OS << NumErrors <<
" error" << (NumErrors == 1 ?
"" :
"s");
1056 if (NumWarnings || NumErrors) {
1060 OS <<
" when compiling for host";
1062 OS <<
" when compiling for "
1075 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &
Error))
1082 if (
auto PassPlugin = llvm::PassPlugin::Load(Path)) {
1083 PassPlugins.emplace_back(std::make_unique<llvm::PassPlugin>(*PassPlugin));
1086 << Path <<
toString(PassPlugin.takeError());
1091 for (
const FrontendPluginRegistry::entry &Plugin :
1092 FrontendPluginRegistry::entries()) {
1093 std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
1105 if (LangOpts.OpenCL)
1114std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
1116 StringRef OriginalModuleMapFile, StringRef ModuleFileName,
1117 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1119 auto Invocation = std::make_shared<CompilerInvocation>(
getInvocation());
1121 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1125 Invocation->resetNonModularOptions();
1129 HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
1130 llvm::erase_if(PPOpts.
Macros,
1131 [&HSOpts](
const std::pair<std::string, bool> &def) {
1132 StringRef MacroDef = def.first;
1133 return HSOpts.ModulesIgnoreMacros.contains(
1134 llvm::CachedHashString(MacroDef.split(
'=').first));
1138 Invocation->getLangOpts().ModuleName =
1142 Invocation->getLangOpts().CurrentModule = std::string(ModuleName);
1147 FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
1148 FrontendOpts.
OutputFile = ModuleFileName.str();
1155 FrontendOpts.
Inputs = {std::move(Input)};
1160 DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts();
1162 DiagOpts.VerifyDiagnostics = 0;
1164 "Module hash mismatch!");
1170 auto InstancePtr = std::make_unique<CompilerInstance>(
1172 auto &Instance = *InstancePtr;
1174 auto &
Inv = Instance.getInvocation();
1176 if (ThreadSafeConfig) {
1177 Instance.setVirtualFileSystem(ThreadSafeConfig->getVFS());
1178 Instance.createFileManager();
1184 Instance.createFileManager();
1187 if (ThreadSafeConfig) {
1188 Instance.createDiagnostics(&ThreadSafeConfig->getDiagConsumer(),
1191 Instance.createDiagnostics(
1196 Instance.getDiagnostics().setSuppressSystemWarnings(
false);
1198 Instance.createSourceManager();
1199 SourceManager &SourceMgr = Instance.getSourceManager();
1201 if (ThreadSafeConfig) {
1207 SourceMgr.pushModuleBuildStack(
1212 Instance.FailedModules = FailedModules;
1214 if (GetDependencyDirectives)
1215 Instance.GetDependencyDirectives =
1216 GetDependencyDirectives->cloneFor(Instance.getFileManager());
1218 if (ThreadSafeConfig) {
1219 Instance.setModuleDepCollector(ThreadSafeConfig->getModuleDepCollector());
1226 Inv.getDependencyOutputOpts() = DependencyOutputOptions();
1232 StringRef ModuleName,
1233 StringRef ModuleFileName,
1234 CompilerInstance &Instance) {
1235 llvm::TimeTraceScope TimeScope(
"Module Compile", ModuleName);
1239 if (
getModuleCache().getInMemoryModuleCache().isPCMFinal(ModuleFileName)) {
1246 << ModuleName << ModuleFileName;
1250 bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnNewStack(
1265 FailedModules = std::move(Instance.FailedModules);
1270 Instance.setSema(
nullptr);
1271 Instance.setASTConsumer(
nullptr);
1274 Instance.clearOutputFiles(
true);
1285 return !Instance.getDiagnostics().hasErrorOccurred() ||
1286 Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
1291 StringRef Filename = llvm::sys::path::filename(
File.getName());
1293 if (Filename ==
"module_private.map")
1294 llvm::sys::path::append(PublicFilename,
"module.map");
1295 else if (Filename ==
"module.private.modulemap")
1296 llvm::sys::path::append(PublicFilename,
"module.modulemap");
1298 return std::nullopt;
1299 return FileMgr.getOptionalFileRef(PublicFilename);
1304 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1320 while (Loc.
isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) {
1321 ModuleMapFID = SourceMgr.getFileID(Loc);
1322 Loc = SourceMgr.getIncludeLoc(ModuleMapFID);
1326 SourceMgr.getFileEntryRefForID(ModuleMapFID);
1327 assert(ModuleMapFile &&
"Top-level module map with no FileID");
1334 ModuleMapFile = PublicMMFile;
1346 return cloneForModuleCompileImpl(
1347 ImportLoc, ModuleName,
1350 std::move(ThreadSafeConfig));
1358 llvm::sys::path::append(FakeModuleMapFile,
"__inferred_module.map");
1360 std::string InferredModuleMapContent;
1361 llvm::raw_string_ostream OS(InferredModuleMapContent);
1364 auto Instance = cloneForModuleCompileImpl(
1365 ImportLoc, ModuleName,
1368 std::move(ThreadSafeConfig));
1370 std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
1371 llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent);
1372 FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef(
1373 FakeModuleMapFile, InferredModuleMapContent.size(), 0);
1374 Instance->getSourceManager().overrideFileContents(ModuleMapFile,
1375 std::move(ModuleMapBuffer));
1385 bool *OutOfDate,
bool *Missing) {
1396 ModuleLoadCapabilities);
1414 Diags.
Report(ModuleNameLoc, diag::err_module_not_built)
1426 StringRef ModuleFileName) {
1429 ModuleNameLoc,
Module, ModuleFileName);
1433 ModuleFileName, *Instance)) {
1435 diag::err_module_not_built)
1467 Diags.
Report(ModuleNameLoc, diag::remark_module_lock)
1476 if (llvm::Error Err = Lock->tryLock().moveInto(Owned)) {
1480 Diags.
Report(ModuleNameLoc, diag::remark_module_lock_failure)
1483 ModuleNameLoc,
Module, ModuleFileName);
1488 ModuleNameLoc,
Module, ModuleFileName);
1493 switch (Lock->waitForUnlockFor(std::chrono::seconds(90))) {
1494 case llvm::WaitForUnlockResult::Success:
1496 case llvm::WaitForUnlockResult::OwnerDied:
1498 case llvm::WaitForUnlockResult::Timeout:
1502 Diags.
Report(ModuleNameLoc, diag::remark_module_lock_timeout)
1505 Lock->unsafeMaybeUnlock();
1510 bool OutOfDate =
false;
1511 bool Missing =
false;
1513 Module, ModuleFileName, &OutOfDate, &Missing))
1515 if (!OutOfDate && !Missing)
1559 for (
auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
1561 FileID FID = SourceMgr.getFileID(MD->getLocation());
1564 if (
auto *DMD = dyn_cast<DefMacroDirective>(MD))
1565 CmdLineDefinition = DMD->getMacroInfo();
1570 if (CurrentDefinition == CmdLineDefinition) {
1572 }
else if (!CurrentDefinition) {
1575 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1577 auto LatestDef = LatestLocalMD->getDefinition();
1578 assert(LatestDef.isUndefined() &&
1579 "predefined macro went away with no #undef?");
1580 PP.
Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
1583 }
else if (!CmdLineDefinition) {
1586 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1588 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1589 diag::note_module_def_undef_here)
1591 }
else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
1594 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1596 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1597 diag::note_module_def_undef_here)
1605 for (
const StringRef ConMacro : TopModule->
ConfigMacros) {
1620 !
getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
1626 std::string Sysroot = HSOpts.
Sysroot;
1629 std::unique_ptr<llvm::Timer> ReadTimer;
1632 ReadTimer = std::make_unique<llvm::Timer>(
"reading_modules",
1633 "Reading modules", *timerGroup);
1634 TheASTReader = llvm::makeIntrusiveRefCnt<ASTReader>(
1638 Sysroot.empty() ?
"" : Sysroot.c_str(),
1647 TheASTReader->setDeserializationListener(
1654 TheASTReader->InitializeSema(
getSema());
1658 for (
auto &Listener : DependencyCollectors)
1659 Listener->attachToASTReader(*TheASTReader);
1668 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1676 bool ConfigMismatchIsRecoverable =
1681 auto Listener = std::make_unique<ReadModuleNames>(*PP);
1682 auto &ListenerRef = *Listener;
1684 std::move(Listener));
1687 switch (TheASTReader->ReadAST(
1690 &LoadedModuleFile)) {
1694 ListenerRef.registerAll();
1703 ListenerRef.markAllUnavailable();
1715 MS_PrebuiltModulePath,
1716 MS_ModuleBuildPragma
1723 Module *M, StringRef ModuleName, std::string &ModuleFilename,
1724 const std::map<std::string, std::string, std::less<>> &BuiltModules,
1726 assert(ModuleFilename.empty() &&
"Already has a module source?");
1730 auto BuiltModuleIt = BuiltModules.find(ModuleName);
1731 if (BuiltModuleIt != BuiltModules.end()) {
1732 ModuleFilename = BuiltModuleIt->second;
1733 return MS_ModuleBuildPragma;
1743 if (!ModuleFilename.empty())
1744 return MS_PrebuiltModulePath;
1750 return MS_ModuleCache;
1753 return MS_ModuleNotFound;
1762 HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1772 std::string ModuleFilename;
1773 ModuleSource Source =
1775 if (Source == MS_ModuleNotFound) {
1778 << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
1781 if (ModuleFilename.empty()) {
1800 Timer.init(
"loading." + ModuleFilename,
"Loading " + ModuleFilename,
1802 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1803 llvm::TimeTraceScope TimeScope(
"Module Load", ModuleName);
1807 unsigned ARRFlags = Source == MS_ModuleCache
1810 : Source == MS_PrebuiltModulePath
1814 Source == MS_PrebuiltModulePath
1816 : Source == MS_ModuleBuildPragma
1819 ImportLoc, ARRFlags)) {
1823 assert(Source != MS_ModuleCache &&
1824 "missing module, but file loaded from cache");
1828 M = HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1832 if (
auto ModuleFile = FileMgr->getOptionalFileRef(ModuleFilename))
1838 return ModuleLoadResult();
1847 if (Source == MS_PrebuiltModulePath)
1851 diag::warn_module_config_mismatch)
1860 return ModuleLoadResult();
1864 return ModuleLoadResult();
1868 if (Source != MS_ModuleCache) {
1872 return ModuleLoadResult();
1876 assert(M &&
"missing module, but trying to compile for cache");
1880 ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
1881 for (; Pos != PosEnd; ++Pos) {
1882 if (Pos->first == ModuleName)
1886 if (Pos != PosEnd) {
1887 SmallString<256> CyclePath;
1888 for (; Pos != PosEnd; ++Pos) {
1889 CyclePath += Pos->first;
1890 CyclePath +=
" -> ";
1892 CyclePath += ModuleName;
1895 << ModuleName << CyclePath;
1900 if (FailedModules.contains(ModuleName)) {
1902 << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
1910 "undiagnosed error in compileModuleAndReadAST");
1911 FailedModules.insert(ModuleName);
1923 bool IsInclusionDirective) {
1925 StringRef ModuleName = Path[0].getIdentifierInfo()->getName();
1931 if (ImportLoc.
isValid() && LastModuleImportLoc == ImportLoc) {
1933 if (LastModuleImportResult && ModuleName !=
getLangOpts().CurrentModule)
1934 TheASTReader->makeModuleVisible(LastModuleImportResult,
Visibility,
1936 return LastModuleImportResult;
1950 }
else if (ModuleName ==
getLangOpts().CurrentModule) {
1952 Module = PP->getHeaderSearchInfo().lookupModule(
1953 ModuleName, ImportLoc,
true,
1954 !IsInclusionDirective);
1965 ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);
1969 DisableGeneratingGlobalModuleIndex =
true;
1981 bool MapPrivateSubModToTopLevel =
false;
1982 for (
unsigned I = 1, N = Path.size(); I != N; ++I) {
1983 StringRef Name = Path[I].getIdentifierInfo()->getName();
1992 PrivateModule.append(
"_Private");
1995 auto &II = PP->getIdentifierTable().get(
1996 PrivateModule, PP->getIdentifierInfo(
Module->
Name)->getTokenID());
1997 PrivPath.emplace_back(Path[0].getLoc(), &II);
2001 if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, ImportLoc,
true,
2002 !IsInclusionDirective) ||
2004 PP->getHeaderSearchInfo()) != MS_ModuleNotFound)
2007 MapPrivateSubModToTopLevel =
true;
2008 PP->markClangModuleAsAffecting(
Module);
2010 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
2012 diag::warn_no_priv_submodule_use_toplevel)
2015 <<
SourceRange(Path[0].getLoc(), Path[I].getLoc())
2019 diag::note_private_top_level_defined);
2027 unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
2031 Name.edit_distance(SubModule->Name,
2032 true, BestEditDistance);
2033 if (ED <= BestEditDistance) {
2034 if (ED < BestEditDistance) {
2036 BestEditDistance = ED;
2039 Best.push_back(SubModule->Name);
2044 if (Best.size() == 1) {
2046 diag::err_no_submodule_suggest)
2048 << Best[0] <<
SourceRange(Path[0].getLoc(), Path[I - 1].getLoc())
2061 <<
SourceRange(Path[0].getLoc(), Path[I - 1].getLoc());
2080 <<
SourceRange(Path.front().getLoc(), Path.back().getLoc());
2089 <<
SourceRange(Path.front().getLoc(), Path.back().getLoc());
2090 LastModuleImportLoc = ImportLoc;
2104 LastModuleImportLoc = ImportLoc;
2106 return LastModuleImportResult;
2110 StringRef ModuleName,
2114 for (
auto &
C : CleanModuleName)
2122 if (std::error_code EC = llvm::sys::fs::createTemporaryFile(
2123 CleanModuleName,
"pcm", ModuleFileName)) {
2125 << ModuleFileName << EC.message();
2128 std::string ModuleMapFileName = (CleanModuleName +
".map").str();
2135 std::string NullTerminatedSource(Source.str());
2137 auto Other = cloneForModuleCompileImpl(ImportLoc, ModuleName, Input,
2138 StringRef(), ModuleFileName);
2143 ModuleMapFileName, NullTerminatedSource.size(), 0);
2144 Other->getSourceManager().overrideFileContents(
2145 ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
2147 Other->BuiltModules = std::move(BuiltModules);
2148 Other->DeleteBuiltModules =
false;
2153 BuiltModules = std::move(
Other->BuiltModules);
2156 BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName);
2157 llvm::sys::RemoveFileOnSignal(ModuleFileName);
2169 TheASTReader->makeModuleVisible(Mod,
Visibility, ImportLoc);
2174 if (
getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
2183 TheASTReader->loadGlobalIndex();
2188 llvm::sys::fs::create_directories(
2197 consumeError(std::move(Err));
2200 TheASTReader->resetForReload();
2201 TheASTReader->loadGlobalIndex();
2202 GlobalIndex = TheASTReader->getGlobalIndex();
2206 if (!HaveFullGlobalModuleIndex && GlobalIndex && !
buildingModule()) {
2208 bool RecreateIndex =
false;
2211 Module *TheModule = I->second;
2215 Path.emplace_back(TriggerLoc,
2217 std::reverse(Path.begin(), Path.end());
2220 RecreateIndex =
true;
2223 if (RecreateIndex) {
2228 consumeError(std::move(Err));
2231 TheASTReader->resetForReload();
2232 TheASTReader->loadGlobalIndex();
2233 GlobalIndex = TheASTReader->getGlobalIndex();
2235 HaveFullGlobalModuleIndex =
true;
2269 ExternalSemaSrc = std::move(ESS);
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
static void collectVFSEntries(CompilerInstance &CI, std::shared_ptr< ModuleDependencyCollector > MDC)
static bool EnableCodeCompletion(Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column)
static bool compileModuleAndReadASTImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName)
Compile a module in a separate compiler instance and read the AST, returning true if the module compi...
static void SetupSerializedDiagnostics(DiagnosticOptions &DiagOpts, DiagnosticsEngine &Diags, StringRef OutputFile)
static bool compileModuleAndReadASTBehindLock(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName)
Compile a module in a separate compiler instance and read the AST, returning true if the module compi...
static Language getLanguageFromOptions(const LangOptions &LangOpts)
Determine the appropriate source input kind based on language options.
static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, Module *Mod, SourceLocation ImportLoc)
Diagnose differences between the current definition of the given configuration macro and the definiti...
static void collectHeaderMaps(const HeaderSearch &HS, std::shared_ptr< ModuleDependencyCollector > MDC)
static ModuleSource selectModuleSource(Module *M, StringRef ModuleName, std::string &ModuleFilename, const std::map< std::string, std::string, std::less<> > &BuiltModules, HeaderSearch &HS)
Select a source for loading the named module and compute the filename to load it from.
static bool readASTAfterCompileModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName, bool *OutOfDate, bool *Missing)
Read the AST right after compiling the module.
static void InitializeFileRemapping(DiagnosticsEngine &Diags, SourceManager &SourceMgr, FileManager &FileMgr, const PreprocessorOptions &InitOpts)
static void collectIncludePCH(CompilerInstance &CI, std::shared_ptr< ModuleDependencyCollector > MDC)
static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File, FileManager &FileMgr)
static void checkConfigMacros(Preprocessor &PP, Module *M, SourceLocation ImportLoc)
static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName)
Compile a module in a separate compiler instance and read the AST, returning true if the module compi...
static void SetUpDiagnosticLog(DiagnosticOptions &DiagOpts, const CodeGenOptions *CodeGenOpts, DiagnosticsEngine &Diags)
Defines the clang::FileManager interface and associated types.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the SourceManager interface.
Defines utilities for dealing with stack allocation and stack space.
Defines version macros and version-related utility functions for Clang.
virtual void Initialize(ASTContext &Context)
Initialize - This is called to initialize the consumer, providing the ASTContext.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void setASTMutationListener(ASTMutationListener *Listener)
Attach an AST mutation listener to the AST context.
void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)
Attach an external AST source to the AST context.
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
Abstract interface for callback invocations by the ASTReader.
RAII object to temporarily add an AST callback listener.
@ ARR_Missing
The client can handle an AST file that cannot load because it is missing.
@ ARR_None
The client can't handle any AST loading failures.
@ ARR_ConfigurationMismatch
The client can handle an AST file that cannot load because it's compiled configuration doesn't match ...
@ ARR_OutOfDate
The client can handle an AST file that cannot load because it is out-of-date relative to its input fi...
@ ARR_TreatModuleWithErrorsAsOutOfDate
If a module file is marked with errors treat it as out-of-date so the caller can rebuild it.
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.
ASTReadResult
The result of reading the control block of an AST file, which can fail for various reasons.
@ 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.
ChainedDiagnosticConsumer - Chain two diagnostic clients so that diagnostics go to the first client a...
Abstract interface for a consumer of code-completion information.
Options controlling the behavior of code completion.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string DwarfDebugFlags
The string to embed in the debug information for the compile unit, if non-empty.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
bool hasOutputManager() const
void createPCHExternalASTSource(StringRef Path, DisableValidationForModuleKind DisableValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener, bool OwnDeserializationListener)
Create an external AST source to read a PCH file and attach it to the AST context.
DiagnosticConsumer & getDiagnosticClient() const
~CompilerInstance() override
void createPreprocessor(TranslationUnitKind TUKind)
Create the preprocessor, using the invocation, file, and source managers, and replace any existing on...
bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
Check global module index for missing imports.
void setOutputManager(IntrusiveRefCntPtr< llvm::vfs::OutputBackend > NewOutputs)
Set the output manager.
void createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
Create the diagnostics engine using the invocation's diagnostic options and replace any existing one ...
DependencyOutputOptions & getDependencyOutputOpts()
bool hasFileManager() const
TargetInfo * getAuxTarget() const
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
GlobalModuleIndex * loadGlobalModuleIndex(SourceLocation TriggerLoc) override
Load, create, or return global module.
raw_ostream & getVerboseOutputStream()
Get the current stream for verbose output.
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false)
Create the default output file (from the invocation's options) and add it to the list of tracked outp...
void setExternalSemaSource(IntrusiveRefCntPtr< ExternalSemaSource > ESS)
bool compileModule(SourceLocation ImportLoc, StringRef ModuleName, StringRef ModuleFileName, CompilerInstance &Instance)
Compile a module file for the given module, using the options provided by the importing compiler inst...
std::string getSpecificModuleCachePath()
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) override
Attempt to load the given module.
FileSystemOptions & getFileSystemOpts()
bool InitializeSourceManager(const FrontendInputFile &Input)
InitializeSourceManager - Initialize the source manager to set InputFile as the main file.
void createFileManager()
Create the file manager and replace any existing one with it.
FileManager & getFileManager() const
Return the current file manager to the caller.
void setBuildGlobalModuleIndex(bool Build)
Set the flag indicating whether we should (re)build the global module index.
void createOutputManager()
Create an output manager.
std::unique_ptr< Sema > takeSema()
void printDiagnosticStats()
At the end of a compilation, print the number of warnings/errors.
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
setASTConsumer - Replace the current AST consumer; the compiler instance takes ownership of Value.
PreprocessorOutputOptions & getPreprocessorOutputOpts()
IntrusiveRefCntPtr< FileManager > getFileManagerPtr() const
ModuleCache & getModuleCache() const
IntrusiveRefCntPtr< ASTReader > getASTReader() const
void setTarget(TargetInfo *Value)
Replace the current Target.
void setModuleDepCollector(std::shared_ptr< ModuleDependencyCollector > Collector)
void addDependencyCollector(std::shared_ptr< DependencyCollector > Listener)
void createASTContext()
Create the AST context.
std::unique_ptr< raw_pwrite_stream > createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal, bool UseTemporary, bool CreateMissingDirectories=false)
Create a new output file, optionally deriving the output path name, and add it to the list of tracked...
bool hasASTContext() const
void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName, StringRef Source) override
Attempt to create the given module from the specified source buffer.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext & getASTContext() const
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
void LoadRequestedPlugins()
Load the list of plugins requested in the FrontendOptions.
TargetOptions & getTargetOpts()
void createVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS=llvm::vfs::getRealFileSystem(), DiagnosticConsumer *DC=nullptr)
Create a virtual file system instance based on the invocation.
void setASTReader(IntrusiveRefCntPtr< ASTReader > Reader)
FrontendOptions & getFrontendOpts()
std::shared_ptr< ModuleDependencyCollector > getModuleDepCollector() const
bool hasDiagnostics() const
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
std::unique_ptr< CompilerInstance > cloneForModuleCompile(SourceLocation ImportLoc, const Module *Module, StringRef ModuleFileName, std::optional< ThreadSafeCloneConfig > ThreadSafeConfig=std::nullopt)
Creates a new CompilerInstance for compiling a module.
void setSourceManager(llvm::IntrusiveRefCntPtr< SourceManager > Value)
setSourceManager - Replace the current source manager.
void setASTContext(llvm::IntrusiveRefCntPtr< ASTContext > Value)
setASTContext - Replace the current AST context.
HeaderSearchOptions & getHeaderSearchOpts()
void createFrontendTimer()
Create the frontend timer and replace any existing one with it.
void createSourceManager()
Create the source manager and replace any existing one with it.
CompilerInvocation & getInvocation()
void setVerboseOutputStream(raw_ostream &Value)
Replace the current stream for verbose output.
PreprocessorOptions & getPreprocessorOpts()
ASTConsumer & getASTConsumer() const
void setFileManager(IntrusiveRefCntPtr< FileManager > Value)
Replace the current file manager.
TargetInfo & getTarget() const
llvm::vfs::OutputBackend & getOutputManager()
llvm::vfs::FileSystem & getVirtualFileSystem() const
void createCodeCompletionConsumer()
Create a code completion consumer using the invocation; note that this will cause the source manager ...
void setCodeCompletionConsumer(CodeCompleteConsumer *Value)
setCodeCompletionConsumer - Replace the current code completion consumer; the compiler instance takes...
bool ExecuteAction(FrontendAction &Act)
ExecuteAction - Execute the provided action against the compiler's CompilerInvocation object.
std::shared_ptr< PCHContainerOperations > getPCHContainerOperations() const
void clearOutputFiles(bool EraseFiles)
clearOutputFiles - Clear the output file list.
DiagnosticOptions & getDiagnosticOpts()
LangOptions & getLangOpts()
llvm::vfs::OutputBackend & getOrCreateOutputManager()
CodeGenOptions & getCodeGenOpts()
SourceManager & getSourceManager() const
Return the current source manager.
void setDiagnostics(llvm::IntrusiveRefCntPtr< DiagnosticsEngine > Value)
setDiagnostics - Replace the current diagnostics engine.
bool shouldBuildGlobalModuleIndex() const
Indicates whether we should (re)build the global module index.
bool hasSourceManager() const
bool hasASTConsumer() const
APINotesOptions & getAPINotesOpts()
std::unique_ptr< raw_pwrite_stream > createNullOutputFile()
void setAuxTarget(TargetInfo *Value)
Replace the current AuxTarget.
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, SourceLocation ImportLoc) override
Make the given module visible.
bool loadModuleFile(StringRef FileName, serialization::ModuleFile *&LoadedModuleFile)
bool hasPreprocessor() const
void setPreprocessor(std::shared_ptr< Preprocessor > Value)
Replace the current preprocessor.
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
LangOptions & getLangOpts()
Mutable getters.
FrontendOptions & getFrontendOpts()
std::string getModuleHash() const
Retrieve a module hash string that is suitable for uniquely identifying the conditions under which th...
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
ShowIncludesDestination ShowIncludesDest
Destination of cl.exe style /showIncludes info.
std::string DOTOutputFile
The file to write GraphViz-formatted header dependencies to.
std::string ModuleDependencyOutputDir
The directory to copy module dependencies to when collecting them.
std::string OutputFile
The file to write dependency output to.
std::string HeaderIncludeOutputFile
The file to write header include output to.
unsigned ShowHeaderIncludes
Show header inclusions (-H).
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
unsigned getNumErrors() const
virtual void finish()
Callback to inform the diagnostic client that processing of all source files has ended.
unsigned getNumWarnings() const
static llvm::IntrusiveRefCntPtr< DiagnosticIDs > create()
Options for controlling the compiler diagnostics engine.
std::string DiagnosticLogFile
The file to log diagnostic output to.
std::vector< std::string > SystemHeaderWarningsModules
The list of -Wsystem-headers-in-module=... options used to override whether -Wsystem-headers is enabl...
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool hasErrorOccurred() const
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
std::unique_ptr< DiagnosticConsumer > takeClient()
Return the current diagnostic client along with ownership of that client.
DiagnosticConsumer * getClient()
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
bool ownsClient() const
Determine whether this DiagnosticsEngine object own its client.
StringRef getName() const
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
StringRef getNameAsRequested() const
The name of this FileEntry, as originally requested without applying any remappings for VFS 'use-exte...
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.
void AddStats(const FileManager &Other)
Import statistics from a child FileManager and add them to this current FileManager.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
static bool fixupRelativePath(const FileSystemOptions &FileSystemOpts, SmallVectorImpl< char > &Path)
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code 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...
bool PrepareToExecute(CompilerInstance &CI)
Prepare the action to execute on the given compiler instance.
llvm::Error Execute()
Set the source manager's main input file, and run the action.
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
virtual bool isModelParsingAction() const
Is this action invoked on a model file?
FrontendOptions - Options for controlling the behavior of the frontend.
unsigned BuildingImplicitModule
Whether we are performing an implicit module build.
unsigned AllowPCMWithCompilerErrors
Output (and read) PCM files regardless of compiler errors.
unsigned BuildingImplicitModuleUsesLock
Whether to use a filesystem lock when building implicit modules.
unsigned ModulesShareFileManager
Whether to share the FileManager when building modules.
std::optional< std::string > AuxTargetCPU
Auxiliary target CPU for CUDA/HIP compilation.
std::string StatsFile
Filename to write statistics to.
std::string OutputFile
The output file, if any.
std::string ActionName
The name of the action to run when using a plugin action.
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
std::string OriginalModuleMap
When the input is a module map, the original module map file from which that map was inferred,...
unsigned GenerateGlobalModuleIndex
Whether we can generate the global module index if needed.
unsigned DisableFree
Disable memory freeing on exit.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
frontend::ActionKind ProgramAction
The frontend action to perform.
std::optional< std::vector< std::string > > AuxTargetFeatures
Auxiliary target features for CUDA/HIP compilation.
A global index for a set of module files, providing information about the identifiers within those mo...
llvm::SmallPtrSet< ModuleFile *, 4 > HitSet
A set of module files in which we found a result.
bool lookupIdentifier(llvm::StringRef Name, HitSet &Hits)
Look for all of the module files with information about the given identifier, e.g....
static llvm::Error writeIndex(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, llvm::StringRef Path)
Write a global index into the given.
One of these records is kept for each identifier that is lexed.
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
@ FPE_Default
Used internally to represent initial unspecified value.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Encapsulates the data about a macro definition (e.g.
The module cache used for compiling modules implicitly.
virtual void prepareForGetLock(StringRef ModuleFilename)=0
May perform any work that only needs to be performed once for multiple calls getLock() with the same ...
virtual void updateModuleTimestamp(StringRef ModuleFilename)=0
Updates the timestamp denoting the last time inputs of the module file were validated.
virtual std::unique_ptr< llvm::AdvisoryLock > getLock(StringRef ModuleFilename)=0
Returns lock for the given module file. The lock is initially unlocked.
Describes the result of attempting to load a module.
bool buildingModule() const
Returns true if this instance is building a module.
ModuleLoader(bool BuildingModule=false)
llvm::StringMap< Module * >::const_iterator module_iterator
module_iterator module_begin() const
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
std::optional< Module * > getCachedModuleLoad(const IdentifierInfo &II)
Return a cached module load.
module_iterator module_end() const
FileID getContainingModuleMapFileID(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
void cacheModuleLoad(const IdentifierInfo &II, Module *M)
Cache a module load. M might be nullptr.
Module * findOrLoadModule(StringRef Name)
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
unsigned IsUnimportable
Whether this module has declared itself unimportable, either because it's missing a requirement from ...
NameVisibilityKind
Describes the visibility of the various names within a particular module.
@ Hidden
All of the names in this module are hidden.
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
SourceLocation DefinitionLoc
The location of the module definition.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
std::string Name
The name of this module.
llvm::iterator_range< submodule_iterator > submodules()
OptionalDirectoryEntryRef Directory
The build directory of this module.
unsigned IsFromModuleFile
Whether this module was loaded from a module file.
unsigned HasIncompatibleModuleFile
Whether we tried and failed to load a module file for this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
unsigned IsAvailable
Whether this module is available in the current translation unit.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
OptionalFileEntryRef getASTFile() const
The serialized AST file for this module, if one was created.
This abstract interface provides operations for unwrapping containers for serialized ASTs (precompile...
@ ReplaceAction
Replace the main action.
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::vector< std::pair< std::string, std::string > > RemappedFiles
The set of file remappings, which take existing files on the system (the first part of each pair) and...
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.
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
DisableValidationForModuleKind DisablePCHOrModuleValidation
Whether to disable most of the normal validation performed on precompiled headers and module files.
std::vector< std::pair< std::string, bool > > Macros
std::vector< std::pair< std::string, llvm::MemoryBuffer * > > RemappedFileBuffers
The set of file-to-buffer remappings, which take existing files on the system (the first part of each...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
MacroDirective * getLocalMacroDirectiveHistory(const IdentifierInfo *II) const
Given an identifier, return the latest non-imported macro directive for that identifier.
bool SetCodeCompletionPoint(FileEntryRef File, unsigned Line, unsigned Column)
Specify the point at which code-completion will be performed.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
FileManager & getFileManager() const
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
HeaderSearch & getHeaderSearchInfo() const
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
A simple code-completion consumer that prints the results it receives in a simple format.
Sema - This implements semantic analysis and AST building for C.
ASTReaderListenter implementation to set SuggestedPredefines of ASTReader which is required to use a ...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
ModuleBuildStack getModuleBuildStack() const
Retrieve the module build stack.
A trivial tuple used to represent a source range.
CharacteristicKind getFileCharacteristic() const
Return whether this is a system header or not.
This is a discriminated union of FileInfo and ExpansionInfo.
const FileInfo & getFile() const
Exposes information about the current target.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, TargetOptions &Opts)
Construct a target for the given options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual void setAuxTarget(const TargetInfo *Aux)
void noSignedCharForObjCBool()
virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, const TargetInfo *Aux)
Set forced language options.
std::string CPU
If given, the name of the target CPU to generate code for.
VerifyDiagnosticConsumer - Create a diagnostic client which will use markers in the input source to c...
Information about a module that has been loaded by the ASTReader.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
@ HeaderSearch
Remove unused header search paths including header maps.
@ PluginAction
Run a plugin action,.
@ RewriteObjC
ObjC->C Rewriter.
bool Inv(InterpState &S, CodePtr OpPC)
@ MK_PCH
File is a PCH file treated as such.
@ MK_Preamble
File is a PCH file treated as the preamble.
@ 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.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions &DiagOpts, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
The JSON file list parser is used to communicate input to InstallAPI.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
ArrayRef< std::pair< std::string, FullSourceLoc > > ModuleBuildStack
The stack used when building modules on demand, which is used to provide a link between the source ma...
void ApplyHeaderSearchOptions(HeaderSearch &HS, const HeaderSearchOptions &HSOpts, const LangOptions &Lang, const llvm::Triple &triple)
Apply the header search options to get given HeaderSearch object.
@ Success
Annotation was successful.
void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, const PCHContainerReader &PCHContainerRdr, const FrontendOptions &FEOpts, const CodeGenOptions &CodeGenOpts)
InitializePreprocessor - Initialize the preprocessor getting it and the environment ready to process ...
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
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.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
void normalizeModuleCachePath(FileManager &FileMgr, StringRef Path, SmallVectorImpl< char > &NormalizedPath)
constexpr size_t DesiredStackSize
The amount of stack space that Clang would like to be provided with.
IntrusiveRefCntPtr< ModuleCache > createCrossProcessModuleCache()
Creates new ModuleCache backed by a file system directory that may be operated on by multiple process...
void noteBottomOfStack(bool ForceSet=false)
Call this once on each thread, as soon after starting the thread as feasible, to note the approximate...
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.
void AttachHeaderIncludeGen(Preprocessor &PP, const DependencyOutputOptions &DepOpts, bool ShowAllHeaders=false, StringRef OutputPath={}, bool ShowDepth=true, bool MSStyle=false)
AttachHeaderIncludeGen - Create a header include list generator, and attach it to the given preproces...
DisableValidationForModuleKind
Whether to disable the normal validation performed on precompiled headers and module files when they ...
@ Other
Other implicit parameter.
Visibility
Describes the different kinds of visibility that a declaration may have.
void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, StringRef SysRoot)
AttachDependencyGraphGen - Create a dependency graph generator, and attach it to the given preprocess...
A source location that has been parsed on the command line.