22#include "clang/Config/config.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/ScopeExit.h"
44#include "llvm/ADT/Statistic.h"
45#include "llvm/Config/llvm-config.h"
46#include "llvm/Support/BuryPointer.h"
47#include "llvm/Support/CrashRecoveryContext.h"
48#include "llvm/Support/Errc.h"
49#include "llvm/Support/FileSystem.h"
50#include "llvm/Support/LockFileManager.h"
51#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Path.h"
53#include "llvm/Support/Program.h"
54#include "llvm/Support/Signals.h"
55#include "llvm/Support/TimeProfiler.h"
56#include "llvm/Support/Timer.h"
57#include "llvm/Support/raw_ostream.h"
58#include "llvm/TargetParser/Host.h"
65CompilerInstance::CompilerInstance(
66 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
70 ModuleCache(SharedModuleCache ? SharedModuleCache
72 ThePCHContainerOperations(
std::move(PCHContainerOps)) {}
75 assert(OutputFiles.empty() &&
"Still output files in flight?");
79 std::shared_ptr<CompilerInvocation>
Value) {
80 Invocation = std::move(
Value);
84 return (BuildGlobalModuleIndex ||
85 (TheASTReader && TheASTReader->isGlobalIndexUnavailable() &&
87 !DisableGeneratingGlobalModuleIndex;
95 OwnedVerboseOutputStream.reset();
96 VerboseOutputStream = &
Value;
100 OwnedVerboseOutputStream.swap(
Value);
101 VerboseOutputStream = OwnedVerboseOutputStream.get();
120 auto TO = std::make_shared<TargetOptions>();
173 PP = std::move(
Value);
179 if (Context && Consumer)
188 Consumer = std::move(
Value);
190 if (Context && Consumer)
195 CompletionConsumer.reset(
Value);
199 return std::move(TheSema);
206 assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() &&
207 "Expected ASTReader to use the same PCM cache");
208 TheASTReader = std::move(Reader);
211std::shared_ptr<ModuleDependencyCollector>
213 return ModuleDepCollector;
217 std::shared_ptr<ModuleDependencyCollector> Collector) {
218 ModuleDepCollector = std::move(Collector);
222 std::shared_ptr<ModuleDependencyCollector> MDC) {
225 for (
auto &Name : HeaderMapFileNames)
230 std::shared_ptr<ModuleDependencyCollector> MDC) {
239 MDC->addFile(PCHInclude);
245 llvm::sys::path::native(PCHDir->getName(), DirNative);
248 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
249 Dir != DirEnd && !EC; Dir.increment(EC)) {
258 MDC->addFile(Dir->path());
263 std::shared_ptr<ModuleDependencyCollector> MDC) {
270 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
271 llvm::MemoryBuffer::getFile(VFSFile);
274 llvm::vfs::collectVFSFromYAML(std::move(Buffer.get()),
275 nullptr, VFSFile, VFSEntries);
278 for (
auto &E : VFSEntries)
279 MDC->addFile(E.VPath, E.RPath);
287 std::unique_ptr<raw_ostream> StreamOwner;
288 raw_ostream *OS = &llvm::errs();
291 auto FileOS = std::make_unique<llvm::raw_fd_ostream>(
293 llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
295 Diags.
Report(diag::warn_fe_cc_log_diagnostics_failure)
298 FileOS->SetUnbuffered();
300 StreamOwner = std::move(FileOS);
305 auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
306 std::move(StreamOwner));
320 StringRef OutputFile) {
321 auto SerializedConsumer =
326 Diags.
takeClient(), std::move(SerializedConsumer)));
329 Diags.
getClient(), std::move(SerializedConsumer)));
334 bool ShouldOwnClient) {
342 bool ShouldOwnClient,
351 Diags->setClient(Client, ShouldOwnClient);
358 if (Opts->VerifyDiagnostics)
380 VFS = FileMgr ? &FileMgr->getVirtualFileSystem()
383 assert(VFS &&
"FileManager has no VFS?");
385 return FileMgr.get();
414 FromFile, std::unique_ptr<llvm::MemoryBuffer>(
415 const_cast<llvm::MemoryBuffer *
>(RB.second)));
423 Diags.
Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
431 Diags.
Report(diag::err_fe_remap_missing_from_file) << RF.first;
450 TheASTReader.reset();
456 PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOptsPtr(),
465 PP->createPreprocessingRecord();
469 PP->getFileManager(), PPOpts);
478 const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple();
479 if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA &&
480 PP->getAuxTargetInfo())
481 HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple();
484 PP->getLangOpts(), *HeaderSearchTriple);
488 if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
490 PP->getHeaderSearchInfo().setModuleHash(ModuleHash);
491 PP->getHeaderSearchInfo().setModuleCachePath(
506 ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
512 if (ModuleDepCollector) {
519 for (
auto &Listener : DependencyCollectors)
520 Listener->attachToPreprocessor(*PP);
527 if (OutputPath ==
"-")
545 llvm::sys::path::append(SpecificModuleCache, ModuleHash);
546 return std::string(SpecificModuleCache);
572 void ReadModuleName(StringRef ModuleName)
override {
575 LoadedModules.push_back(ModuleName.str());
580 for (
const std::string &LoadedModule : LoadedModules)
583 LoadedModules.clear();
586 void markAllUnavailable() {
587 for (
const std::string &LoadedModule : LoadedModules) {
590 M->HasIncompatibleModuleFile =
true;
596 while (!Stack.empty()) {
597 Module *Current = Stack.pop_back_val();
598 if (Current->IsUnimportable)
continue;
599 Current->IsAvailable =
true;
600 auto SubmodulesRange = Current->submodules();
601 Stack.insert(Stack.end(), SubmodulesRange.begin(),
602 SubmodulesRange.end());
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) {
638 PP, ModuleCache, &Context, PCHContainerRdr, Extensions,
639 Sysroot.empty() ?
"" : Sysroot.data(), DisableValidation,
640 AllowPCHWithCompilerErrors,
false,
642 UseGlobalModuleIndex));
648 Reader->setDeserializationListener(
650 OwnDeserializationListener);
652 for (
auto &Listener : DependencyCollectors)
653 Listener->attachToASTReader(*Reader);
655 auto Listener = std::make_unique<ReadModuleNames>(PP);
656 auto &ListenerRef = *Listener;
658 std::move(Listener));
660 switch (Reader->ReadAST(Path,
669 ListenerRef.registerAll();
685 ListenerRef.markAllUnavailable();
712 if (!CompletionConsumer) {
725 FrontendTimerGroup.reset(
726 new llvm::TimerGroup(
"frontend",
"Clang front-end time report"));
728 new llvm::Timer(
"frontend",
"Clang front-end timer",
729 *FrontendTimerGroup));
749 TUKind, CompletionConsumer));
755 if (ExternalSemaSrc) {
756 TheSema->addExternalSource(ExternalSemaSrc.get());
757 ExternalSemaSrc->InitializeSema(*TheSema);
763 (void)TheSema->APINotes.loadCurrentModuleAPINotes(
775 for (OutputFile &OF : OutputFiles) {
778 consumeError(OF.File->discard());
779 if (!OF.Filename.empty())
780 llvm::sys::fs::remove(OF.Filename);
787 if (OF.File->TmpName.empty()) {
788 consumeError(OF.File->discard());
792 llvm::Error E = OF.File->keep(OF.Filename);
797 << OF.File->TmpName << OF.Filename << std::move(E);
799 llvm::sys::fs::remove(OF.File->TmpName);
802 if (DeleteBuiltModules) {
803 for (
auto &
Module : BuiltModules)
804 llvm::sys::fs::remove(
Module.second);
805 BuiltModules.clear();
810 bool Binary, StringRef InFile, StringRef Extension,
bool RemoveFileOnSignal,
811 bool CreateMissingDirectories,
bool ForceUseTemporary) {
813 std::optional<SmallString<128>> PathStorage;
814 if (OutputPath.empty()) {
815 if (InFile ==
"-" || Extension.empty()) {
818 PathStorage.emplace(InFile);
819 llvm::sys::path::replace_extension(*PathStorage, Extension);
820 OutputPath = *PathStorage;
826 CreateMissingDirectories);
830 return std::make_unique<llvm::raw_null_ostream>();
833std::unique_ptr<raw_pwrite_stream>
835 bool RemoveFileOnSignal,
bool UseTemporary,
836 bool CreateMissingDirectories) {
838 createOutputFileImpl(OutputPath, Binary, RemoveFileOnSignal, UseTemporary,
839 CreateMissingDirectories);
841 return std::move(*OS);
843 << OutputPath << errorToErrorCode(OS.takeError()).message();
848CompilerInstance::createOutputFileImpl(StringRef OutputPath,
bool Binary,
849 bool RemoveFileOnSignal,
851 bool CreateMissingDirectories) {
852 assert((!CreateMissingDirectories || UseTemporary) &&
853 "CreateMissingDirectories is only allowed when using temporary files");
857 std::optional<SmallString<128>> AbsPath;
858 if (OutputPath !=
"-" && !llvm::sys::path::is_absolute(OutputPath)) {
860 "File Manager is required to fix up relative path.\n");
862 AbsPath.emplace(OutputPath);
863 FileMgr->FixupRelativePath(*AbsPath);
864 OutputPath = *AbsPath;
867 std::unique_ptr<llvm::raw_fd_ostream> OS;
868 std::optional<StringRef> OSFile;
871 if (OutputPath ==
"-")
872 UseTemporary =
false;
874 llvm::sys::fs::file_status Status;
875 llvm::sys::fs::status(OutputPath, Status);
876 if (llvm::sys::fs::exists(Status)) {
878 if (!llvm::sys::fs::can_write(OutputPath))
879 return llvm::errorCodeToError(
884 if (!llvm::sys::fs::is_regular_file(Status))
885 UseTemporary =
false;
890 std::optional<llvm::sys::fs::TempFile> Temp;
896 StringRef OutputExtension = llvm::sys::path::extension(OutputPath);
898 StringRef(OutputPath).drop_back(OutputExtension.size());
899 TempPath +=
"-%%%%%%%%";
900 TempPath += OutputExtension;
902 llvm::sys::fs::OpenFlags BinaryFlags =
903 Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_Text;
905 llvm::sys::fs::TempFile::create(
906 TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write,
909 llvm::Error E = handleErrors(
910 ExpectedFile.takeError(), [&](
const llvm::ECError &E) -> llvm::Error {
911 std::error_code EC = E.convertToErrorCode();
912 if (CreateMissingDirectories &&
913 EC == llvm::errc::no_such_file_or_directory) {
914 StringRef Parent = llvm::sys::path::parent_path(OutputPath);
915 EC = llvm::sys::fs::create_directories(Parent);
917 ExpectedFile = llvm::sys::fs::TempFile::create(
918 TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write,
921 return llvm::errorCodeToError(
922 llvm::errc::no_such_file_or_directory);
925 return llvm::errorCodeToError(EC);
929 consumeError(std::move(E));
931 Temp = std::move(ExpectedFile.get());
932 OS.reset(
new llvm::raw_fd_ostream(Temp->FD,
false));
933 OSFile = Temp->TmpName;
943 OS.reset(
new llvm::raw_fd_ostream(
945 (Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_TextWithCRLF)));
947 return llvm::errorCodeToError(EC);
952 OutputFiles.emplace_back(((OutputPath !=
"-") ? OutputPath :
"").str(),
955 if (!Binary || OS->supportsSeeking())
956 return std::move(OS);
958 return std::make_unique<llvm::buffer_unique_ostream>(std::move(OS));
982 "Couldn't establish MainFileID!");
986 StringRef InputFile = Input.
getFile();
989 auto FileOrErr = InputFile ==
"-"
993 auto EC = llvm::errorToErrorCode(FileOrErr.takeError());
994 if (InputFile !=
"-")
995 Diags.
Report(diag::err_fe_error_reading) << InputFile << EC.message();
997 Diags.
Report(diag::err_fe_error_reading_stdin) << EC.message();
1005 "Couldn't establish MainFileID!");
1012 assert(
hasDiagnostics() &&
"Diagnostics engine is not initialized!");
1014 assert(!
getFrontendOpts().ShowVersion &&
"Client must handle '-version'!");
1021 auto FinishDiagnosticClient = llvm::make_scope_exit([&]() {
1040 OS <<
"clang -cc1 version " CLANG_VERSION_STRING <<
" based upon LLVM "
1041 << LLVM_VERSION_STRING <<
" default target "
1042 << llvm::sys::getDefaultTargetTriple() <<
"\n";
1048 llvm::EnableStatistics(
false);
1062 if (llvm::Error Err = Act.
Execute()) {
1063 consumeError(std::move(Err));
1076 llvm::PrintStatistics(OS);
1079 if (!StatsFile.empty()) {
1080 llvm::sys::fs::OpenFlags FileFlags = llvm::sys::fs::OF_TextWithCRLF;
1082 FileFlags |= llvm::sys::fs::OF_Append;
1085 std::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, FileFlags);
1088 << StatsFile << EC.message();
1090 llvm::PrintStatisticsJSON(*StatS);
1109 OS << NumWarnings <<
" warning" << (NumWarnings == 1 ?
"" :
"s");
1110 if (NumWarnings && NumErrors)
1113 OS << NumErrors <<
" error" << (NumErrors == 1 ?
"" :
"s");
1114 if (NumWarnings || NumErrors) {
1118 OS <<
" when compiling for host";
1131 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
1137 for (
const FrontendPluginRegistry::entry &Plugin :
1138 FrontendPluginRegistry::entries()) {
1139 std::unique_ptr<PluginASTAction>
P(Plugin.instantiate());
1151 if (LangOpts.OpenCL)
1166 StringRef OriginalModuleMapFile, StringRef ModuleFileName,
1171 llvm::TimeTraceScope TimeScope(
"Module Compile", ModuleName);
1177 ImportLoc, diag::err_module_rebuild_finalized)
1184 std::make_shared<CompilerInvocation>(ImportingInstance.
getInvocation());
1195 llvm::erase_if(PPOpts.
Macros,
1196 [&HSOpts](
const std::pair<std::string, bool> &def) {
1197 StringRef MacroDef = def.first;
1198 return HSOpts.ModulesIgnoreMacros.contains(
1199 llvm::CachedHashString(MacroDef.split(
'=').first));
1203 Invocation->getLangOpts().ModuleName =
1207 Invocation->getLangOpts().CurrentModule = std::string(ModuleName);
1213 FrontendOpts.
OutputFile = ModuleFileName.str();
1220 FrontendOpts.
Inputs = {Input};
1227 DiagOpts.VerifyDiagnostics = 0;
1229 Invocation->getModuleHash() &&
"Module hash mismatch!");
1237 auto &
Inv = *Invocation;
1238 Instance.setInvocation(std::move(Invocation));
1245 Instance.getDiagnostics().setSuppressSystemWarnings(
false);
1252 Instance.createSourceManager(Instance.getFileManager());
1276 diag::remark_module_build)
1277 << ModuleName << ModuleFileName;
1279 PreBuildStep(Instance);
1283 bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread(
1286 Instance.ExecuteAction(Action);
1290 PostBuildStep(Instance);
1293 diag::remark_module_build_done)
1303 Instance.setSema(
nullptr);
1304 Instance.setASTConsumer(
nullptr);
1307 Instance.clearOutputFiles(
true);
1312 return !Instance.getDiagnostics().hasErrorOccurred() ||
1313 Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
1318 StringRef
Filename = llvm::sys::path::filename(
File.getName());
1320 if (
Filename ==
"module_private.map")
1321 llvm::sys::path::append(PublicFilename,
"module.map");
1322 else if (
Filename ==
"module.private.modulemap")
1323 llvm::sys::path::append(PublicFilename,
"module.modulemap");
1325 return std::nullopt;
1334 StringRef ModuleFileName) {
1351 ModuleMapFID = SourceMgr.
getFileID(Loc);
1357 assert(ModuleMapFile &&
"Top-level module map with no FileID");
1364 ModuleMapFile = PublicMMFile;
1379 llvm::sys::path::append(FakeModuleMapFile,
"__inferred_module.map");
1381 std::string InferredModuleMapContent;
1382 llvm::raw_string_ostream OS(InferredModuleMapContent);
1392 std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
1393 llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
1394 FileEntryRef ModuleMapFile = Instance.getFileManager().getVirtualFileRef(
1395 FakeModuleMapFile, InferredModuleMapContent.size(), 0);
1396 Instance.getSourceManager().overrideFileContents(
1397 ModuleMapFile, std::move(ModuleMapBuffer));
1426 ModuleLoadCapabilities);
1438 Diags.
Report(ModuleNameLoc, diag::err_module_not_built)
1450 StringRef ModuleFileName) {
1454 diag::err_module_not_built)
1477 Diags.
Report(ModuleNameLoc, diag::remark_module_lock)
1482 StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
1483 llvm::sys::fs::create_directories(Dir);
1486 llvm::LockFileManager Locked(ModuleFileName);
1488 case llvm::LockFileManager::LFS_Error:
1492 Diags.
Report(ModuleNameLoc, diag::remark_module_lock_failure)
1495 Locked.unsafeRemoveLockFile();
1497 case llvm::LockFileManager::LFS_Owned:
1500 ModuleNameLoc,
Module, ModuleFileName);
1502 case llvm::LockFileManager::LFS_Shared:
1508 switch (Locked.waitForUnlock()) {
1509 case llvm::LockFileManager::Res_Success:
1511 case llvm::LockFileManager::Res_OwnerDied:
1513 case llvm::LockFileManager::Res_Timeout:
1517 Diags.
Report(ModuleNameLoc, diag::remark_module_lock_timeout)
1520 Locked.unsafeRemoveLockFile();
1525 bool OutOfDate =
false;
1527 Module, ModuleFileName, &OutOfDate))
1566 if (!
Id->hadMacroDefinition())
1572 for (
auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
1577 if (
auto *DMD = dyn_cast<DefMacroDirective>(MD))
1578 CmdLineDefinition = DMD->getMacroInfo();
1583 if (CurrentDefinition == CmdLineDefinition) {
1585 }
else if (!CurrentDefinition) {
1588 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1590 auto LatestDef = LatestLocalMD->getDefinition();
1591 assert(LatestDef.isUndefined() &&
1592 "predefined macro went away with no #undef?");
1593 PP.
Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
1596 }
else if (!CmdLineDefinition) {
1599 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1601 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1602 diag::note_module_def_undef_here)
1604 }
else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
1607 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1609 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1610 diag::note_module_def_undef_here)
1618 for (
const StringRef ConMacro : TopModule->
ConfigMacros) {
1626 llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::OF_None);
1632 llvm::sys::fs::file_status StatBuf;
1635 assert(!TimestampFile.empty());
1636 llvm::sys::path::append(TimestampFile,
"modules.timestamp");
1639 if (std::error_code EC = llvm::sys::fs::status(TimestampFile, StatBuf)) {
1641 if (EC == std::errc::no_such_file_or_directory) {
1649 time_t TimeStampModTime =
1650 llvm::sys::toTimeT(StatBuf.getLastModificationTime());
1651 time_t CurrentTime = time(
nullptr);
1664 llvm::sys::path::native(HSOpts.
ModuleCachePath, ModuleCachePathNative);
1665 for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd;
1666 Dir != DirEnd && !EC; Dir.increment(EC)) {
1668 if (!llvm::sys::fs::is_directory(Dir->path()))
1672 for (llvm::sys::fs::directory_iterator
File(Dir->path(), EC), FileEnd;
1673 File != FileEnd && !EC;
File.increment(EC)) {
1675 StringRef Extension = llvm::sys::path::extension(
File->path());
1676 if (Extension !=
".pcm" && Extension !=
".timestamp" &&
1677 llvm::sys::path::filename(
File->path()) !=
"modules.idx")
1682 if (llvm::sys::fs::status(
File->path(), StatBuf))
1686 time_t FileAccessTime = llvm::sys::toTimeT(StatBuf.getLastAccessedTime());
1687 if (CurrentTime - FileAccessTime <=
1693 llvm::sys::fs::remove(
File->path());
1696 std::string TimpestampFilename =
File->path() +
".timestamp";
1697 llvm::sys::fs::remove(TimpestampFilename);
1702 if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
1703 llvm::sys::fs::directory_iterator() && !EC)
1704 llvm::sys::fs::remove(Dir->path());
1718 !
getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() &&
1725 std::string Sysroot = HSOpts.
Sysroot;
1728 std::unique_ptr<llvm::Timer> ReadTimer;
1730 if (FrontendTimerGroup)
1731 ReadTimer = std::make_unique<llvm::Timer>(
"reading_modules",
1733 *FrontendTimerGroup);
1737 Sysroot.empty() ?
"" : Sysroot.c_str(),
1744 TheASTReader->setDeserializationListener(
1751 TheASTReader->InitializeSema(
getSema());
1755 for (
auto &Listener : DependencyCollectors)
1756 Listener->attachToASTReader(*TheASTReader);
1762 if (FrontendTimerGroup)
1764 *FrontendTimerGroup);
1765 llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer :
nullptr);
1773 bool ConfigMismatchIsRecoverable =
1778 auto Listener = std::make_unique<ReadModuleNames>(*PP);
1779 auto &ListenerRef = *Listener;
1781 std::move(Listener));
1784 switch (TheASTReader->ReadAST(
1787 &LoadedModuleFile)) {
1791 ListenerRef.registerAll();
1800 ListenerRef.markAllUnavailable();
1812 MS_PrebuiltModulePath,
1813 MS_ModuleBuildPragma
1820 Module *M, StringRef ModuleName, std::string &ModuleFilename,
1821 const std::map<std::string, std::string, std::less<>> &BuiltModules,
1823 assert(ModuleFilename.empty() &&
"Already has a module source?");
1827 auto BuiltModuleIt = BuiltModules.find(ModuleName);
1828 if (BuiltModuleIt != BuiltModules.end()) {
1829 ModuleFilename = BuiltModuleIt->second;
1830 return MS_ModuleBuildPragma;
1840 if (!ModuleFilename.empty())
1841 return MS_PrebuiltModulePath;
1847 return MS_ModuleCache;
1850 return MS_ModuleNotFound;
1859 HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1869 std::string ModuleFilename;
1870 ModuleSource Source =
1872 if (Source == MS_ModuleNotFound) {
1875 << ModuleName <<
SourceRange(ImportLoc, ModuleNameLoc);
1878 if (ModuleFilename.empty()) {
1896 if (FrontendTimerGroup)
1897 Timer.init(
"loading." + ModuleFilename,
"Loading " + ModuleFilename,
1898 *FrontendTimerGroup);
1899 llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer :
nullptr);
1900 llvm::TimeTraceScope TimeScope(
"Module Load", ModuleName);
1904 unsigned ARRFlags = Source == MS_ModuleCache
1907 : Source == MS_PrebuiltModulePath
1911 Source == MS_PrebuiltModulePath
1913 : Source == MS_ModuleBuildPragma
1916 ImportLoc, ARRFlags)) {
1920 assert(Source != MS_ModuleCache &&
1921 "missing module, but file loaded from cache");
1925 M = HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1929 if (
auto ModuleFile = FileMgr->getFile(ModuleFilename))
1944 if (Source == MS_PrebuiltModulePath)
1948 diag::warn_module_config_mismatch)
1965 if (Source != MS_ModuleCache) {
1973 assert(M &&
"missing module, but trying to compile for cache");
1977 ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
1978 for (; Pos != PosEnd; ++Pos) {
1979 if (Pos->first == ModuleName)
1983 if (Pos != PosEnd) {
1985 for (; Pos != PosEnd; ++Pos) {
1986 CyclePath += Pos->first;
1987 CyclePath +=
" -> ";
1989 CyclePath += ModuleName;
1992 << ModuleName << CyclePath;
1997 if (FailedModules && FailedModules->hasAlreadyFailed(ModuleName)) {
1999 << ModuleName <<
SourceRange(ImportLoc, ModuleNameLoc);
2007 "undiagnosed error in compileModuleAndReadAST");
2009 FailedModules->addFailed(ModuleName);
2021 bool IsInclusionDirective) {
2023 StringRef ModuleName = Path[0].first->getName();
2029 if (ImportLoc.
isValid() && LastModuleImportLoc == ImportLoc) {
2031 if (LastModuleImportResult && ModuleName !=
getLangOpts().CurrentModule)
2032 TheASTReader->makeModuleVisible(LastModuleImportResult,
Visibility,
2034 return LastModuleImportResult;
2048 }
else if (ModuleName ==
getLangOpts().CurrentModule) {
2051 ModuleName, ImportLoc,
true,
2052 !IsInclusionDirective);
2063 ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);
2067 DisableGeneratingGlobalModuleIndex =
true;
2079 bool MapPrivateSubModToTopLevel =
false;
2080 for (
unsigned I = 1, N = Path.size(); I != N; ++I) {
2081 StringRef Name = Path[I].first->getName();
2090 PrivateModule.append(
"_Private");
2095 PrivPath.push_back(std::make_pair(&II, Path[0].second));
2100 !IsInclusionDirective) ||
2105 MapPrivateSubModToTopLevel =
true;
2108 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
2110 diag::warn_no_priv_submodule_use_toplevel)
2116 diag::note_private_top_level_defined);
2124 unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
2128 Name.edit_distance(SubModule->Name,
2129 true, BestEditDistance);
2130 if (ED <= BestEditDistance) {
2131 if (ED < BestEditDistance) {
2133 BestEditDistance = ED;
2136 Best.push_back(SubModule->Name);
2141 if (Best.size() == 1) {
2144 <<
SourceRange(Path[0].second, Path[I - 1].second)
2157 <<
SourceRange(Path[0].second, Path[I - 1].second);
2176 <<
SourceRange(Path.front().second, Path.back().second);
2185 <<
SourceRange(Path.front().second, Path.back().second);
2186 LastModuleImportLoc = ImportLoc;
2200 LastModuleImportLoc = ImportLoc;
2202 return LastModuleImportResult;
2206 StringRef ModuleName,
2210 for (
auto &
C : CleanModuleName)
2218 if (std::error_code EC = llvm::sys::fs::createTemporaryFile(
2219 CleanModuleName,
"pcm", ModuleFileName)) {
2221 << ModuleFileName << EC.message();
2224 std::string ModuleMapFileName = (CleanModuleName +
".map").str();
2231 std::string NullTerminatedSource(Source.str());
2237 ModuleMapFileName, NullTerminatedSource.size(), 0);
2238 Other.getSourceManager().overrideFileContents(
2239 ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
2241 Other.BuiltModules = std::move(BuiltModules);
2242 Other.DeleteBuiltModules =
false;
2246 BuiltModules = std::move(
Other.BuiltModules);
2251 ModuleFileName, PreBuildStep, PostBuildStep)) {
2252 BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName);
2253 llvm::sys::RemoveFileOnSignal(ModuleFileName);
2265 TheASTReader->makeModuleVisible(Mod,
Visibility, ImportLoc);
2270 if (
getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
2279 TheASTReader->loadGlobalIndex();
2284 llvm::sys::fs::create_directories(
2293 consumeError(std::move(Err));
2296 TheASTReader->resetForReload();
2297 TheASTReader->loadGlobalIndex();
2298 GlobalIndex = TheASTReader->getGlobalIndex();
2302 if (!HaveFullGlobalModuleIndex && GlobalIndex && !
buildingModule()) {
2304 bool RecreateIndex =
false;
2307 Module *TheModule = I->second;
2311 Path.push_back(std::make_pair(
2313 std::reverse(Path.begin(), Path.end());
2316 RecreateIndex =
true;
2319 if (RecreateIndex) {
2324 consumeError(std::move(Err));
2327 TheASTReader->resetForReload();
2328 TheASTReader->loadGlobalIndex();
2329 GlobalIndex = TheASTReader->getGlobalIndex();
2331 HaveFullGlobalModuleIndex =
true;
2365 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 compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, StringRef ModuleName, FrontendInputFile Input, StringRef OriginalModuleMapFile, StringRef ModuleFileName, llvm::function_ref< void(CompilerInstance &)> PreBuildStep=[](CompilerInstance &) {}, llvm::function_ref< void(CompilerInstance &)> PostBuildStep=[](CompilerInstance &) {})
Compile a module file for the given module, using the options provided by the importing compiler inst...
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 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 bool readASTAfterCompileModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName, bool *OutOfDate)
Read the AST right after compiling the module.
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 void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, const CodeGenOptions *CodeGenOpts, DiagnosticsEngine &Diags)
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 bool compileModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName)
Compile a module file for the given module in a separate compiler instance, using the options provide...
static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, DiagnosticsEngine &Diags, StringRef OutputFile)
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...
Defines the clang::FileManager interface and associated types.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
llvm::MachO::Target Target
Defines the clang::Preprocessor interface.
Defines the SourceManager interface.
Defines utilities for dealing with stack allocation and stack space.
Defines version macros and version-related utility functions for Clang.
std::vector< std::string > ModuleSearchPaths
The set of search paths where we API notes can be found for particular modules.
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.
Reads an AST files chain containing the contents of a translation unit.
@ 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 InMemoryModuleCache &ModuleCache, 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.
void setFileManager(FileManager *Value)
Replace the current file manager and virtual file system.
void setSourceManager(SourceManager *Value)
setSourceManager - Replace the current source manager.
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 createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
Create the diagnostics engine using the invocation's diagnostic options and replace any existing one ...
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)
std::string getSpecificModuleCachePath()
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) override
Attempt to load the given module.
void setInvocation(std::shared_ptr< CompilerInvocation > Value)
setInvocation - Replace the current invocation.
std::shared_ptr< FailedModulesSet > getFailedModulesSetPtr() const
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.
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< ASTReader > getASTReader() const
void setTarget(TargetInfo *Value)
Replace the current Target.
void setModuleDepCollector(std::shared_ptr< ModuleDependencyCollector > Collector)
InMemoryModuleCache & getModuleCache() const
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.
std::shared_ptr< HeaderSearchOptions > getHeaderSearchOptsPtr() const
void setASTContext(ASTContext *Value)
setASTContext - Replace the current AST context.
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.
HeaderSearchOptions & getHeaderSearchOpts()
void createFrontendTimer()
Create the frontend timer and replace any existing one with it.
void setDiagnostics(DiagnosticsEngine *Value)
setDiagnostics - Replace the current diagnostics engine.
bool hasFailedModulesSet() const
CompilerInvocation & getInvocation()
void setVerboseOutputStream(raw_ostream &Value)
Replace the current stream for verbose output.
PreprocessorOptions & getPreprocessorOpts()
ASTConsumer & getASTConsumer() const
TargetInfo & getTarget() const
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()
CodeGenOptions & getCodeGenOpts()
SourceManager & getSourceManager() const
Return the current source manager.
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.
void createFailedModulesSet()
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.
Helper class for holding the data necessary to invoke the compiler.
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
Used for handling and querying diagnostic IDs.
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-header-in-module=... options used to override whether -Wsystem-headers is enable...
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...
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
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::Expected< FileEntryRef > getSTDIN()
Get the FileEntryRef for stdin, returning an error if stdin cannot be read.
const FileEntry * getVirtualFile(StringRef Filename, off_t Size, time_t ModificationTime)
FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, time_t ModificationTime)
Retrieve a file entry for a "virtual" file that acts as if there were a file with the given name on d...
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Diagnostic consumer that forwards diagnostics along to an existing, already-initialized diagnostic co...
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 SourceLocation and its associated SourceManager.
A global index for a set of module files, providing information about the identifiers within those mo...
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.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
In-memory cache for modules.
bool isPCMFinal(llvm::StringRef Filename) const
Check whether the PCM is final and has been shown to work.
@ 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.
Describes the result of attempting to load a module.
Abstract interface for a module loader.
bool buildingModule() const
Returns true if this instance is building a module.
llvm::StringMap< Module * >::const_iterator module_iterator
Module * findModule(StringRef Name) const
Retrieve a module with the given name.
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.
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...
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.
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...
void resetNonModularOptions()
Reset any options that are not considered when building a module.
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.
void markClangModuleAsAffecting(Module *M)
Mark the given clang module as affecting the current clang module or translation unit.
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.
const TranslationUnitKind TUKind
The kind of translation unit we are processing.
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
void setPredefines(std::string P)
Set the predefines for this Preprocessor.
IdentifierTable & getIdentifierTable()
Builtin::Context & getBuiltinInfo()
DiagnosticsEngine & getDiagnostics() const
SelectorTable & getSelectorTable()
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.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
void setModuleBuildStack(ModuleBuildStack stack)
Set the module build stack.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
void setOverridenFilesKeepOriginalName(bool value)
Set true if the SourceManager should report the original file name for contents of files that were ov...
ModuleBuildStack getModuleBuildStack() const
Retrieve the module build stack.
FileID getMainFileID() const
Returns the FileID of the main source file.
void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc)
Push an entry to the module build stack.
void overrideFileContents(FileEntryRef SourceFile, const llvm::MemoryBufferRef &Buffer)
Override the contents of the given source file by providing an already-allocated buffer.
SourceLocation getIncludeLoc(FileID FID) const
Returns the include location if FID is a #include'd file otherwise it returns an invalid location.
void setMainFileID(FileID FID)
Set the file ID for the main source file.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
A trivial tuple used to represent a source range.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
virtual void setAuxTarget(const TargetInfo *Aux)
void noSignedCharForObjCBool()
virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts)
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 *Diags, 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.
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, bool ReportDiags=true)
ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...
void ApplyHeaderSearchOptions(HeaderSearch &HS, const HeaderSearchOptions &HSOpts, const LangOptions &Lang, const llvm::Triple &triple)
Apply the header search options to get given HeaderSearch object.
void noteBottomOfStack()
Call this once on each thread, as soon after starting the thread as feasible, to note the approximate...
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 ...
std::error_code make_error_code(BuildPreambleError Error)
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
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.
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.