23#include "clang/Config/config.h"
45#include "llvm/ADT/IntrusiveRefCntPtr.h"
46#include "llvm/ADT/STLExtras.h"
47#include "llvm/ADT/ScopeExit.h"
48#include "llvm/ADT/Statistic.h"
49#include "llvm/Config/llvm-config.h"
50#include "llvm/Plugins/PassPlugin.h"
51#include "llvm/Support/AdvisoryLock.h"
52#include "llvm/Support/BuryPointer.h"
53#include "llvm/Support/CrashRecoveryContext.h"
54#include "llvm/Support/Errc.h"
55#include "llvm/Support/FileSystem.h"
56#include "llvm/Support/MemoryBuffer.h"
57#include "llvm/Support/Path.h"
58#include "llvm/Support/Signals.h"
59#include "llvm/Support/TimeProfiler.h"
60#include "llvm/Support/Timer.h"
61#include "llvm/Support/VirtualFileSystem.h"
62#include "llvm/Support/VirtualOutputBackends.h"
63#include "llvm/Support/VirtualOutputError.h"
64#include "llvm/Support/raw_ostream.h"
65#include "llvm/TargetParser/Host.h"
72CompilerInstance::CompilerInstance(
73 std::shared_ptr<CompilerInvocation> Invocation,
74 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
75 std::shared_ptr<ModuleCache> ModCache)
77 Invocation(
std::move(Invocation)),
78 ModCache(ModCache ?
std::move(ModCache)
80 ThePCHContainerOperations(
std::move(PCHContainerOps)) {
81 assert(this->Invocation &&
"Invocation must not be null");
85 assert(OutputFiles.empty() &&
"Still output files in flight?");
89 return (BuildGlobalModuleIndex ||
90 (TheASTReader && TheASTReader->isGlobalIndexUnavailable() &&
92 !DisableGeneratingGlobalModuleIndex;
97 Diagnostics = std::move(
Value);
101 OwnedVerboseOutputStream.reset();
102 VerboseOutputStream = &
Value;
106 OwnedVerboseOutputStream.swap(
Value);
107 VerboseOutputStream = OwnedVerboseOutputStream.get();
125 auto &TO = AuxTargetOpts = std::make_unique<TargetOptions>();
166 assert(
Value ==
nullptr ||
168 FileMgr = std::move(
Value);
173 SourceMgr = std::move(
Value);
177 PP = std::move(
Value);
182 Context = std::move(
Value);
184 if (Context && Consumer)
193 Consumer = std::move(
Value);
195 if (Context && Consumer)
200 CompletionConsumer.reset(
Value);
204 return std::move(TheSema);
211 assert(ModCache.get() == &Reader->getModuleManager().getModuleCache() &&
212 "Expected ASTReader to use the same PCM cache");
213 TheASTReader = std::move(Reader);
216std::shared_ptr<ModuleDependencyCollector>
218 return ModuleDepCollector;
222 std::shared_ptr<ModuleDependencyCollector> Collector) {
223 ModuleDepCollector = std::move(Collector);
227 std::shared_ptr<ModuleDependencyCollector> MDC) {
230 for (
auto &Name : HeaderMapFileNames)
235 std::shared_ptr<ModuleDependencyCollector> MDC) {
242 auto PCHDir =
FileMgr.getOptionalDirectoryRef(PCHInclude);
244 MDC->addFile(PCHInclude);
250 llvm::sys::path::native(PCHDir->getName(), DirNative);
251 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
253 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
254 Dir != DirEnd && !EC; Dir.increment(EC)) {
263 MDC->addFile(Dir->path());
268 std::shared_ptr<ModuleDependencyCollector> MDC) {
272 if (
auto *RedirectingVFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&VFS))
273 llvm::vfs::collectVFSEntries(*RedirectingVFS, VFSEntries);
276 for (
auto &E : VFSEntries)
277 MDC->addFile(E.VPath, E.RPath);
291 llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(std::move(VFS));
299 std::unique_ptr<raw_ostream> StreamOwner;
300 raw_ostream *OS = &llvm::errs();
303 auto FileOS = std::make_unique<llvm::raw_fd_ostream>(
305 llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
307 Diags.
Report(diag::warn_fe_cc_log_diagnostics_failure)
310 FileOS->SetUnbuffered();
312 StreamOwner = std::move(FileOS);
317 auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
318 std::move(StreamOwner));
332 StringRef OutputFile) {
333 auto SerializedConsumer =
338 Diags.
takeClient(), std::move(SerializedConsumer)));
341 Diags.
getClient(), std::move(SerializedConsumer)));
346 bool ShouldOwnClient) {
355 auto Diags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(
361 Diags->setClient(Client, ShouldOwnClient);
368 if (Opts.VerifyDiagnostics)
387 assert(VFS &&
"CompilerInstance needs a VFS for creating FileManager");
394 assert(Diagnostics &&
"DiagnosticsEngine needed for creating SourceManager");
395 assert(FileMgr &&
"FileManager needed for creating SourceManager");
396 SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
getDiagnostics(),
410 FileMgr.getVirtualFileRef(RB.first, RB.second->getBufferSize(), 0);
417 SourceMgr.overrideFileContents(FromFile, RB.second->getMemBufferRef());
419 SourceMgr.overrideFileContents(
420 FromFile, std::unique_ptr<llvm::MemoryBuffer>(RB.second));
428 Diags.
Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
438 SourceMgr.overrideFileContents(FromFile, *ToFile);
441 SourceMgr.setOverridenFilesKeepOriginalName(
451 TheASTReader.reset();
457 PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOpts(),
466 PP->createPreprocessingRecord();
470 PP->getFileManager(), PPOpts);
479 const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple();
480 if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA &&
481 PP->getAuxTargetInfo())
482 HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple();
485 PP->getLangOpts(), *HeaderSearchTriple);
489 if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
493 PP->getHeaderSearchInfo().initializeModuleCachePath(
508 ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
514 if (ModuleDepCollector) {
525 for (
auto &Listener : DependencyCollectors)
526 Listener->attachToPreprocessor(*PP);
533 if (OutputPath ==
"-")
546 if (GetDependencyDirectives)
547 PP->setDependencyDirectivesGetter(*GetDependencyDirectives);
554 auto Context = llvm::makeIntrusiveRefCnt<ASTContext>(
555 getLangOpts(), PP.getSourceManager(), PP.getIdentifierTable(),
556 PP.getSelectorTable(), PP.getBuiltinInfo(), PP.TUKind);
573 void ReadModuleName(StringRef ModuleName)
override {
576 LoadedModules.push_back(ModuleName.str());
581 for (
const std::string &LoadedModule : LoadedModules)
584 LoadedModules.clear();
587 void markAllUnavailable() {
588 for (
const std::string &LoadedModule : LoadedModules) {
591 M->HasIncompatibleModuleFile =
true;
595 SmallVector<Module *, 2> Stack;
597 while (!Stack.empty()) {
598 Module *Current = Stack.pop_back_val();
602 llvm::append_range(Stack, SubmodulesRange);
606 LoadedModules.clear();
613 bool AllowPCHWithCompilerErrors,
void *DeserializationListener,
614 bool OwnDeserializationListener) {
621 DeserializationListener, OwnDeserializationListener,
Preamble,
626 StringRef Path, StringRef Sysroot,
631 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
632 ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
633 void *DeserializationListener,
bool OwnDeserializationListener,
634 bool Preamble,
bool UseGlobalModuleIndex) {
636 PP.getHeaderSearchInfo().getHeaderSearchOpts();
638 auto Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
639 PP, ModCache, &Context, PCHContainerRdr, CodeGenOpts, Extensions,
640 Sysroot.empty() ?
"" : Sysroot.data(), DisableValidation,
641 AllowPCHWithCompilerErrors,
false,
648 Context.setExternalSource(Reader);
650 Reader->setDeserializationListener(
652 OwnDeserializationListener);
654 for (
auto &Listener : DependencyCollectors)
655 Listener->attachToASTReader(*Reader);
657 auto Listener = std::make_unique<ReadModuleNames>(PP);
658 auto &ListenerRef = *Listener;
660 std::move(Listener));
662 switch (Reader->ReadAST(Path,
670 PP.setPredefines(Reader->getSuggestedPredefines());
671 ListenerRef.registerAll();
687 ListenerRef.markAllUnavailable();
688 Context.setExternalSource(
nullptr);
714 if (!CompletionConsumer) {
727 timerGroup.reset(
new llvm::TimerGroup(
"clang",
"Clang time report"));
728 FrontendTimer.reset(
new llvm::Timer(
"frontend",
"Front end", *timerGroup));
748 TUKind, CompletionConsumer));
754 if (ExternalSemaSrc) {
755 TheSema->addExternalSource(ExternalSemaSrc);
756 ExternalSemaSrc->InitializeSema(*TheSema);
762 (void)TheSema->APINotes.loadCurrentModuleAPINotes(
774 for (
auto &O : OutputFiles)
775 llvm::handleAllErrors(
777 [&](
const llvm::vfs::TempFileOutputError &E) {
778 getDiagnostics().Report(diag::err_unable_to_rename_temp)
779 << E.getTempPath() << E.getOutputPath()
780 << E.convertToErrorCode().message();
782 [&](
const llvm::vfs::OutputError &E) {
783 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
784 << E.getOutputPath() << E.convertToErrorCode().message();
786 [&](
const llvm::ErrorInfoBase &EIB) {
787 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
788 << O.getPath() << EIB.message();
792 if (DeleteBuiltModules) {
793 for (
auto &
Module : BuiltModules)
794 llvm::sys::fs::remove(
Module.second);
795 BuiltModules.clear();
800 bool Binary, StringRef InFile, StringRef Extension,
bool RemoveFileOnSignal,
801 bool CreateMissingDirectories,
bool ForceUseTemporary) {
803 std::optional<SmallString<128>> PathStorage;
804 if (OutputPath.empty()) {
805 if (InFile ==
"-" || Extension.empty()) {
808 PathStorage.emplace(InFile);
809 llvm::sys::path::replace_extension(*PathStorage, Extension);
810 OutputPath = *PathStorage;
816 CreateMissingDirectories);
820 return std::make_unique<llvm::raw_null_ostream>();
827 assert(!OutputMgr &&
"Already has an output manager");
828 OutputMgr = std::move(NewOutputs);
832 assert(!OutputMgr &&
"Already has an output manager");
833 OutputMgr = llvm::makeIntrusiveRefCnt<llvm::vfs::OnDiskOutputBackend>();
847std::unique_ptr<raw_pwrite_stream>
849 bool RemoveFileOnSignal,
bool UseTemporary,
850 bool CreateMissingDirectories) {
852 createOutputFileImpl(OutputPath,
Binary, RemoveFileOnSignal, UseTemporary,
853 CreateMissingDirectories);
855 return std::move(*OS);
857 << OutputPath << errorToErrorCode(OS.takeError()).message();
862CompilerInstance::createOutputFileImpl(StringRef OutputPath,
bool Binary,
863 bool RemoveFileOnSignal,
865 bool CreateMissingDirectories) {
866 assert((!CreateMissingDirectories || UseTemporary) &&
867 "CreateMissingDirectories is only allowed when using temporary files");
871 std::optional<SmallString<128>> AbsPath;
872 if (OutputPath !=
"-" && !llvm::sys::path::is_absolute(OutputPath)) {
874 "File Manager is required to fix up relative path.\n");
876 AbsPath.emplace(OutputPath);
878 OutputPath = *AbsPath;
886 .setDiscardOnSignal(RemoveFileOnSignal)
887 .setAtomicWrite(UseTemporary)
888 .setImplyCreateDirectories(UseTemporary && CreateMissingDirectories));
890 return O.takeError();
892 O->discardOnDestroy([](llvm::Error E) { consumeError(std::move(E)); });
893 OutputFiles.push_back(std::move(*O));
894 return OutputFiles.back().createProxy();
916 SourceMgr.setMainFileID(SourceMgr.createFileID(Input.
getBuffer(), Kind));
917 assert(SourceMgr.getMainFileID().isValid() &&
918 "Couldn't establish MainFileID!");
922 StringRef InputFile = Input.
getFile();
925 auto FileOrErr = InputFile ==
"-"
927 : FileMgr.getFileRef(InputFile,
true);
929 auto EC = llvm::errorToErrorCode(FileOrErr.takeError());
930 if (InputFile !=
"-")
931 Diags.
Report(diag::err_fe_error_reading) << InputFile << EC.message();
933 Diags.
Report(diag::err_fe_error_reading_stdin) << EC.message();
937 SourceMgr.setMainFileID(
940 assert(SourceMgr.getMainFileID().isValid() &&
941 "Couldn't establish MainFileID!");
948 assert(
hasDiagnostics() &&
"Diagnostics engine is not initialized!");
950 assert(!
getFrontendOpts().ShowVersion &&
"Client must handle '-version'!");
971 OS <<
"clang -cc1 version " CLANG_VERSION_STRING <<
" based upon LLVM "
972 << LLVM_VERSION_STRING <<
" default target "
973 << llvm::sys::getDefaultTargetTriple() <<
"\n";
976 llvm::EnableStatistics(
false);
990 if (llvm::Error Err = Act.
Execute()) {
991 consumeError(std::move(Err));
1004 llvm::PrintStatistics(OS);
1007 if (!StatsFile.empty()) {
1008 llvm::sys::fs::OpenFlags FileFlags = llvm::sys::fs::OF_TextWithCRLF;
1010 FileFlags |= llvm::sys::fs::OF_Append;
1013 std::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, FileFlags);
1016 << StatsFile << EC.message();
1018 llvm::PrintStatisticsJSON(*StatS);
1037 OS << NumWarnings <<
" warning" << (NumWarnings == 1 ?
"" :
"s");
1038 if (NumWarnings && NumErrors)
1041 OS << NumErrors <<
" error" << (NumErrors == 1 ?
"" :
"s");
1042 if (NumWarnings || NumErrors) {
1046 OS <<
" when compiling for host";
1048 OS <<
" when compiling for "
1061 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &
Error))
1068 if (
auto PassPlugin = llvm::PassPlugin::Load(Path)) {
1069 PassPlugins.emplace_back(std::make_unique<llvm::PassPlugin>(*PassPlugin));
1072 << Path <<
toString(PassPlugin.takeError());
1077 for (
const FrontendPluginRegistry::entry &Plugin :
1078 FrontendPluginRegistry::entries()) {
1079 std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
1091 if (LangOpts.OpenCL)
1100std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
1102 StringRef OriginalModuleMapFile, StringRef ModuleFileName,
1103 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1105 auto Invocation = std::make_shared<CompilerInvocation>(
getInvocation());
1107 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1111 Invocation->resetNonModularOptions();
1115 HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
1116 llvm::erase_if(PPOpts.
Macros,
1117 [&HSOpts](
const std::pair<std::string, bool> &def) {
1118 StringRef MacroDef = def.first;
1119 return HSOpts.ModulesIgnoreMacros.contains(
1120 llvm::CachedHashString(MacroDef.split(
'=').first));
1124 Invocation->getLangOpts().ModuleName =
1128 Invocation->getLangOpts().CurrentModule = std::string(ModuleName);
1133 FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
1134 FrontendOpts.
OutputFile = ModuleFileName.str();
1141 FrontendOpts.
Inputs = {std::move(Input)};
1146 DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts();
1148 DiagOpts.VerifyDiagnostics = 0;
1151 "Module hash mismatch!");
1153 std::shared_ptr<ModuleCache> ModCache;
1154 if (ThreadSafeConfig) {
1155 ModCache = ThreadSafeConfig->getModuleCache();
1157 ModCache = this->ModCache;
1161 auto InstancePtr = std::make_unique<CompilerInstance>(
1163 auto &Instance = *InstancePtr;
1165 auto &
Inv = Instance.getInvocation();
1167 if (ThreadSafeConfig) {
1168 Instance.setVirtualFileSystem(ThreadSafeConfig->getVFS());
1169 Instance.createFileManager();
1175 Instance.createFileManager();
1178 if (ThreadSafeConfig) {
1179 Instance.createDiagnostics(&ThreadSafeConfig->getDiagConsumer(),
1182 Instance.createDiagnostics(
1187 Instance.getDiagnostics().setSuppressSystemWarnings(
false);
1189 Instance.createSourceManager();
1190 SourceManager &SourceMgr = Instance.getSourceManager();
1192 if (ThreadSafeConfig) {
1198 SourceMgr.pushModuleBuildStack(
1203 Instance.FailedModules = FailedModules;
1208 if (GetDependencyDirectives)
1209 Instance.GetDependencyDirectives =
1210 GetDependencyDirectives->cloneFor(Instance.getFileManager());
1212 if (ThreadSafeConfig) {
1213 Instance.setModuleDepCollector(ThreadSafeConfig->getModuleDepCollector());
1220 Inv.getDependencyOutputOpts() = DependencyOutputOptions();
1226class PrettyStackTraceBuildModule :
public llvm::PrettyStackTraceEntry {
1227 StringRef ModuleName;
1228 StringRef ModuleFileName;
1231 PrettyStackTraceBuildModule(StringRef ModuleName, StringRef ModuleFileName)
1232 : ModuleName(ModuleName), ModuleFileName(ModuleFileName) {}
1233 void print(raw_ostream &OS)
const override {
1234 OS <<
"Building module '" << ModuleName <<
"' as '" << ModuleFileName
1241 StringRef ModuleName,
1242 StringRef ModuleFileName,
1243 CompilerInstance &Instance) {
1244 PrettyStackTraceBuildModule CrashInfo(ModuleName, ModuleFileName);
1245 llvm::TimeTraceScope TimeScope(
"Module Compile", ModuleName);
1249 if (
getModuleCache().getInMemoryModuleCache().isPCMFinal(ModuleFileName)) {
1256 << ModuleName << ModuleFileName;
1260 bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnNewStack(
1262 std::unique_ptr<FrontendAction> Action =
1263 std::make_unique<GenerateModuleFromModuleMapAction>();
1265 if (
auto WrapGenModuleAction = Instance.getGenModuleActionWrapper())
1266 Action = WrapGenModuleAction(Instance.getFrontendOpts(),
1269 Instance.ExecuteAction(*Action);
1281 FailedModules = std::move(Instance.FailedModules);
1286 Instance.setSema(
nullptr);
1287 Instance.setASTConsumer(
nullptr);
1290 Instance.clearOutputFiles(
true);
1301 return !Instance.getDiagnostics().hasErrorOccurred() ||
1302 Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
1307 StringRef Filename = llvm::sys::path::filename(
File.getName());
1309 if (Filename ==
"module_private.map")
1310 llvm::sys::path::append(PublicFilename,
"module.map");
1311 else if (Filename ==
"module.private.modulemap")
1312 llvm::sys::path::append(PublicFilename,
"module.modulemap");
1314 return std::nullopt;
1315 return FileMgr.getOptionalFileRef(PublicFilename);
1320 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1336 while (Loc.
isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) {
1337 ModuleMapFID = SourceMgr.getFileID(Loc);
1338 Loc = SourceMgr.getIncludeLoc(ModuleMapFID);
1342 SourceMgr.getFileEntryRefForID(ModuleMapFID);
1343 assert(ModuleMapFile &&
"Top-level module map with no FileID");
1350 ModuleMapFile = PublicMMFile;
1362 return cloneForModuleCompileImpl(
1363 ImportLoc, ModuleName,
1366 std::move(ThreadSafeConfig));
1374 llvm::sys::path::append(FakeModuleMapFile,
"__inferred_module.map");
1376 std::string InferredModuleMapContent;
1377 llvm::raw_string_ostream OS(InferredModuleMapContent);
1380 auto Instance = cloneForModuleCompileImpl(
1381 ImportLoc, ModuleName,
1384 std::move(ThreadSafeConfig));
1386 std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
1387 llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent);
1388 FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef(
1389 FakeModuleMapFile, InferredModuleMapContent.size(), 0);
1390 Instance->getSourceManager().overrideFileContents(ModuleMapFile,
1391 std::move(ModuleMapBuffer));
1402 bool *OutOfDate,
bool *Missing) {
1413 ModuleLoadCapabilities);
1442 StringRef ModuleFileName) {
1449 ModuleFileName, *Instance)) {
1451 diag::err_module_not_built)
1497 if (llvm::Error Err = Lock->tryLock().moveInto(Owned)) {
1520 switch (Lock->waitForUnlockFor(std::chrono::seconds(Timeout))) {
1521 case llvm::WaitForUnlockResult::Success:
1523 case llvm::WaitForUnlockResult::OwnerDied:
1525 case llvm::WaitForUnlockResult::Timeout:
1532 Lock->unsafeUnlock();
1537 bool OutOfDate =
false;
1538 bool Missing =
false;
1540 Module, ModuleFileName, &OutOfDate, &Missing))
1542 if (!OutOfDate && !Missing)
1601 for (
auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
1603 FileID FID = SourceMgr.getFileID(MDLoc);
1609 !SourceMgr.isWrittenInCommandLineFile(MDLoc))
1611 if (
auto *DMD = dyn_cast<DefMacroDirective>(MD))
1612 CmdLineDefinition = DMD->getMacroInfo();
1617 if (CurrentDefinition == CmdLineDefinition) {
1619 }
else if (!CurrentDefinition) {
1622 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1624 auto LatestDef = LatestLocalMD->getDefinition();
1625 assert(LatestDef.isUndefined() &&
1626 "predefined macro went away with no #undef?");
1627 PP.
Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
1630 }
else if (!CmdLineDefinition) {
1633 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1635 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1636 diag::note_module_def_undef_here)
1638 }
else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
1641 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1643 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1644 diag::note_module_def_undef_here)
1652 for (
const StringRef ConMacro : TopModule->
ConfigMacros) {
1668 .getHeaderSearchInfo()
1669 .getSpecificModuleCachePath()
1676 std::string Sysroot = HSOpts.
Sysroot;
1679 std::unique_ptr<llvm::Timer> ReadTimer;
1682 ReadTimer = std::make_unique<llvm::Timer>(
"reading_modules",
1683 "Reading modules", *timerGroup);
1684 TheASTReader = llvm::makeIntrusiveRefCnt<ASTReader>(
1688 Sysroot.empty() ?
"" : Sysroot.c_str(),
1697 TheASTReader->setDeserializationListener(
1704 TheASTReader->InitializeSema(
getSema());
1708 for (
auto &Listener : DependencyCollectors)
1709 Listener->attachToASTReader(*TheASTReader);
1718 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1726 bool ConfigMismatchIsRecoverable =
1731 auto Listener = std::make_unique<ReadModuleNames>(*PP);
1732 auto &ListenerRef = *Listener;
1734 std::move(Listener));
1737 switch (TheASTReader->ReadAST(
1740 &LoadedModuleFile)) {
1744 ListenerRef.registerAll();
1750 diag::warn_ast_file_config_mismatch)
1754 ListenerRef.markAllUnavailable();
1766 MS_PrebuiltModulePath,
1767 MS_ModuleBuildPragma
1774 Module *M, StringRef ModuleName, std::string &ModuleFilename,
1775 const std::map<std::string, std::string, std::less<>> &BuiltModules,
1777 assert(ModuleFilename.empty() &&
"Already has a module source?");
1781 auto BuiltModuleIt = BuiltModules.find(ModuleName);
1782 if (BuiltModuleIt != BuiltModules.end()) {
1783 ModuleFilename = BuiltModuleIt->second;
1784 return MS_ModuleBuildPragma;
1794 if (!ModuleFilename.empty())
1795 return MS_PrebuiltModulePath;
1801 return MS_ModuleCache;
1804 return MS_ModuleNotFound;
1809 bool IsInclusionDirective) {
1813 HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1823 std::string ModuleFilename;
1824 ModuleSource Source =
1826 SourceLocation ModuleNameLoc = ModuleNameRange.
getBegin();
1827 if (Source == MS_ModuleNotFound) {
1830 << ModuleName << ModuleNameRange;
1833 if (ModuleFilename.empty()) {
1852 Timer.init(
"loading." + ModuleFilename,
"Loading " + ModuleFilename,
1854 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1855 llvm::TimeTraceScope TimeScope(
"Module Load", ModuleName);
1859 unsigned ARRFlags = Source == MS_ModuleCache
1862 : Source == MS_PrebuiltModulePath
1866 Source == MS_PrebuiltModulePath
1868 : Source == MS_ModuleBuildPragma
1871 ImportLoc, ARRFlags)) {
1875 assert(Source != MS_ModuleCache &&
1876 "missing module, but file loaded from cache");
1880 M = HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1884 if (
auto ModuleFile = FileMgr->getOptionalFileRef(ModuleFilename))
1890 return ModuleLoadResult();
1899 if (Source == MS_PrebuiltModulePath)
1903 diag::warn_ast_file_config_mismatch)
1912 return ModuleLoadResult();
1916 return ModuleLoadResult();
1920 if (Source != MS_ModuleCache) {
1924 return ModuleLoadResult();
1928 assert(M &&
"missing module, but trying to compile for cache");
1932 ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
1933 for (; Pos != PosEnd; ++Pos) {
1934 if (Pos->first == ModuleName)
1938 if (Pos != PosEnd) {
1939 SmallString<256> CyclePath;
1940 for (; Pos != PosEnd; ++Pos) {
1941 CyclePath += Pos->first;
1942 CyclePath +=
" -> ";
1944 CyclePath += ModuleName;
1947 << ModuleName << CyclePath;
1952 if (FailedModules.contains(ModuleName)) {
1954 << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
1962 "undiagnosed error in compileModuleAndReadAST");
1963 FailedModules.insert(ModuleName);
1975 bool IsInclusionDirective) {
1977 StringRef ModuleName = Path[0].getIdentifierInfo()->getName();
1983 if (ImportLoc.
isValid() && LastModuleImportLoc == ImportLoc) {
1985 if (LastModuleImportResult && ModuleName !=
getLangOpts().CurrentModule)
1986 TheASTReader->makeModuleVisible(LastModuleImportResult,
Visibility,
1988 return LastModuleImportResult;
2002 }
else if (ModuleName ==
getLangOpts().CurrentModule) {
2004 Module = PP->getHeaderSearchInfo().lookupModule(
2005 ModuleName, ImportLoc,
true,
2006 !IsInclusionDirective);
2018 ModuleName, ImportLoc,
true, !IsInclusionDirective);
2021 PPCb->moduleLoadSkipped(
Module);
2024 std::vector<clang::Module *> Worklist{
Module};
2025 while (!Worklist.empty()) {
2027 Worklist.pop_back();
2030 Worklist.push_back(SubM);
2035 SourceLocation ModuleNameEndLoc = Path.back().getLoc().getLocWithOffset(
2036 Path.back().getIdentifierInfo()->getLength());
2039 IsInclusionDirective);
2043 DisableGeneratingGlobalModuleIndex =
true;
2055 bool MapPrivateSubModToTopLevel =
false;
2056 for (
unsigned I = 1, N = Path.size(); I != N; ++I) {
2057 StringRef Name = Path[I].getIdentifierInfo()->getName();
2066 PrivateModule.append(
"_Private");
2069 auto &II = PP->getIdentifierTable().get(
2070 PrivateModule, PP->getIdentifierInfo(
Module->
Name)->getTokenID());
2071 PrivPath.emplace_back(Path[0].getLoc(), &II);
2075 if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, ImportLoc,
true,
2076 !IsInclusionDirective) ||
2078 PP->getHeaderSearchInfo()) != MS_ModuleNotFound)
2081 MapPrivateSubModToTopLevel =
true;
2082 PP->markClangModuleAsAffecting(
Module);
2084 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
2086 diag::warn_no_priv_submodule_use_toplevel)
2089 <<
SourceRange(Path[0].getLoc(), Path[I].getLoc())
2093 diag::note_private_top_level_defined);
2101 unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
2105 Name.edit_distance(SubModule->Name,
2106 true, BestEditDistance);
2107 if (ED <= BestEditDistance) {
2108 if (ED < BestEditDistance) {
2110 BestEditDistance = ED;
2113 Best.push_back(SubModule->Name);
2118 if (Best.size() == 1) {
2120 diag::err_no_submodule_suggest)
2122 << Best[0] <<
SourceRange(Path[0].getLoc(), Path[I - 1].getLoc())
2135 <<
SourceRange(Path[0].getLoc(), Path[I - 1].getLoc());
2154 <<
SourceRange(Path.front().getLoc(), Path.back().getLoc());
2163 <<
SourceRange(Path.front().getLoc(), Path.back().getLoc());
2164 LastModuleImportLoc = ImportLoc;
2178 LastModuleImportLoc = ImportLoc;
2180 return LastModuleImportResult;
2184 StringRef ModuleName,
2188 for (
auto &
C : CleanModuleName)
2196 if (std::error_code EC = llvm::sys::fs::createTemporaryFile(
2197 CleanModuleName,
"pcm", ModuleFileName)) {
2199 << ModuleFileName << EC.message();
2202 std::string ModuleMapFileName = (CleanModuleName +
".map").str();
2209 std::string NullTerminatedSource(Source.str());
2211 auto Other = cloneForModuleCompileImpl(ImportLoc, ModuleName, Input,
2212 StringRef(), ModuleFileName);
2217 ModuleMapFileName, NullTerminatedSource.size(), 0);
2218 Other->getSourceManager().overrideFileContents(
2219 ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
2221 Other->BuiltModules = std::move(BuiltModules);
2222 Other->DeleteBuiltModules =
false;
2227 BuiltModules = std::move(
Other->BuiltModules);
2230 BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName);
2231 llvm::sys::RemoveFileOnSignal(ModuleFileName);
2243 TheASTReader->makeModuleVisible(Mod,
Visibility, ImportLoc);
2249 .getHeaderSearchInfo()
2250 .getSpecificModuleCachePath()
2260 TheASTReader->loadGlobalIndex();
2265 llvm::sys::fs::create_directories(
2266 getPreprocessor().getHeaderSearchInfo().getSpecificModuleCachePath());
2270 .getHeaderSearchInfo()
2271 .getSpecificModuleCachePath())) {
2276 consumeError(std::move(Err));
2279 TheASTReader->resetForReload();
2280 TheASTReader->loadGlobalIndex();
2281 GlobalIndex = TheASTReader->getGlobalIndex();
2285 if (!HaveFullGlobalModuleIndex && GlobalIndex && !
buildingModule()) {
2291 bool RecreateIndex =
false;
2294 Module *TheModule = I->second;
2298 Path.emplace_back(TriggerLoc,
2300 std::reverse(Path.begin(), Path.end());
2303 RecreateIndex =
true;
2306 if (RecreateIndex) {
2310 .getHeaderSearchInfo()
2311 .getSpecificModuleCachePath())) {
2313 consumeError(std::move(Err));
2316 TheASTReader->resetForReload();
2317 TheASTReader->loadGlobalIndex();
2318 GlobalIndex = TheASTReader->getGlobalIndex();
2320 HaveFullGlobalModuleIndex =
true;
2354 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 void SetupSerializedDiagnostics(DiagnosticOptions &DiagOpts, DiagnosticsEngine &Diags, StringRef OutputFile)
static bool compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName)
Compile a module in a separate compiler instance.
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.
CompileOrReadResult
The result of compileModuleBehindLockOrRead().
@ Compiled
We successfully compiled the module and we still need to read it.
@ Read
We read a module file compiled by another instance.
@ FailedToRead
We failed to read the module file compiled by another instance.
@ FailedToCompile
We failed to compile the module.
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 CompileOrReadResult compileModuleBehindLockOrRead(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName)
Attempt to compile the module in a separate compiler instance behind a lock (to avoid building the sa...
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...
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)
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.
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...
GenModuleActionWrapperFunc getGenModuleActionWrapper() const
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 computeContextHash() const
Compute the context hash - a string that uniquely identifies compiler settings.
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
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.
unsigned ImplicitModulesLockTimeoutSeconds
The time in seconds to wait on an implicit module lock before timing out.
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.
void loadAllParsedModules()
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...
This interface provides a way to observe the actions of the preprocessor as it does its thing.
@ 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.
SourceLocation getBegin() const
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.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ 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.
std::shared_ptr< ModuleCache > createCrossProcessModuleCache()
Creates new ModuleCache backed by a file system directory that may be operated on by multiple process...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
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)
constexpr size_t DesiredStackSize
The amount of stack space that Clang would like to be provided with.
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.