22#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/Support/AdvisoryLock.h"
50#include "llvm/Support/BuryPointer.h"
51#include "llvm/Support/CrashRecoveryContext.h"
52#include "llvm/Support/Errc.h"
53#include "llvm/Support/FileSystem.h"
54#include "llvm/Support/MemoryBuffer.h"
55#include "llvm/Support/Path.h"
56#include "llvm/Support/Signals.h"
57#include "llvm/Support/TimeProfiler.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/VirtualFileSystem.h"
60#include "llvm/Support/VirtualOutputBackends.h"
61#include "llvm/Support/VirtualOutputError.h"
62#include "llvm/Support/raw_ostream.h"
63#include "llvm/TargetParser/Host.h"
70CompilerInstance::CompilerInstance(
71 std::shared_ptr<CompilerInvocation> Invocation,
72 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
75 Invocation(
std::move(Invocation)),
77 ThePCHContainerOperations(
std::move(PCHContainerOps)) {
78 assert(this->Invocation &&
"Invocation must not be null");
82 assert(OutputFiles.empty() &&
"Still output files in flight?");
86 return (BuildGlobalModuleIndex ||
87 (TheASTReader && TheASTReader->isGlobalIndexUnavailable() &&
89 !DisableGeneratingGlobalModuleIndex;
94 Diagnostics = std::move(
Value);
98 OwnedVerboseOutputStream.reset();
99 VerboseOutputStream = &
Value;
103 OwnedVerboseOutputStream.swap(
Value);
104 VerboseOutputStream = OwnedVerboseOutputStream.get();
122 auto &TO = AuxTargetOpts = std::make_unique<TargetOptions>();
173 FileMgr = std::move(
Value);
178 SourceMgr = std::move(
Value);
182 PP = std::move(
Value);
187 Context = std::move(
Value);
189 if (Context && Consumer)
198 Consumer = std::move(
Value);
200 if (Context && Consumer)
205 CompletionConsumer.reset(
Value);
209 return std::move(TheSema);
216 assert(ModCache.get() == &Reader->getModuleManager().getModuleCache() &&
217 "Expected ASTReader to use the same PCM cache");
218 TheASTReader = std::move(Reader);
221std::shared_ptr<ModuleDependencyCollector>
223 return ModuleDepCollector;
227 std::shared_ptr<ModuleDependencyCollector> Collector) {
228 ModuleDepCollector = std::move(Collector);
232 std::shared_ptr<ModuleDependencyCollector> MDC) {
235 for (
auto &Name : HeaderMapFileNames)
240 std::shared_ptr<ModuleDependencyCollector> MDC) {
247 auto PCHDir =
FileMgr.getOptionalDirectoryRef(PCHInclude);
249 MDC->addFile(PCHInclude);
255 llvm::sys::path::native(PCHDir->getName(), DirNative);
256 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
258 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
259 Dir != DirEnd && !EC; Dir.increment(EC)) {
268 MDC->addFile(Dir->path());
273 std::shared_ptr<ModuleDependencyCollector> MDC) {
280 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
281 llvm::MemoryBuffer::getFile(VFSFile);
284 llvm::vfs::collectVFSFromYAML(std::move(Buffer.get()),
285 nullptr, VFSFile, VFSEntries);
288 for (
auto &E : VFSEntries)
289 MDC->addFile(E.VPath, E.RPath);
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)));
345 bool ShouldOwnClient) {
354 auto Diags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(
360 Diags->setClient(Client, ShouldOwnClient);
367 if (Opts.VerifyDiagnostics)
388 VFS = FileMgr ? FileMgr->getVirtualFileSystemPtr()
391 assert(VFS &&
"FileManager has no VFS?");
394 llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(std::move(VFS));
397 return FileMgr.get();
404 llvm::makeIntrusiveRefCnt<SourceManager>(
getDiagnostics(), FileMgr);
417 FileMgr.getVirtualFileRef(RB.first, RB.second->getBufferSize(), 0);
424 SourceMgr.overrideFileContents(FromFile, RB.second->getMemBufferRef());
426 SourceMgr.overrideFileContents(
427 FromFile, std::unique_ptr<llvm::MemoryBuffer>(RB.second));
435 Diags.
Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
445 SourceMgr.overrideFileContents(FromFile, *ToFile);
448 SourceMgr.setOverridenFilesKeepOriginalName(
458 TheASTReader.reset();
464 PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOpts(),
473 PP->createPreprocessingRecord();
477 PP->getFileManager(), PPOpts);
486 const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple();
487 if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA &&
488 PP->getAuxTargetInfo())
489 HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple();
492 PP->getLangOpts(), *HeaderSearchTriple);
496 if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
498 PP->getHeaderSearchInfo().setModuleHash(ModuleHash);
499 PP->getHeaderSearchInfo().setModuleCachePath(
514 ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
520 if (ModuleDepCollector) {
531 for (
auto &Listener : DependencyCollectors)
532 Listener->attachToPreprocessor(*PP);
539 if (OutputPath ==
"-")
552 if (GetDependencyDirectives)
553 PP->setDependencyDirectivesGetter(*GetDependencyDirectives);
560 llvm::sys::path::append(SpecificModuleCache, ModuleHash);
561 return std::string(SpecificModuleCache);
568 auto Context = llvm::makeIntrusiveRefCnt<ASTContext>(
569 getLangOpts(), PP.getSourceManager(), PP.getIdentifierTable(),
570 PP.getSelectorTable(), PP.getBuiltinInfo(), PP.TUKind);
587 void ReadModuleName(StringRef ModuleName)
override {
590 LoadedModules.push_back(ModuleName.str());
595 for (
const std::string &LoadedModule : LoadedModules)
598 LoadedModules.clear();
601 void markAllUnavailable() {
602 for (
const std::string &LoadedModule : LoadedModules) {
605 M->HasIncompatibleModuleFile =
true;
609 SmallVector<Module *, 2> Stack;
611 while (!Stack.empty()) {
612 Module *Current = Stack.pop_back_val();
616 llvm::append_range(Stack, SubmodulesRange);
620 LoadedModules.clear();
627 bool AllowPCHWithCompilerErrors,
void *DeserializationListener,
628 bool OwnDeserializationListener) {
635 DeserializationListener, OwnDeserializationListener,
Preamble,
640 StringRef Path, StringRef Sysroot,
645 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
646 ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
647 void *DeserializationListener,
bool OwnDeserializationListener,
648 bool Preamble,
bool UseGlobalModuleIndex) {
650 PP.getHeaderSearchInfo().getHeaderSearchOpts();
652 auto Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
653 PP, ModCache, &Context, PCHContainerRdr, CodeGenOpts, Extensions,
654 Sysroot.empty() ?
"" : Sysroot.data(), DisableValidation,
655 AllowPCHWithCompilerErrors,
false,
662 Context.setExternalSource(Reader);
664 Reader->setDeserializationListener(
666 OwnDeserializationListener);
668 for (
auto &Listener : DependencyCollectors)
669 Listener->attachToASTReader(*Reader);
671 auto Listener = std::make_unique<ReadModuleNames>(PP);
672 auto &ListenerRef = *Listener;
674 std::move(Listener));
676 switch (Reader->ReadAST(Path,
684 PP.setPredefines(Reader->getSuggestedPredefines());
685 ListenerRef.registerAll();
701 ListenerRef.markAllUnavailable();
702 Context.setExternalSource(
nullptr);
728 if (!CompletionConsumer) {
741 timerGroup.reset(
new llvm::TimerGroup(
"clang",
"Clang time report"));
742 FrontendTimer.reset(
new llvm::Timer(
"frontend",
"Front end", *timerGroup));
762 TUKind, CompletionConsumer));
768 if (ExternalSemaSrc) {
769 TheSema->addExternalSource(ExternalSemaSrc);
770 ExternalSemaSrc->InitializeSema(*TheSema);
776 (void)TheSema->APINotes.loadCurrentModuleAPINotes(
788 for (
auto &O : OutputFiles)
789 llvm::handleAllErrors(
791 [&](
const llvm::vfs::TempFileOutputError &E) {
792 getDiagnostics().Report(diag::err_unable_to_rename_temp)
793 << E.getTempPath() << E.getOutputPath()
794 << E.convertToErrorCode().message();
796 [&](
const llvm::vfs::OutputError &E) {
797 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
798 << E.getOutputPath() << E.convertToErrorCode().message();
800 [&](
const llvm::ErrorInfoBase &EIB) {
801 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
802 << O.getPath() << EIB.message();
806 if (DeleteBuiltModules) {
807 for (
auto &
Module : BuiltModules)
808 llvm::sys::fs::remove(
Module.second);
809 BuiltModules.clear();
814 bool Binary, StringRef InFile, StringRef Extension,
bool RemoveFileOnSignal,
815 bool CreateMissingDirectories,
bool ForceUseTemporary) {
817 std::optional<SmallString<128>> PathStorage;
818 if (OutputPath.empty()) {
819 if (InFile ==
"-" || Extension.empty()) {
822 PathStorage.emplace(InFile);
823 llvm::sys::path::replace_extension(*PathStorage, Extension);
824 OutputPath = *PathStorage;
830 CreateMissingDirectories);
834 return std::make_unique<llvm::raw_null_ostream>();
841 assert(!OutputMgr &&
"Already has an output manager");
842 OutputMgr = std::move(NewOutputs);
846 assert(!OutputMgr &&
"Already has an output manager");
847 OutputMgr = llvm::makeIntrusiveRefCnt<llvm::vfs::OnDiskOutputBackend>();
861std::unique_ptr<raw_pwrite_stream>
863 bool RemoveFileOnSignal,
bool UseTemporary,
864 bool CreateMissingDirectories) {
866 createOutputFileImpl(OutputPath,
Binary, RemoveFileOnSignal, UseTemporary,
867 CreateMissingDirectories);
869 return std::move(*OS);
871 << OutputPath << errorToErrorCode(OS.takeError()).message();
876CompilerInstance::createOutputFileImpl(StringRef OutputPath,
bool Binary,
877 bool RemoveFileOnSignal,
879 bool CreateMissingDirectories) {
880 assert((!CreateMissingDirectories || UseTemporary) &&
881 "CreateMissingDirectories is only allowed when using temporary files");
885 std::optional<SmallString<128>> AbsPath;
886 if (OutputPath !=
"-" && !llvm::sys::path::is_absolute(OutputPath)) {
888 "File Manager is required to fix up relative path.\n");
890 AbsPath.emplace(OutputPath);
891 FileMgr->FixupRelativePath(*AbsPath);
892 OutputPath = *AbsPath;
900 .setDiscardOnSignal(RemoveFileOnSignal)
901 .setAtomicWrite(UseTemporary)
902 .setImplyCreateDirectories(UseTemporary && CreateMissingDirectories));
904 return O.takeError();
906 O->discardOnDestroy([](llvm::Error E) { consumeError(std::move(E)); });
907 OutputFiles.push_back(std::move(*O));
908 return OutputFiles.back().createProxy();
930 SourceMgr.setMainFileID(SourceMgr.createFileID(Input.
getBuffer(), Kind));
931 assert(SourceMgr.getMainFileID().isValid() &&
932 "Couldn't establish MainFileID!");
936 StringRef InputFile = Input.
getFile();
939 auto FileOrErr = InputFile ==
"-"
941 : FileMgr.getFileRef(InputFile,
true);
943 auto EC = llvm::errorToErrorCode(FileOrErr.takeError());
944 if (InputFile !=
"-")
945 Diags.
Report(diag::err_fe_error_reading) << InputFile << EC.message();
947 Diags.
Report(diag::err_fe_error_reading_stdin) << EC.message();
951 SourceMgr.setMainFileID(
954 assert(SourceMgr.getMainFileID().isValid() &&
955 "Couldn't establish MainFileID!");
962 assert(
hasDiagnostics() &&
"Diagnostics engine is not initialized!");
964 assert(!
getFrontendOpts().ShowVersion &&
"Client must handle '-version'!");
971 auto FinishDiagnosticClient = llvm::make_scope_exit([&]() {
990 OS <<
"clang -cc1 version " CLANG_VERSION_STRING <<
" based upon LLVM "
991 << LLVM_VERSION_STRING <<
" default target "
992 << llvm::sys::getDefaultTargetTriple() <<
"\n";
995 llvm::EnableStatistics(
false);
1009 if (llvm::Error Err = Act.
Execute()) {
1010 consumeError(std::move(Err));
1023 llvm::PrintStatistics(OS);
1026 if (!StatsFile.empty()) {
1027 llvm::sys::fs::OpenFlags FileFlags = llvm::sys::fs::OF_TextWithCRLF;
1029 FileFlags |= llvm::sys::fs::OF_Append;
1032 std::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, FileFlags);
1035 << StatsFile << EC.message();
1037 llvm::PrintStatisticsJSON(*StatS);
1056 OS << NumWarnings <<
" warning" << (NumWarnings == 1 ?
"" :
"s");
1057 if (NumWarnings && NumErrors)
1060 OS << NumErrors <<
" error" << (NumErrors == 1 ?
"" :
"s");
1061 if (NumWarnings || NumErrors) {
1065 OS <<
" when compiling for host";
1078 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &
Error))
1084 for (
const FrontendPluginRegistry::entry &Plugin :
1085 FrontendPluginRegistry::entries()) {
1086 std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
1098 if (LangOpts.OpenCL)
1107std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
1109 StringRef OriginalModuleMapFile, StringRef ModuleFileName,
1110 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1112 auto Invocation = std::make_shared<CompilerInvocation>(
getInvocation());
1114 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1118 Invocation->resetNonModularOptions();
1122 HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
1123 llvm::erase_if(PPOpts.
Macros,
1124 [&HSOpts](
const std::pair<std::string, bool> &def) {
1125 StringRef MacroDef = def.first;
1126 return HSOpts.ModulesIgnoreMacros.contains(
1127 llvm::CachedHashString(MacroDef.split(
'=').first));
1131 Invocation->getLangOpts().ModuleName =
1135 Invocation->getLangOpts().CurrentModule = std::string(ModuleName);
1140 FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
1141 FrontendOpts.
OutputFile = ModuleFileName.str();
1148 FrontendOpts.
Inputs = {std::move(Input)};
1153 DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts();
1155 DiagOpts.VerifyDiagnostics = 0;
1157 "Module hash mismatch!");
1163 auto InstancePtr = std::make_unique<CompilerInstance>(
1165 auto &Instance = *InstancePtr;
1167 auto &
Inv = Instance.getInvocation();
1169 if (ThreadSafeConfig) {
1170 Instance.createFileManager(ThreadSafeConfig->getVFS());
1177 if (ThreadSafeConfig) {
1178 Instance.createDiagnostics(Instance.getVirtualFileSystem(),
1179 &ThreadSafeConfig->getDiagConsumer(),
1182 Instance.createDiagnostics(
1183 Instance.getVirtualFileSystem(),
1188 Instance.getDiagnostics().setSuppressSystemWarnings(
false);
1190 Instance.createSourceManager(Instance.getFileManager());
1191 SourceManager &SourceMgr = Instance.getSourceManager();
1193 if (ThreadSafeConfig) {
1199 SourceMgr.pushModuleBuildStack(
1204 Instance.FailedModules = FailedModules;
1206 if (GetDependencyDirectives)
1207 Instance.GetDependencyDirectives =
1208 GetDependencyDirectives->cloneFor(Instance.getFileManager());
1210 if (ThreadSafeConfig) {
1211 Instance.setModuleDepCollector(ThreadSafeConfig->getModuleDepCollector());
1218 Inv.getDependencyOutputOpts() = DependencyOutputOptions();
1224 StringRef ModuleName,
1225 StringRef ModuleFileName,
1226 CompilerInstance &Instance) {
1227 llvm::TimeTraceScope TimeScope(
"Module Compile", ModuleName);
1231 if (
getModuleCache().getInMemoryModuleCache().isPCMFinal(ModuleFileName)) {
1238 << ModuleName << ModuleFileName;
1242 bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnNewStack(
1257 FailedModules = std::move(Instance.FailedModules);
1262 Instance.setSema(
nullptr);
1263 Instance.setASTConsumer(
nullptr);
1266 Instance.clearOutputFiles(
true);
1277 return !Instance.getDiagnostics().hasErrorOccurred() ||
1278 Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
1283 StringRef Filename = llvm::sys::path::filename(
File.getName());
1285 if (Filename ==
"module_private.map")
1286 llvm::sys::path::append(PublicFilename,
"module.map");
1287 else if (Filename ==
"module.private.modulemap")
1288 llvm::sys::path::append(PublicFilename,
"module.modulemap");
1290 return std::nullopt;
1291 return FileMgr.getOptionalFileRef(PublicFilename);
1296 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1312 while (Loc.
isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) {
1313 ModuleMapFID = SourceMgr.getFileID(Loc);
1314 Loc = SourceMgr.getIncludeLoc(ModuleMapFID);
1318 SourceMgr.getFileEntryRefForID(ModuleMapFID);
1319 assert(ModuleMapFile &&
"Top-level module map with no FileID");
1326 ModuleMapFile = PublicMMFile;
1338 return cloneForModuleCompileImpl(
1339 ImportLoc, ModuleName,
1342 std::move(ThreadSafeConfig));
1350 llvm::sys::path::append(FakeModuleMapFile,
"__inferred_module.map");
1352 std::string InferredModuleMapContent;
1353 llvm::raw_string_ostream OS(InferredModuleMapContent);
1356 auto Instance = cloneForModuleCompileImpl(
1357 ImportLoc, ModuleName,
1360 std::move(ThreadSafeConfig));
1362 std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
1363 llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent);
1364 FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef(
1365 FakeModuleMapFile, InferredModuleMapContent.size(), 0);
1366 Instance->getSourceManager().overrideFileContents(ModuleMapFile,
1367 std::move(ModuleMapBuffer));
1377 bool *OutOfDate,
bool *Missing) {
1388 ModuleLoadCapabilities);
1406 Diags.
Report(ModuleNameLoc, diag::err_module_not_built)
1418 StringRef ModuleFileName) {
1421 ModuleNameLoc,
Module, ModuleFileName);
1425 ModuleFileName, *Instance)) {
1427 diag::err_module_not_built)
1459 Diags.
Report(ModuleNameLoc, diag::remark_module_lock)
1468 if (llvm::Error Err = Lock->tryLock().moveInto(Owned)) {
1472 Diags.
Report(ModuleNameLoc, diag::remark_module_lock_failure)
1475 ModuleNameLoc,
Module, ModuleFileName);
1480 ModuleNameLoc,
Module, ModuleFileName);
1485 switch (Lock->waitForUnlockFor(std::chrono::seconds(90))) {
1486 case llvm::WaitForUnlockResult::Success:
1488 case llvm::WaitForUnlockResult::OwnerDied:
1490 case llvm::WaitForUnlockResult::Timeout:
1494 Diags.
Report(ModuleNameLoc, diag::remark_module_lock_timeout)
1497 Lock->unsafeMaybeUnlock();
1502 bool OutOfDate =
false;
1503 bool Missing =
false;
1505 Module, ModuleFileName, &OutOfDate, &Missing))
1507 if (!OutOfDate && !Missing)
1551 for (
auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
1553 FileID FID = SourceMgr.getFileID(MD->getLocation());
1556 if (
auto *DMD = dyn_cast<DefMacroDirective>(MD))
1557 CmdLineDefinition = DMD->getMacroInfo();
1562 if (CurrentDefinition == CmdLineDefinition) {
1564 }
else if (!CurrentDefinition) {
1567 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1569 auto LatestDef = LatestLocalMD->getDefinition();
1570 assert(LatestDef.isUndefined() &&
1571 "predefined macro went away with no #undef?");
1572 PP.
Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
1575 }
else if (!CmdLineDefinition) {
1578 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1580 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1581 diag::note_module_def_undef_here)
1583 }
else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
1586 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1588 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1589 diag::note_module_def_undef_here)
1597 for (
const StringRef ConMacro : TopModule->
ConfigMacros) {
1605 llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::OF_None);
1611 llvm::sys::fs::file_status StatBuf;
1614 assert(!TimestampFile.empty());
1615 llvm::sys::path::append(TimestampFile,
"modules.timestamp");
1618 if (std::error_code EC = llvm::sys::fs::status(TimestampFile, StatBuf)) {
1620 if (EC == std::errc::no_such_file_or_directory) {
1628 time_t TimeStampModTime =
1629 llvm::sys::toTimeT(StatBuf.getLastModificationTime());
1630 time_t CurrentTime = time(
nullptr);
1642 for (llvm::sys::fs::directory_iterator Dir(HSOpts.
ModuleCachePath, EC),
1644 Dir != DirEnd && !EC; Dir.increment(EC)) {
1646 if (!llvm::sys::fs::is_directory(Dir->path()))
1650 for (llvm::sys::fs::directory_iterator
File(Dir->path(), EC), FileEnd;
1651 File != FileEnd && !EC;
File.increment(EC)) {
1653 StringRef Extension = llvm::sys::path::extension(
File->path());
1654 if (Extension !=
".pcm" && Extension !=
".timestamp" &&
1655 llvm::sys::path::filename(
File->path()) !=
"modules.idx")
1660 if (llvm::sys::fs::status(
File->path(), StatBuf))
1664 time_t FileAccessTime = llvm::sys::toTimeT(StatBuf.getLastAccessedTime());
1665 if (CurrentTime - FileAccessTime <=
1671 llvm::sys::fs::remove(
File->path());
1674 std::string TimpestampFilename =
File->path() +
".timestamp";
1675 llvm::sys::fs::remove(TimpestampFilename);
1680 if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
1681 llvm::sys::fs::directory_iterator() && !EC)
1682 llvm::sys::fs::remove(Dir->path());
1696 !
getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() &&
1703 std::string Sysroot = HSOpts.
Sysroot;
1706 std::unique_ptr<llvm::Timer> ReadTimer;
1709 ReadTimer = std::make_unique<llvm::Timer>(
"reading_modules",
1710 "Reading modules", *timerGroup);
1711 TheASTReader = llvm::makeIntrusiveRefCnt<ASTReader>(
1715 Sysroot.empty() ?
"" : Sysroot.c_str(),
1724 TheASTReader->setDeserializationListener(
1731 TheASTReader->InitializeSema(
getSema());
1735 for (
auto &Listener : DependencyCollectors)
1736 Listener->attachToASTReader(*TheASTReader);
1745 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1753 bool ConfigMismatchIsRecoverable =
1758 auto Listener = std::make_unique<ReadModuleNames>(*PP);
1759 auto &ListenerRef = *Listener;
1761 std::move(Listener));
1764 switch (TheASTReader->ReadAST(
1767 &LoadedModuleFile)) {
1771 ListenerRef.registerAll();
1780 ListenerRef.markAllUnavailable();
1792 MS_PrebuiltModulePath,
1793 MS_ModuleBuildPragma
1800 Module *M, StringRef ModuleName, std::string &ModuleFilename,
1801 const std::map<std::string, std::string, std::less<>> &BuiltModules,
1803 assert(ModuleFilename.empty() &&
"Already has a module source?");
1807 auto BuiltModuleIt = BuiltModules.find(ModuleName);
1808 if (BuiltModuleIt != BuiltModules.end()) {
1809 ModuleFilename = BuiltModuleIt->second;
1810 return MS_ModuleBuildPragma;
1820 if (!ModuleFilename.empty())
1821 return MS_PrebuiltModulePath;
1827 return MS_ModuleCache;
1830 return MS_ModuleNotFound;
1839 HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1849 std::string ModuleFilename;
1850 ModuleSource Source =
1852 if (Source == MS_ModuleNotFound) {
1855 << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
1858 if (ModuleFilename.empty()) {
1877 Timer.init(
"loading." + ModuleFilename,
"Loading " + ModuleFilename,
1879 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1880 llvm::TimeTraceScope TimeScope(
"Module Load", ModuleName);
1884 unsigned ARRFlags = Source == MS_ModuleCache
1887 : Source == MS_PrebuiltModulePath
1891 Source == MS_PrebuiltModulePath
1893 : Source == MS_ModuleBuildPragma
1896 ImportLoc, ARRFlags)) {
1900 assert(Source != MS_ModuleCache &&
1901 "missing module, but file loaded from cache");
1905 M = HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1909 if (
auto ModuleFile = FileMgr->getOptionalFileRef(ModuleFilename))
1915 return ModuleLoadResult();
1924 if (Source == MS_PrebuiltModulePath)
1928 diag::warn_module_config_mismatch)
1937 return ModuleLoadResult();
1941 return ModuleLoadResult();
1945 if (Source != MS_ModuleCache) {
1949 return ModuleLoadResult();
1953 assert(M &&
"missing module, but trying to compile for cache");
1957 ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
1958 for (; Pos != PosEnd; ++Pos) {
1959 if (Pos->first == ModuleName)
1963 if (Pos != PosEnd) {
1964 SmallString<256> CyclePath;
1965 for (; Pos != PosEnd; ++Pos) {
1966 CyclePath += Pos->first;
1967 CyclePath +=
" -> ";
1969 CyclePath += ModuleName;
1972 << ModuleName << CyclePath;
1977 if (FailedModules.contains(ModuleName)) {
1979 << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
1987 "undiagnosed error in compileModuleAndReadAST");
1988 FailedModules.insert(ModuleName);
2000 bool IsInclusionDirective) {
2002 StringRef ModuleName = Path[0].getIdentifierInfo()->getName();
2008 if (ImportLoc.
isValid() && LastModuleImportLoc == ImportLoc) {
2010 if (LastModuleImportResult && ModuleName !=
getLangOpts().CurrentModule)
2011 TheASTReader->makeModuleVisible(LastModuleImportResult,
Visibility,
2013 return LastModuleImportResult;
2027 }
else if (ModuleName ==
getLangOpts().CurrentModule) {
2029 Module = PP->getHeaderSearchInfo().lookupModule(
2030 ModuleName, ImportLoc,
true,
2031 !IsInclusionDirective);
2042 ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);
2046 DisableGeneratingGlobalModuleIndex =
true;
2058 bool MapPrivateSubModToTopLevel =
false;
2059 for (
unsigned I = 1, N = Path.size(); I != N; ++I) {
2060 StringRef Name = Path[I].getIdentifierInfo()->getName();
2069 PrivateModule.append(
"_Private");
2072 auto &II = PP->getIdentifierTable().get(
2073 PrivateModule, PP->getIdentifierInfo(
Module->
Name)->getTokenID());
2074 PrivPath.emplace_back(Path[0].getLoc(), &II);
2078 if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, ImportLoc,
true,
2079 !IsInclusionDirective) ||
2081 PP->getHeaderSearchInfo()) != MS_ModuleNotFound)
2084 MapPrivateSubModToTopLevel =
true;
2085 PP->markClangModuleAsAffecting(
Module);
2087 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
2089 diag::warn_no_priv_submodule_use_toplevel)
2092 <<
SourceRange(Path[0].getLoc(), Path[I].getLoc())
2096 diag::note_private_top_level_defined);
2104 unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
2108 Name.edit_distance(SubModule->Name,
2109 true, BestEditDistance);
2110 if (ED <= BestEditDistance) {
2111 if (ED < BestEditDistance) {
2113 BestEditDistance = ED;
2116 Best.push_back(SubModule->Name);
2121 if (Best.size() == 1) {
2123 diag::err_no_submodule_suggest)
2125 << Best[0] <<
SourceRange(Path[0].getLoc(), Path[I - 1].getLoc())
2138 <<
SourceRange(Path[0].getLoc(), Path[I - 1].getLoc());
2157 <<
SourceRange(Path.front().getLoc(), Path.back().getLoc());
2166 <<
SourceRange(Path.front().getLoc(), Path.back().getLoc());
2167 LastModuleImportLoc = ImportLoc;
2181 LastModuleImportLoc = ImportLoc;
2183 return LastModuleImportResult;
2187 StringRef ModuleName,
2191 for (
auto &
C : CleanModuleName)
2199 if (std::error_code EC = llvm::sys::fs::createTemporaryFile(
2200 CleanModuleName,
"pcm", ModuleFileName)) {
2202 << ModuleFileName << EC.message();
2205 std::string ModuleMapFileName = (CleanModuleName +
".map").str();
2212 std::string NullTerminatedSource(Source.str());
2214 auto Other = cloneForModuleCompileImpl(ImportLoc, ModuleName, Input,
2215 StringRef(), ModuleFileName);
2220 ModuleMapFileName, NullTerminatedSource.size(), 0);
2221 Other->getSourceManager().overrideFileContents(
2222 ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
2224 Other->BuiltModules = std::move(BuiltModules);
2225 Other->DeleteBuiltModules =
false;
2230 BuiltModules = std::move(
Other->BuiltModules);
2233 BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName);
2234 llvm::sys::RemoveFileOnSignal(ModuleFileName);
2246 TheASTReader->makeModuleVisible(Mod,
Visibility, ImportLoc);
2251 if (
getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
2260 TheASTReader->loadGlobalIndex();
2265 llvm::sys::fs::create_directories(
2274 consumeError(std::move(Err));
2277 TheASTReader->resetForReload();
2278 TheASTReader->loadGlobalIndex();
2279 GlobalIndex = TheASTReader->getGlobalIndex();
2283 if (!HaveFullGlobalModuleIndex && GlobalIndex && !
buildingModule()) {
2285 bool RecreateIndex =
false;
2288 Module *TheModule = I->second;
2292 Path.emplace_back(TriggerLoc,
2294 std::reverse(Path.begin(), Path.end());
2297 RecreateIndex =
true;
2300 if (RecreateIndex) {
2305 consumeError(std::move(Err));
2308 TheASTReader->resetForReload();
2309 TheASTReader->loadGlobalIndex();
2310 GlobalIndex = TheASTReader->getGlobalIndex();
2312 HaveFullGlobalModuleIndex =
true;
2346 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 pruneModuleCache(const HeaderSearchOptions &HSOpts)
Prune the module cache of modules that haven't been accessed in a long time.
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 writeTimestampFile(StringRef TimestampFile)
Write a new timestamp file with the given path.
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 createSourceManager(FileManager &FileMgr)
Create the source manager and replace any existing one with it.
void setOutputManager(IntrusiveRefCntPtr< llvm::vfs::OutputBackend > NewOutputs)
Set the output manager.
FileManager * createFileManager(IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Create the file manager and replace any existing one with it.
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...
void createDiagnostics(llvm::vfs::FileSystem &VFS, DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
Create the diagnostics engine using the invocation's diagnostic options and replace any existing one ...
std::string getSpecificModuleCachePath()
std::unique_ptr< CompilerInstance > cloneForModuleCompile(SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName, std::optional< ThreadSafeCloneConfig > ThreadSafeConfig=std::nullopt)
Creates a new CompilerInstance for compiling a module.
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.
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
void LoadRequestedPlugins()
Load the list of plugins requested in the FrontendOptions.
TargetOptions & getTargetOpts()
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.
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.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
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 and virtual file system.
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.
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
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...
@ 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)
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.