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/raw_ostream.h"
61#include "llvm/TargetParser/Host.h"
68CompilerInstance::CompilerInstance(
69 std::shared_ptr<CompilerInvocation> Invocation,
70 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
73 Invocation(
std::move(Invocation)),
75 ThePCHContainerOperations(
std::move(PCHContainerOps)) {
76 assert(this->Invocation &&
"Invocation must not be null");
80 assert(OutputFiles.empty() &&
"Still output files in flight?");
84 return (BuildGlobalModuleIndex ||
85 (TheASTReader && TheASTReader->isGlobalIndexUnavailable() &&
87 !DisableGeneratingGlobalModuleIndex;
92 Diagnostics = std::move(
Value);
96 OwnedVerboseOutputStream.reset();
97 VerboseOutputStream = &
Value;
101 OwnedVerboseOutputStream.swap(
Value);
102 VerboseOutputStream = OwnedVerboseOutputStream.get();
120 auto &TO = AuxTargetOpts = std::make_unique<TargetOptions>();
171 FileMgr = std::move(
Value);
176 SourceMgr = std::move(
Value);
180 PP = std::move(
Value);
185 Context = std::move(
Value);
187 if (Context && Consumer)
196 Consumer = std::move(
Value);
198 if (Context && Consumer)
203 CompletionConsumer.reset(
Value);
207 return std::move(TheSema);
214 assert(ModCache.get() == &Reader->getModuleManager().getModuleCache() &&
215 "Expected ASTReader to use the same PCM cache");
216 TheASTReader = std::move(Reader);
219std::shared_ptr<ModuleDependencyCollector>
221 return ModuleDepCollector;
225 std::shared_ptr<ModuleDependencyCollector> Collector) {
226 ModuleDepCollector = std::move(Collector);
230 std::shared_ptr<ModuleDependencyCollector> MDC) {
233 for (
auto &Name : HeaderMapFileNames)
238 std::shared_ptr<ModuleDependencyCollector> MDC) {
247 MDC->addFile(PCHInclude);
253 llvm::sys::path::native(PCHDir->getName(), DirNative);
256 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
257 Dir != DirEnd && !EC; Dir.increment(EC)) {
266 MDC->addFile(Dir->path());
271 std::shared_ptr<ModuleDependencyCollector> MDC) {
278 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
279 llvm::MemoryBuffer::getFile(VFSFile);
282 llvm::vfs::collectVFSFromYAML(std::move(Buffer.get()),
283 nullptr, VFSFile, VFSEntries);
286 for (
auto &
E : VFSEntries)
287 MDC->addFile(
E.VPath,
E.RPath);
295 std::unique_ptr<raw_ostream> StreamOwner;
296 raw_ostream *OS = &llvm::errs();
299 auto FileOS = std::make_unique<llvm::raw_fd_ostream>(
301 llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
303 Diags.
Report(diag::warn_fe_cc_log_diagnostics_failure)
306 FileOS->SetUnbuffered();
308 StreamOwner = std::move(FileOS);
313 auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
314 std::move(StreamOwner));
328 StringRef OutputFile) {
329 auto SerializedConsumer =
334 Diags.
takeClient(), std::move(SerializedConsumer)));
337 Diags.
getClient(), std::move(SerializedConsumer)));
343 bool ShouldOwnClient) {
352 auto Diags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(
358 Diags->setClient(Client, ShouldOwnClient);
365 if (Opts.VerifyDiagnostics)
386 VFS = FileMgr ? FileMgr->getVirtualFileSystemPtr()
389 assert(VFS &&
"FileManager has no VFS?");
392 llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(std::move(VFS));
395 return FileMgr.get();
402 llvm::makeIntrusiveRefCnt<SourceManager>(
getDiagnostics(), FileMgr);
425 FromFile, std::unique_ptr<llvm::MemoryBuffer>(RB.second));
433 Diags.
Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
456 TheASTReader.reset();
462 PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOpts(),
471 PP->createPreprocessingRecord();
475 PP->getFileManager(), PPOpts);
484 const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple();
485 if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA &&
486 PP->getAuxTargetInfo())
487 HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple();
490 PP->getLangOpts(), *HeaderSearchTriple);
494 if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
496 PP->getHeaderSearchInfo().setModuleHash(ModuleHash);
497 PP->getHeaderSearchInfo().setModuleCachePath(
512 ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
518 if (ModuleDepCollector) {
525 for (
auto &Listener : DependencyCollectors)
526 Listener->attachToPreprocessor(*PP);
533 if (OutputPath ==
"-")
546 if (GetDependencyDirectives)
547 PP->setDependencyDirectivesGetter(*GetDependencyDirectives);
554 llvm::sys::path::append(SpecificModuleCache, ModuleHash);
555 return std::string(SpecificModuleCache);
562 auto Context = llvm::makeIntrusiveRefCnt<ASTContext>(
581 void ReadModuleName(StringRef ModuleName)
override {
584 LoadedModules.push_back(ModuleName.str());
589 for (
const std::string &LoadedModule : LoadedModules)
592 LoadedModules.clear();
595 void markAllUnavailable() {
596 for (
const std::string &LoadedModule : LoadedModules) {
599 M->HasIncompatibleModuleFile =
true;
605 while (!Stack.empty()) {
606 Module *Current = Stack.pop_back_val();
607 if (Current->IsUnimportable)
continue;
608 Current->IsAvailable =
true;
609 auto SubmodulesRange = Current->submodules();
610 llvm::append_range(Stack, SubmodulesRange);
614 LoadedModules.clear();
621 bool AllowPCHWithCompilerErrors,
void *DeserializationListener,
622 bool OwnDeserializationListener) {
629 DeserializationListener, OwnDeserializationListener,
Preamble,
634 StringRef
Path, StringRef Sysroot,
639 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
640 ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
641 void *DeserializationListener,
bool OwnDeserializationListener,
642 bool Preamble,
bool UseGlobalModuleIndex) {
646 auto Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
647 PP, ModCache, &Context, PCHContainerRdr, CodeGenOpts, Extensions,
648 Sysroot.empty() ?
"" : Sysroot.data(), DisableValidation,
649 AllowPCHWithCompilerErrors,
false,
658 Reader->setDeserializationListener(
660 OwnDeserializationListener);
662 for (
auto &Listener : DependencyCollectors)
663 Listener->attachToASTReader(*Reader);
665 auto Listener = std::make_unique<ReadModuleNames>(PP);
666 auto &ListenerRef = *Listener;
668 std::move(Listener));
670 switch (Reader->ReadAST(
Path,
679 ListenerRef.registerAll();
695 ListenerRef.markAllUnavailable();
722 if (!CompletionConsumer) {
735 timerGroup.reset(
new llvm::TimerGroup(
"clang",
"Clang time report"));
736 FrontendTimer.reset(
new llvm::Timer(
"frontend",
"Front end", *timerGroup));
756 TUKind, CompletionConsumer));
762 if (ExternalSemaSrc) {
763 TheSema->addExternalSource(ExternalSemaSrc);
764 ExternalSemaSrc->InitializeSema(*TheSema);
770 (void)TheSema->APINotes.loadCurrentModuleAPINotes(
782 for (OutputFile &OF : OutputFiles) {
785 consumeError(OF.File->discard());
786 if (!OF.Filename.empty())
787 llvm::sys::fs::remove(OF.Filename);
794 if (OF.File->TmpName.empty()) {
795 consumeError(OF.File->discard());
799 llvm::Error
E = OF.File->keep(OF.Filename);
804 << OF.File->TmpName << OF.Filename << std::move(
E);
806 llvm::sys::fs::remove(OF.File->TmpName);
809 if (DeleteBuiltModules) {
810 for (
auto &
Module : BuiltModules)
811 llvm::sys::fs::remove(
Module.second);
812 BuiltModules.clear();
817 bool Binary, StringRef InFile, StringRef Extension,
bool RemoveFileOnSignal,
818 bool CreateMissingDirectories,
bool ForceUseTemporary) {
820 std::optional<SmallString<128>> PathStorage;
821 if (OutputPath.empty()) {
822 if (InFile ==
"-" || Extension.empty()) {
825 PathStorage.emplace(InFile);
826 llvm::sys::path::replace_extension(*PathStorage, Extension);
827 OutputPath = *PathStorage;
833 CreateMissingDirectories);
837 return std::make_unique<llvm::raw_null_ostream>();
840std::unique_ptr<raw_pwrite_stream>
842 bool RemoveFileOnSignal,
bool UseTemporary,
843 bool CreateMissingDirectories) {
845 createOutputFileImpl(OutputPath,
Binary, RemoveFileOnSignal, UseTemporary,
846 CreateMissingDirectories);
848 return std::move(*OS);
850 << OutputPath << errorToErrorCode(OS.takeError()).message();
855CompilerInstance::createOutputFileImpl(StringRef OutputPath,
bool Binary,
856 bool RemoveFileOnSignal,
858 bool CreateMissingDirectories) {
859 assert((!CreateMissingDirectories || UseTemporary) &&
860 "CreateMissingDirectories is only allowed when using temporary files");
864 std::optional<SmallString<128>> AbsPath;
865 if (OutputPath !=
"-" && !llvm::sys::path::is_absolute(OutputPath)) {
867 "File Manager is required to fix up relative path.\n");
869 AbsPath.emplace(OutputPath);
870 FileMgr->FixupRelativePath(*AbsPath);
871 OutputPath = *AbsPath;
874 std::unique_ptr<llvm::raw_fd_ostream> OS;
875 std::optional<StringRef> OSFile;
878 if (OutputPath ==
"-")
879 UseTemporary =
false;
881 llvm::sys::fs::file_status Status;
882 llvm::sys::fs::status(OutputPath, Status);
883 if (llvm::sys::fs::exists(Status)) {
885 if (!llvm::sys::fs::can_write(OutputPath))
886 return llvm::errorCodeToError(
891 if (!llvm::sys::fs::is_regular_file(Status))
892 UseTemporary =
false;
897 std::optional<llvm::sys::fs::TempFile> Temp;
903 StringRef OutputExtension = llvm::sys::path::extension(OutputPath);
905 StringRef(OutputPath).drop_back(OutputExtension.size());
906 TempPath +=
"-%%%%%%%%";
907 TempPath += OutputExtension;
909 llvm::sys::fs::OpenFlags BinaryFlags =
910 Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_Text;
912 llvm::sys::fs::TempFile::create(
913 TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write,
916 llvm::Error
E = handleErrors(
917 ExpectedFile.takeError(), [&](
const llvm::ECError &
E) -> llvm::Error {
918 std::error_code EC = E.convertToErrorCode();
919 if (CreateMissingDirectories &&
920 EC == llvm::errc::no_such_file_or_directory) {
921 StringRef Parent = llvm::sys::path::parent_path(OutputPath);
922 EC = llvm::sys::fs::create_directories(Parent);
924 ExpectedFile = llvm::sys::fs::TempFile::create(
925 TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write,
928 return llvm::errorCodeToError(
929 llvm::errc::no_such_file_or_directory);
932 return llvm::errorCodeToError(EC);
936 consumeError(std::move(
E));
938 Temp = std::move(ExpectedFile.get());
939 OS.reset(
new llvm::raw_fd_ostream(Temp->FD,
false));
940 OSFile = Temp->TmpName;
950 OS.reset(
new llvm::raw_fd_ostream(
952 (
Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_TextWithCRLF)));
954 return llvm::errorCodeToError(EC);
959 OutputFiles.emplace_back(((OutputPath !=
"-") ? OutputPath :
"").str(),
962 if (!
Binary || OS->supportsSeeking())
963 return std::move(OS);
965 return std::make_unique<llvm::buffer_unique_ostream>(std::move(OS));
989 "Couldn't establish MainFileID!");
993 StringRef InputFile = Input.
getFile();
996 auto FileOrErr = InputFile ==
"-"
1000 auto EC = llvm::errorToErrorCode(FileOrErr.takeError());
1001 if (InputFile !=
"-")
1002 Diags.
Report(diag::err_fe_error_reading) << InputFile << EC.message();
1004 Diags.
Report(diag::err_fe_error_reading_stdin) << EC.message();
1012 "Couldn't establish MainFileID!");
1019 assert(
hasDiagnostics() &&
"Diagnostics engine is not initialized!");
1021 assert(!
getFrontendOpts().ShowVersion &&
"Client must handle '-version'!");
1028 auto FinishDiagnosticClient = llvm::make_scope_exit([&]() {
1047 OS <<
"clang -cc1 version " CLANG_VERSION_STRING <<
" based upon LLVM "
1048 << LLVM_VERSION_STRING <<
" default target "
1049 << llvm::sys::getDefaultTargetTriple() <<
"\n";
1052 llvm::EnableStatistics(
false);
1066 if (llvm::Error Err = Act.
Execute()) {
1067 consumeError(std::move(Err));
1080 llvm::PrintStatistics(OS);
1083 if (!StatsFile.empty()) {
1084 llvm::sys::fs::OpenFlags FileFlags = llvm::sys::fs::OF_TextWithCRLF;
1086 FileFlags |= llvm::sys::fs::OF_Append;
1089 std::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, FileFlags);
1092 << StatsFile << EC.message();
1094 llvm::PrintStatisticsJSON(*StatS);
1113 OS << NumWarnings <<
" warning" << (NumWarnings == 1 ?
"" :
"s");
1114 if (NumWarnings && NumErrors)
1117 OS << NumErrors <<
" error" << (NumErrors == 1 ?
"" :
"s");
1118 if (NumWarnings || NumErrors) {
1122 OS <<
" when compiling for host";
1135 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(
Path.c_str(), &Error))
1141 for (
const FrontendPluginRegistry::entry &Plugin :
1142 FrontendPluginRegistry::entries()) {
1143 std::unique_ptr<PluginASTAction>
P(Plugin.instantiate());
1155 if (LangOpts.OpenCL)
1164std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
1166 StringRef OriginalModuleMapFile, StringRef ModuleFileName,
1167 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1169 auto Invocation = std::make_shared<CompilerInvocation>(
getInvocation());
1175 Invocation->resetNonModularOptions();
1180 llvm::erase_if(PPOpts.
Macros,
1181 [&HSOpts](
const std::pair<std::string, bool> &def) {
1182 StringRef MacroDef = def.first;
1183 return HSOpts.ModulesIgnoreMacros.contains(
1184 llvm::CachedHashString(MacroDef.split(
'=').first));
1188 Invocation->getLangOpts().ModuleName =
1192 Invocation->getLangOpts().CurrentModule = std::string(ModuleName);
1198 FrontendOpts.
OutputFile = ModuleFileName.str();
1205 FrontendOpts.
Inputs = {std::move(Input)};
1212 DiagOpts.VerifyDiagnostics = 0;
1213 assert(
getInvocation().getModuleHash() == Invocation->getModuleHash() &&
1214 "Module hash mismatch!");
1220 auto InstancePtr = std::make_unique<CompilerInstance>(
1222 auto &Instance = *InstancePtr;
1224 auto &
Inv = Instance.getInvocation();
1226 if (ThreadSafeConfig) {
1227 Instance.createFileManager(ThreadSafeConfig->getVFS());
1234 if (ThreadSafeConfig) {
1235 Instance.createDiagnostics(Instance.getVirtualFileSystem(),
1236 &ThreadSafeConfig->getDiagConsumer(),
1239 Instance.createDiagnostics(
1240 Instance.getVirtualFileSystem(),
1245 Instance.getDiagnostics().setSuppressSystemWarnings(
false);
1247 Instance.createSourceManager(Instance.getFileManager());
1250 if (ThreadSafeConfig) {
1261 Instance.FailedModules = FailedModules;
1263 if (GetDependencyDirectives)
1264 Instance.GetDependencyDirectives =
1265 GetDependencyDirectives->cloneFor(Instance.getFileManager());
1267 if (ThreadSafeConfig) {
1268 Instance.setModuleDepCollector(ThreadSafeConfig->getModuleDepCollector());
1281 StringRef ModuleName,
1282 StringRef ModuleFileName,
1284 llvm::TimeTraceScope TimeScope(
"Module Compile", ModuleName);
1288 if (
getModuleCache().getInMemoryModuleCache().isPCMFinal(ModuleFileName)) {
1295 << ModuleName << ModuleFileName;
1299 bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnNewStack(
1302 Instance.ExecuteAction(Action);
1314 FailedModules = std::move(Instance.FailedModules);
1319 Instance.setSema(
nullptr);
1320 Instance.setASTConsumer(
nullptr);
1323 Instance.clearOutputFiles(
true);
1334 return !Instance.getDiagnostics().hasErrorOccurred() ||
1335 Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
1340 StringRef
Filename = llvm::sys::path::filename(
File.getName());
1342 if (
Filename ==
"module_private.map")
1343 llvm::sys::path::append(PublicFilename,
"module.map");
1344 else if (
Filename ==
"module.private.modulemap")
1345 llvm::sys::path::append(PublicFilename,
"module.modulemap");
1347 return std::nullopt;
1353 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1376 assert(ModuleMapFile &&
"Top-level module map with no FileID");
1383 ModuleMapFile = PublicMMFile;
1395 return cloneForModuleCompileImpl(
1396 ImportLoc, ModuleName,
1399 std::move(ThreadSafeConfig));
1407 llvm::sys::path::append(FakeModuleMapFile,
"__inferred_module.map");
1409 std::string InferredModuleMapContent;
1410 llvm::raw_string_ostream OS(InferredModuleMapContent);
1413 auto Instance = cloneForModuleCompileImpl(
1414 ImportLoc, ModuleName,
1417 std::move(ThreadSafeConfig));
1419 std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
1420 llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent);
1421 FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef(
1422 FakeModuleMapFile, InferredModuleMapContent.size(), 0);
1423 Instance->getSourceManager().overrideFileContents(ModuleMapFile,
1424 std::move(ModuleMapBuffer));
1434 bool *OutOfDate,
bool *Missing) {
1445 ModuleLoadCapabilities);
1463 Diags.
Report(ModuleNameLoc, diag::err_module_not_built)
1475 StringRef ModuleFileName) {
1478 ModuleNameLoc,
Module, ModuleFileName);
1482 ModuleFileName, *Instance)) {
1484 diag::err_module_not_built)
1516 Diags.
Report(ModuleNameLoc, diag::remark_module_lock)
1525 if (llvm::Error Err = Lock->tryLock().moveInto(Owned)) {
1529 Diags.
Report(ModuleNameLoc, diag::remark_module_lock_failure)
1532 ModuleNameLoc,
Module, ModuleFileName);
1537 ModuleNameLoc,
Module, ModuleFileName);
1542 switch (Lock->waitForUnlockFor(std::chrono::seconds(90))) {
1543 case llvm::WaitForUnlockResult::Success:
1545 case llvm::WaitForUnlockResult::OwnerDied:
1547 case llvm::WaitForUnlockResult::Timeout:
1551 Diags.
Report(ModuleNameLoc, diag::remark_module_lock_timeout)
1554 Lock->unsafeMaybeUnlock();
1559 bool OutOfDate =
false;
1560 bool Missing =
false;
1562 Module, ModuleFileName, &OutOfDate, &Missing))
1564 if (!OutOfDate && !Missing)
1602 if (!
Id->hadMacroDefinition())
1608 for (
auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
1613 if (
auto *DMD = dyn_cast<DefMacroDirective>(MD))
1614 CmdLineDefinition = DMD->getMacroInfo();
1619 if (CurrentDefinition == CmdLineDefinition) {
1621 }
else if (!CurrentDefinition) {
1624 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1626 auto LatestDef = LatestLocalMD->getDefinition();
1627 assert(LatestDef.isUndefined() &&
1628 "predefined macro went away with no #undef?");
1629 PP.
Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
1632 }
else if (!CmdLineDefinition) {
1635 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1637 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1638 diag::note_module_def_undef_here)
1640 }
else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
1643 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1645 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1646 diag::note_module_def_undef_here)
1654 for (
const StringRef ConMacro : TopModule->
ConfigMacros) {
1662 llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::OF_None);
1668 llvm::sys::fs::file_status StatBuf;
1671 assert(!TimestampFile.empty());
1672 llvm::sys::path::append(TimestampFile,
"modules.timestamp");
1675 if (std::error_code EC = llvm::sys::fs::status(TimestampFile, StatBuf)) {
1677 if (EC == std::errc::no_such_file_or_directory) {
1685 time_t TimeStampModTime =
1686 llvm::sys::toTimeT(StatBuf.getLastModificationTime());
1687 time_t CurrentTime = time(
nullptr);
1699 for (llvm::sys::fs::directory_iterator Dir(HSOpts.
ModuleCachePath, EC),
1701 Dir != DirEnd && !EC; Dir.increment(EC)) {
1703 if (!llvm::sys::fs::is_directory(Dir->path()))
1707 for (llvm::sys::fs::directory_iterator
File(Dir->path(), EC), FileEnd;
1708 File != FileEnd && !EC;
File.increment(EC)) {
1710 StringRef Extension = llvm::sys::path::extension(
File->path());
1711 if (Extension !=
".pcm" && Extension !=
".timestamp" &&
1712 llvm::sys::path::filename(
File->path()) !=
"modules.idx")
1717 if (llvm::sys::fs::status(
File->path(), StatBuf))
1721 time_t FileAccessTime = llvm::sys::toTimeT(StatBuf.getLastAccessedTime());
1722 if (CurrentTime - FileAccessTime <=
1728 llvm::sys::fs::remove(
File->path());
1731 std::string TimpestampFilename =
File->path() +
".timestamp";
1732 llvm::sys::fs::remove(TimpestampFilename);
1737 if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
1738 llvm::sys::fs::directory_iterator() && !EC)
1739 llvm::sys::fs::remove(Dir->path());
1753 !
getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() &&
1760 std::string Sysroot = HSOpts.
Sysroot;
1763 std::unique_ptr<llvm::Timer> ReadTimer;
1766 ReadTimer = std::make_unique<llvm::Timer>(
"reading_modules",
1767 "Reading modules", *timerGroup);
1768 TheASTReader = llvm::makeIntrusiveRefCnt<ASTReader>(
1772 Sysroot.empty() ?
"" : Sysroot.c_str(),
1781 TheASTReader->setDeserializationListener(
1788 TheASTReader->InitializeSema(
getSema());
1792 for (
auto &Listener : DependencyCollectors)
1793 Listener->attachToASTReader(*TheASTReader);
1802 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1810 bool ConfigMismatchIsRecoverable =
1815 auto Listener = std::make_unique<ReadModuleNames>(*PP);
1816 auto &ListenerRef = *Listener;
1818 std::move(Listener));
1821 switch (TheASTReader->ReadAST(
1824 &LoadedModuleFile)) {
1828 ListenerRef.registerAll();
1837 ListenerRef.markAllUnavailable();
1849 MS_PrebuiltModulePath,
1850 MS_ModuleBuildPragma
1857 Module *M, StringRef ModuleName, std::string &ModuleFilename,
1858 const std::map<std::string, std::string, std::less<>> &BuiltModules,
1860 assert(ModuleFilename.empty() &&
"Already has a module source?");
1864 auto BuiltModuleIt = BuiltModules.find(ModuleName);
1865 if (BuiltModuleIt != BuiltModules.end()) {
1866 ModuleFilename = BuiltModuleIt->second;
1867 return MS_ModuleBuildPragma;
1877 if (!ModuleFilename.empty())
1878 return MS_PrebuiltModulePath;
1884 return MS_ModuleCache;
1887 return MS_ModuleNotFound;
1896 HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1906 std::string ModuleFilename;
1907 ModuleSource Source =
1909 if (Source == MS_ModuleNotFound) {
1912 << ModuleName <<
SourceRange(ImportLoc, ModuleNameLoc);
1915 if (ModuleFilename.empty()) {
1934 Timer.init(
"loading." + ModuleFilename,
"Loading " + ModuleFilename,
1936 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1937 llvm::TimeTraceScope TimeScope(
"Module Load", ModuleName);
1941 unsigned ARRFlags = Source == MS_ModuleCache
1944 : Source == MS_PrebuiltModulePath
1948 Source == MS_PrebuiltModulePath
1950 : Source == MS_ModuleBuildPragma
1953 ImportLoc, ARRFlags)) {
1957 assert(Source != MS_ModuleCache &&
1958 "missing module, but file loaded from cache");
1962 M = HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1966 if (
auto ModuleFile = FileMgr->getOptionalFileRef(ModuleFilename))
1981 if (Source == MS_PrebuiltModulePath)
1985 diag::warn_module_config_mismatch)
2002 if (Source != MS_ModuleCache) {
2010 assert(M &&
"missing module, but trying to compile for cache");
2014 ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
2015 for (; Pos != PosEnd; ++Pos) {
2016 if (Pos->first == ModuleName)
2020 if (Pos != PosEnd) {
2022 for (; Pos != PosEnd; ++Pos) {
2023 CyclePath += Pos->first;
2024 CyclePath +=
" -> ";
2026 CyclePath += ModuleName;
2029 << ModuleName << CyclePath;
2034 if (FailedModules.contains(ModuleName)) {
2036 << ModuleName <<
SourceRange(ImportLoc, ModuleNameLoc);
2044 "undiagnosed error in compileModuleAndReadAST");
2045 FailedModules.insert(ModuleName);
2057 bool IsInclusionDirective) {
2059 StringRef ModuleName =
Path[0].getIdentifierInfo()->getName();
2065 if (ImportLoc.
isValid() && LastModuleImportLoc == ImportLoc) {
2067 if (LastModuleImportResult && ModuleName !=
getLangOpts().CurrentModule)
2068 TheASTReader->makeModuleVisible(LastModuleImportResult,
Visibility,
2070 return LastModuleImportResult;
2084 }
else if (ModuleName ==
getLangOpts().CurrentModule) {
2087 ModuleName, ImportLoc,
true,
2088 !IsInclusionDirective);
2099 ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);
2103 DisableGeneratingGlobalModuleIndex =
true;
2115 bool MapPrivateSubModToTopLevel =
false;
2116 for (
unsigned I = 1, N =
Path.size(); I != N; ++I) {
2117 StringRef Name =
Path[I].getIdentifierInfo()->getName();
2126 PrivateModule.append(
"_Private");
2131 PrivPath.emplace_back(
Path[0].getLoc(), &II);
2136 !IsInclusionDirective) ||
2141 MapPrivateSubModToTopLevel =
true;
2144 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
2146 diag::warn_no_priv_submodule_use_toplevel)
2153 diag::note_private_top_level_defined);
2161 unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
2165 Name.edit_distance(SubModule->Name,
2166 true, BestEditDistance);
2167 if (ED <= BestEditDistance) {
2168 if (ED < BestEditDistance) {
2170 BestEditDistance = ED;
2173 Best.push_back(SubModule->Name);
2178 if (Best.size() == 1) {
2180 diag::err_no_submodule_suggest)
2224 LastModuleImportLoc = ImportLoc;
2238 LastModuleImportLoc = ImportLoc;
2240 return LastModuleImportResult;
2244 StringRef ModuleName,
2248 for (
auto &
C : CleanModuleName)
2256 if (std::error_code EC = llvm::sys::fs::createTemporaryFile(
2257 CleanModuleName,
"pcm", ModuleFileName)) {
2259 << ModuleFileName << EC.message();
2262 std::string ModuleMapFileName = (CleanModuleName +
".map").str();
2269 std::string NullTerminatedSource(Source.str());
2271 auto Other = cloneForModuleCompileImpl(ImportLoc, ModuleName, Input,
2272 StringRef(), ModuleFileName);
2277 ModuleMapFileName, NullTerminatedSource.size(), 0);
2278 Other->getSourceManager().overrideFileContents(
2279 ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
2281 Other->BuiltModules = std::move(BuiltModules);
2282 Other->DeleteBuiltModules =
false;
2287 BuiltModules = std::move(
Other->BuiltModules);
2290 BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName);
2291 llvm::sys::RemoveFileOnSignal(ModuleFileName);
2303 TheASTReader->makeModuleVisible(Mod,
Visibility, ImportLoc);
2308 if (
getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
2317 TheASTReader->loadGlobalIndex();
2322 llvm::sys::fs::create_directories(
2331 consumeError(std::move(Err));
2334 TheASTReader->resetForReload();
2335 TheASTReader->loadGlobalIndex();
2336 GlobalIndex = TheASTReader->getGlobalIndex();
2340 if (!HaveFullGlobalModuleIndex && GlobalIndex && !
buildingModule()) {
2342 bool RecreateIndex =
false;
2345 Module *TheModule = I->second;
2349 Path.emplace_back(TriggerLoc,
2351 std::reverse(
Path.begin(),
Path.end());
2354 RecreateIndex =
true;
2357 if (RecreateIndex) {
2362 consumeError(std::move(Err));
2365 TheASTReader->resetForReload();
2366 TheASTReader->loadGlobalIndex();
2367 GlobalIndex = TheASTReader->getGlobalIndex();
2369 HaveFullGlobalModuleIndex =
true;
2403 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...
llvm::MachO::Target Target
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.
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.
@ 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.
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.
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.
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::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.
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::Expected< FileEntryRef > getSTDIN()
Get the FileEntryRef for stdin, returning an error if stdin cannot be read.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
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, bool IsText=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.
bool PrepareToExecute(CompilerInstance &CI)
Prepare the action to execute on the given compiler instance.
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
llvm::Error Execute()
Set the source manager's main input file, and run the action.
virtual void EndSourceFile()
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
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.
@ 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.
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_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...
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...
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 ...
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
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.
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 ...
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.
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.