24#include "clang/Config/config.h"
48#include "llvm/ADT/IntrusiveRefCntPtr.h"
49#include "llvm/ADT/STLExtras.h"
50#include "llvm/ADT/ScopeExit.h"
51#include "llvm/ADT/Statistic.h"
52#include "llvm/Config/llvm-config.h"
53#include "llvm/Plugins/PassPlugin.h"
54#include "llvm/Support/AdvisoryLock.h"
55#include "llvm/Support/BuryPointer.h"
56#include "llvm/Support/CrashRecoveryContext.h"
57#include "llvm/Support/Errc.h"
58#include "llvm/Support/FileSystem.h"
59#include "llvm/Support/MemoryBuffer.h"
60#include "llvm/Support/Path.h"
61#include "llvm/Support/Signals.h"
62#include "llvm/Support/SmallVectorMemoryBuffer.h"
63#include "llvm/Support/Threading.h"
64#include "llvm/Support/TimeProfiler.h"
65#include "llvm/Support/Timer.h"
66#include "llvm/Support/VirtualFileSystem.h"
67#include "llvm/Support/VirtualOutputBackends.h"
68#include "llvm/Support/VirtualOutputError.h"
69#include "llvm/Support/raw_ostream.h"
70#include "llvm/TargetParser/Host.h"
77CompilerInstance::CompilerInstance(
78 std::shared_ptr<CompilerInvocation> Invocation,
79 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
80 std::shared_ptr<ModuleCache> ModCache)
82 Invocation(
std::move(Invocation)),
83 ModCache(ModCache ?
std::move(ModCache)
85 ThePCHContainerOperations(
std::move(PCHContainerOps)) {
86 assert(this->Invocation &&
"Invocation must not be null");
90 assert(OutputFiles.empty() &&
"Still output files in flight?");
94 return (BuildGlobalModuleIndex ||
95 (TheASTReader && TheASTReader->isGlobalIndexUnavailable() &&
97 !DisableGeneratingGlobalModuleIndex;
102 Diagnostics = std::move(
Value);
106 OwnedVerboseOutputStream.reset();
107 VerboseOutputStream = &
Value;
111 OwnedVerboseOutputStream.swap(
Value);
112 VerboseOutputStream = OwnedVerboseOutputStream.get();
136 auto &TO = AuxTargetOpts = std::make_unique<TargetOptions>();
177 assert(
Value ==
nullptr ||
179 FileMgr = std::move(
Value);
184 SourceMgr = std::move(
Value);
188 PP = std::move(
Value);
192 assert(Context &&
"Compiler instance has no AST context!");
198 Context = std::move(
Value);
200 if (Context && Consumer)
209 Consumer = std::move(
Value);
211 if (Context && Consumer)
216 CompletionConsumer.reset(
Value);
220 return std::move(TheSema);
227 assert(ModCache.get() == &Reader->getModuleManager().getModuleCache() &&
228 "Expected ASTReader to use the same PCM cache");
229 TheASTReader = std::move(Reader);
232std::shared_ptr<ModuleDependencyCollector>
234 return ModuleDepCollector;
238 std::shared_ptr<ModuleDependencyCollector> Collector) {
239 ModuleDepCollector = std::move(Collector);
243 std::shared_ptr<ModuleDependencyCollector> MDC) {
246 for (
auto &Name : HeaderMapFileNames)
251 std::shared_ptr<ModuleDependencyCollector> MDC) {
258 auto PCHDir =
FileMgr.getOptionalDirectoryRef(PCHInclude);
260 MDC->addFile(PCHInclude);
266 llvm::sys::path::native(PCHDir->getName(), DirNative);
267 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
269 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
270 Dir != DirEnd && !EC; Dir.increment(EC)) {
279 MDC->addFile(Dir->path());
284 std::shared_ptr<ModuleDependencyCollector> MDC) {
288 if (
auto *RedirectingVFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&VFS))
289 llvm::vfs::collectVFSEntries(*RedirectingVFS, VFSEntries);
292 for (
auto &E : VFSEntries)
293 MDC->addFile(E.VPath, E.RPath);
298 bool ShouldOwnClient =
false;
301 ShouldOwnClient =
true;
313 llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(std::move(VFS));
321 std::unique_ptr<raw_ostream> StreamOwner;
322 raw_ostream *OS = &llvm::errs();
325 auto FileOS = std::make_unique<llvm::raw_fd_ostream>(
327 llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
329 Diags.
Report(diag::warn_fe_cc_log_diagnostics_failure)
332 FileOS->SetUnbuffered();
334 StreamOwner = std::move(FileOS);
339 auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
340 std::move(StreamOwner));
354 StringRef OutputFile) {
355 auto SerializedConsumer =
360 Diags.
takeClient(), std::move(SerializedConsumer)));
363 Diags.
getClient(), std::move(SerializedConsumer)));
368 bool ShouldOwnClient) {
377 auto Diags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(
383 Diags->setClient(Client, ShouldOwnClient);
390 if (Opts.VerifyDiagnostics)
409 assert(VFS &&
"CompilerInstance needs a VFS for creating FileManager");
416 assert(Diagnostics &&
"DiagnosticsEngine needed for creating SourceManager");
417 assert(FileMgr &&
"FileManager needed for creating SourceManager");
418 SourceMgr = llvm::makeIntrusiveRefCnt<SourceManager>(
getDiagnostics(),
432 FileMgr.getVirtualFileRef(RB.first, RB.second->getBufferSize(), 0);
439 SourceMgr.overrideFileContents(FromFile, RB.second->getMemBufferRef());
441 SourceMgr.overrideFileContents(
442 FromFile, std::unique_ptr<llvm::MemoryBuffer>(RB.second));
450 Diags.
Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
460 SourceMgr.overrideFileContents(FromFile, *ToFile);
463 SourceMgr.setOverridenFilesKeepOriginalName(
473 TheASTReader.reset();
479 PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOpts(),
488 PP->createPreprocessingRecord();
492 PP->getFileManager(), PPOpts);
501 const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple();
502 if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA &&
503 PP->getAuxTargetInfo())
504 HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple();
507 PP->getLangOpts(), *HeaderSearchTriple);
511 if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {
515 PP->getHeaderSearchInfo().initializeModuleCachePath(
530 ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
536 if (ModuleDepCollector) {
547 for (
auto &Listener : DependencyCollectors)
548 Listener->attachToPreprocessor(*PP);
555 if (OutputPath ==
"-")
568 if (GetDependencyDirectives)
569 PP->setDependencyDirectivesGetter(*GetDependencyDirectives);
573 PP->getDiagnostics().Report(clang::diag::err_fe_text_encoding_config)
574 << PP->getTextEncoding().getLiteralEncoding();
581 auto Context = llvm::makeIntrusiveRefCnt<ASTContext>(
582 getLangOpts(), PP.getSourceManager(), PP.getIdentifierTable(),
583 PP.getSelectorTable(), PP.getBuiltinInfo(), PP.TUKind);
600 void ReadModuleName(StringRef ModuleName)
override {
603 LoadedModules.push_back(ModuleName.str());
608 for (
const std::string &LoadedModule : LoadedModules)
611 LoadedModules.clear();
614 void markAllUnavailable() {
615 for (
const std::string &LoadedModule : LoadedModules) {
618 M->HasIncompatibleModuleFile =
true;
622 SmallVector<Module *, 2> Stack;
624 while (!Stack.empty()) {
625 Module *Current = Stack.pop_back_val();
629 llvm::append_range(Stack, SubmodulesRange);
633 LoadedModules.clear();
640 bool AllowPCHWithCompilerErrors,
void *DeserializationListener,
641 bool OwnDeserializationListener) {
648 DeserializationListener, OwnDeserializationListener,
Preamble,
653 StringRef Path, StringRef Sysroot,
658 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
659 ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
660 void *DeserializationListener,
bool OwnDeserializationListener,
661 bool Preamble,
bool UseGlobalModuleIndex) {
663 PP.getHeaderSearchInfo().getHeaderSearchOpts();
665 auto Reader = llvm::makeIntrusiveRefCnt<ASTReader>(
666 PP, ModCache, &Context, PCHContainerRdr, CodeGenOpts, Extensions,
667 Sysroot.empty() ?
"" : Sysroot.data(), DisableValidation,
668 AllowPCHWithCompilerErrors,
false,
675 Context.setExternalSource(Reader);
677 Reader->setDeserializationListener(
679 OwnDeserializationListener);
681 for (
auto &Listener : DependencyCollectors)
682 Listener->attachToASTReader(*Reader);
684 auto Listener = std::make_unique<ReadModuleNames>(PP);
685 auto &ListenerRef = *Listener;
687 std::move(Listener));
696 PP.setPredefines(Reader->getSuggestedPredefines());
697 ListenerRef.registerAll();
713 ListenerRef.markAllUnavailable();
714 Context.setExternalSource(
nullptr);
740 if (!CompletionConsumer) {
753 timerGroup.reset(
new llvm::TimerGroup(
"clang",
"Clang time report"));
754 FrontendTimer.reset(
new llvm::Timer(
"frontend",
"Front end", *timerGroup));
774 TUKind, CompletionConsumer));
780 if (ExternalSemaSrc) {
781 TheSema->addExternalSource(ExternalSemaSrc);
782 ExternalSemaSrc->InitializeSema(*TheSema);
788 (void)TheSema->APINotes.loadCurrentModuleAPINotes(
800 for (
auto &O : OutputFiles)
801 llvm::handleAllErrors(
803 [&](
const llvm::vfs::TempFileOutputError &E) {
804 getDiagnostics().Report(diag::err_unable_to_rename_temp)
805 << E.getTempPath() << E.getOutputPath()
806 << E.convertToErrorCode().message();
808 [&](
const llvm::vfs::OutputError &E) {
809 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
810 << E.getOutputPath() << E.convertToErrorCode().message();
812 [&](
const llvm::ErrorInfoBase &EIB) {
813 getDiagnostics().Report(diag::err_fe_unable_to_open_output)
814 << O.getPath() << EIB.message();
818 if (DeleteBuiltModules) {
819 for (
auto &
Module : BuiltModules)
820 llvm::sys::fs::remove(
Module.second);
821 BuiltModules.clear();
826 bool Binary, StringRef InFile, StringRef Extension,
bool RemoveFileOnSignal,
827 bool CreateMissingDirectories,
bool ForceUseTemporary,
828 bool SetOnlyIfDifferent) {
830 std::optional<SmallString<128>> PathStorage;
831 if (OutputPath.empty()) {
832 if (InFile ==
"-" || Extension.empty()) {
835 PathStorage.emplace(InFile);
836 llvm::sys::path::replace_extension(*PathStorage, Extension);
837 OutputPath = *PathStorage;
843 CreateMissingDirectories, SetOnlyIfDifferent);
847 return std::make_unique<llvm::raw_null_ostream>();
854 assert(!OutputMgr &&
"Already has an output manager");
855 OutputMgr = std::move(NewOutputs);
859 assert(!OutputMgr &&
"Already has an output manager");
860 OutputMgr = llvm::makeIntrusiveRefCnt<llvm::vfs::OnDiskOutputBackend>();
875 StringRef OutputPath,
bool Binary,
bool RemoveFileOnSignal,
876 bool UseTemporary,
bool CreateMissingDirectories,
bool SetOnlyIfDifferent) {
878 createOutputFileImpl(OutputPath,
Binary, RemoveFileOnSignal, UseTemporary,
879 CreateMissingDirectories, SetOnlyIfDifferent);
881 return std::move(*OS);
883 << OutputPath << errorToErrorCode(OS.takeError()).message();
888CompilerInstance::createOutputFileImpl(StringRef OutputPath,
bool Binary,
889 bool RemoveFileOnSignal,
891 bool CreateMissingDirectories,
892 bool SetOnlyIfDifferent) {
893 assert((!CreateMissingDirectories || UseTemporary) &&
894 "CreateMissingDirectories is only allowed when using temporary files");
898 std::optional<SmallString<128>> AbsPath;
899 if (OutputPath !=
"-" && !llvm::sys::path::is_absolute(OutputPath)) {
901 "File Manager is required to fix up relative path.\n");
903 AbsPath.emplace(OutputPath);
905 OutputPath = *AbsPath;
913 .setDiscardOnSignal(RemoveFileOnSignal)
914 .setAtomicWrite(UseTemporary)
915 .setImplyCreateDirectories(UseTemporary && CreateMissingDirectories)
916 .setOnlyIfDifferent(SetOnlyIfDifferent));
918 return O.takeError();
920 O->discardOnDestroy([](llvm::Error E) { consumeError(std::move(E)); });
921 OutputFiles.push_back(std::move(*O));
922 return OutputFiles.back().createProxy();
944 SourceMgr.setMainFileID(SourceMgr.createFileID(Input.
getBuffer(), Kind));
945 assert(SourceMgr.getMainFileID().isValid() &&
946 "Couldn't establish MainFileID!");
950 StringRef InputFile = Input.
getFile();
953 auto FileOrErr = InputFile ==
"-"
955 : FileMgr.getFileRef(InputFile,
true);
957 auto EC = llvm::errorToErrorCode(FileOrErr.takeError());
958 if (InputFile !=
"-")
959 Diags.
Report(diag::err_fe_error_reading) << InputFile << EC.message();
961 Diags.
Report(diag::err_fe_error_reading_stdin) << EC.message();
965 SourceMgr.setMainFileID(
968 assert(SourceMgr.getMainFileID().isValid() &&
969 "Couldn't establish MainFileID!");
975void CompilerInstance::PrepareForExecution() {
992 assert(
hasDiagnostics() &&
"Diagnostics engine is not initialized!");
994 assert(!
getFrontendOpts().ShowVersion &&
"Client must handle '-version'!");
996 llvm::TimeTraceScope TimeScope(
"ExecuteCompiler");
998 PrepareForExecution();
1019 OS <<
"clang -cc1 version " CLANG_VERSION_STRING <<
" based upon LLVM "
1020 << LLVM_VERSION_STRING <<
" default target "
1021 << llvm::sys::getDefaultTargetTriple() <<
"\n";
1024 llvm::EnableStatistics(
false);
1037 ModuleImportResults.clear();
1040 if (llvm::Error Err = Act.
Execute()) {
1041 consumeError(std::move(Err));
1054 llvm::PrintStatistics(OS);
1057 if (!StatsFile.empty()) {
1058 llvm::sys::fs::OpenFlags FileFlags = llvm::sys::fs::OF_TextWithCRLF;
1060 FileFlags |= llvm::sys::fs::OF_Append;
1063 std::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, FileFlags);
1066 << StatsFile << EC.message();
1068 llvm::PrintStatisticsJSON(*StatS);
1087 OS << NumWarnings <<
" warning" << (NumWarnings == 1 ?
"" :
"s");
1088 if (NumWarnings && NumErrors)
1091 OS << NumErrors <<
" error" << (NumErrors == 1 ?
"" :
"s");
1092 if (NumWarnings || NumErrors) {
1096 OS <<
" when compiling for host";
1098 OS <<
" when compiling for "
1111 if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &
Error))
1118 if (
auto PassPlugin = llvm::PassPlugin::load(Path)) {
1119 PassPlugins.emplace_back(std::make_unique<llvm::PassPlugin>(*PassPlugin));
1122 << Path <<
toString(PassPlugin.takeError());
1127 for (
const FrontendPluginRegistry::entry &Plugin :
1128 FrontendPluginRegistry::entries()) {
1129 std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
1141 auto Args = std::make_unique<const char *[]>(NumArgs + 2);
1142 Args[0] =
"clang (LLVM option parsing)";
1143 for (
unsigned i = 0; i != NumArgs; ++i)
1145 Args[NumArgs + 1] =
nullptr;
1146 llvm::cl::parseCommandLineOptions(LibraryOptions,
1156 if (LangOpts.OpenCL)
1165std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl(
1169 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1171 auto Invocation = std::make_shared<CompilerInvocation>(
getInvocation());
1173 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
1177 Invocation->resetNonModularOptions();
1181 HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
1182 llvm::erase_if(PPOpts.
Macros,
1183 [&HSOpts](
const std::pair<std::string, bool> &def) {
1184 StringRef MacroDef = def.first;
1185 return HSOpts.ModulesIgnoreMacros.contains(
1186 llvm::CachedHashString(MacroDef.split(
'=').first));
1194 [&HSOpts](
const HeaderSearchOptions::Entry &E) {
1195 return HSOpts.ModulesIgnoreSearchPaths.contains(
1196 llvm::CachedHashString(E.Path));
1201 Invocation->getLangOpts().ModuleName =
1205 Invocation->getLangOpts().CurrentModule = std::string(ModuleName);
1210 FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();
1211 FrontendOpts.
OutputFile = ModuleFileName.str();
1218 FrontendOpts.
Inputs = {std::move(Input)};
1223 DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts();
1225 DiagOpts.VerifyDiagnostics = 0;
1228 "Module hash mismatch!");
1230 std::shared_ptr<ModuleCache> ModCache;
1231 if (ThreadSafeConfig) {
1232 ModCache = ThreadSafeConfig->getModuleCache();
1234 ModCache = this->ModCache;
1238 auto InstancePtr = std::make_unique<CompilerInstance>(
1240 auto &Instance = *InstancePtr;
1242 auto &
Inv = Instance.getInvocation();
1244 if (ThreadSafeConfig) {
1245 Instance.setVirtualFileSystem(ThreadSafeConfig->getVFS());
1246 Instance.createFileManager();
1252 Instance.createFileManager();
1255 if (ThreadSafeConfig) {
1256 Instance.createDiagnostics(&ThreadSafeConfig->getDiagConsumer(),
1259 Instance.createDiagnostics(
1264 Instance.getDiagnostics().setSuppressSystemWarnings(
false);
1266 Instance.createSourceManager();
1267 SourceManager &SourceMgr = Instance.getSourceManager();
1269 if (ThreadSafeConfig) {
1275 SourceMgr.pushModuleBuildStack(
1280 Instance.FailedModules = FailedModules;
1285 Instance.setInheritedDirectoryDependencies(DirectoryDependencies);
1290 if (GetDependencyDirectives)
1291 Instance.GetDependencyDirectives =
1292 GetDependencyDirectives->cloneFor(Instance.getFileManager());
1294 if (ThreadSafeConfig) {
1295 Instance.setModuleDepCollector(ThreadSafeConfig->getModuleDepCollector());
1302 Inv.getDependencyOutputOpts() = DependencyOutputOptions();
1308class PrettyStackTraceBuildModule :
public llvm::PrettyStackTraceEntry {
1309 StringRef ModuleName;
1310 StringRef ModuleFileName;
1313 PrettyStackTraceBuildModule(StringRef ModuleName, StringRef ModuleFileName)
1314 : ModuleName(ModuleName), ModuleFileName(ModuleFileName) {}
1315 void print(raw_ostream &OS)
const override {
1316 OS <<
"Building module '" << ModuleName <<
"' as '" << ModuleFileName
1322std::unique_ptr<llvm::MemoryBuffer>
1325 CompilerInstance &Instance) {
1326 PrettyStackTraceBuildModule CrashInfo(ModuleName,
ModuleFileName);
1327 llvm::TimeTraceScope TimeScope(
"Module Compile", ModuleName);
1344 uint64_t ParentTID = llvm::get_threadid();
1345 bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnNewStack(
1348 <<
"module_compile_thread: parent=" << ParentTID
1351 auto OS = std::make_unique<llvm::raw_svector_ostream>(Buffer);
1353 std::unique_ptr<FrontendAction> Action =
1354 std::make_unique<GenerateModuleFromModuleMapAction>(std::move(OS));
1356 if (
auto WrapGenModuleAction = Instance.getGenModuleActionWrapper())
1357 Action = WrapGenModuleAction(Instance.getFrontendOpts(),
1360 Instance.ExecuteAction(*Action);
1372 FailedModules = std::move(Instance.FailedModules);
1377 Instance.setSema(
nullptr);
1378 Instance.setASTConsumer(
nullptr);
1381 Instance.clearOutputFiles(
true);
1395 if (Instance.getDiagnostics().hasErrorOccurred() &&
1396 !Instance.getFrontendOpts().AllowPCMWithCompilerErrors)
1401 return std::make_unique<llvm::SmallVectorMemoryBuffer>(
1402 std::move(Buffer), Instance.getFrontendOpts().OutputFile,
1408 StringRef Filename = llvm::sys::path::filename(
File.getName());
1410 if (Filename ==
"module_private.map")
1411 llvm::sys::path::append(PublicFilename,
"module.map");
1412 else if (Filename ==
"module.private.modulemap")
1413 llvm::sys::path::append(PublicFilename,
"module.modulemap");
1415 return std::nullopt;
1416 return FileMgr.getOptionalFileRef(PublicFilename);
1421 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig) {
1437 while (Loc.
isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) {
1438 ModuleMapFID = SourceMgr.getFileID(Loc);
1439 Loc = SourceMgr.getIncludeLoc(ModuleMapFID);
1443 SourceMgr.getFileEntryRefForID(ModuleMapFID);
1444 assert(ModuleMapFile &&
"Top-level module map with no FileID");
1451 ModuleMapFile = PublicMMFile;
1463 return cloneForModuleCompileImpl(
1464 ImportLoc, ModuleName,
1475 llvm::sys::path::append(FakeModuleMapFile,
"__inferred_module.map");
1477 std::string InferredModuleMapContent;
1478 llvm::raw_string_ostream OS(InferredModuleMapContent);
1481 auto Instance = cloneForModuleCompileImpl(
1482 ImportLoc, ModuleName,
1487 std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
1488 llvm::MemoryBuffer::getMemBufferCopy(InferredModuleMapContent);
1489 FileEntryRef ModuleMapFile = Instance->getFileManager().getVirtualFileRef(
1490 FakeModuleMapFile, InferredModuleMapContent.size(), 0);
1491 Instance->getSourceManager().overrideFileContents(ModuleMapFile,
1492 std::move(ModuleMapBuffer));
1504 bool *OutOfDate,
bool *Missing) {
1515 ModuleLoadCapabilities);
1545 std::unique_ptr<llvm::MemoryBuffer> Buffer;
1557 diag::err_module_not_built)
1569 diag::err_module_not_written)
1587 StringRef ExtractedBuffer = Rdr.
ExtractPCH(*Buffer);
1590 Buffer = llvm::MemoryBuffer::getMemBufferCopy(ExtractedBuffer);
1628 if (llvm::Error Err = Lock->tryLock().moveInto(Owned)) {
1651 switch (Lock->waitForUnlockFor(std::chrono::seconds(Timeout))) {
1652 case llvm::WaitForUnlockResult::Success:
1654 case llvm::WaitForUnlockResult::OwnerDied:
1656 case llvm::WaitForUnlockResult::Timeout:
1663 Lock->unsafeUnlock();
1668 bool OutOfDate =
false;
1669 bool Missing =
false;
1673 if (!OutOfDate && !Missing)
1733 for (
auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
1735 FileID FID = SourceMgr.getFileID(MDLoc);
1741 !SourceMgr.isWrittenInCommandLineFile(MDLoc))
1743 if (
auto *DMD = dyn_cast<DefMacroDirective>(MD))
1744 CmdLineDefinition = DMD->getMacroInfo();
1749 if (CurrentDefinition == CmdLineDefinition) {
1751 }
else if (!CurrentDefinition) {
1754 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1756 auto LatestDef = LatestLocalMD->getDefinition();
1757 assert(LatestDef.isUndefined() &&
1758 "predefined macro went away with no #undef?");
1759 PP.
Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
1762 }
else if (!CmdLineDefinition) {
1765 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1767 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1768 diag::note_module_def_undef_here)
1770 }
else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
1773 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1775 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1776 diag::note_module_def_undef_here)
1784 for (
const StringRef ConMacro : TopModule->
ConfigMacros) {
1800 .getHeaderSearchInfo()
1801 .getSpecificModuleCachePath()
1808 std::string Sysroot = HSOpts.
Sysroot;
1811 std::unique_ptr<llvm::Timer> ReadTimer;
1814 ReadTimer = std::make_unique<llvm::Timer>(
"reading_modules",
1815 "Reading modules", *timerGroup);
1816 TheASTReader = llvm::makeIntrusiveRefCnt<ASTReader>(
1820 Sysroot.empty() ?
"" : Sysroot.c_str(),
1829 TheASTReader->setDeserializationListener(
1836 TheASTReader->InitializeSema(
getSema());
1840 for (
auto &Listener : DependencyCollectors)
1841 Listener->attachToASTReader(*TheASTReader);
1848 Timer.init(
"preloading." + std::string(
FileName.str()),
1849 "Preloading " + std::string(
FileName.str()), *timerGroup);
1850 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1858 bool ConfigMismatchIsRecoverable =
1863 auto Listener = std::make_unique<ReadModuleNames>(*PP);
1864 auto &ListenerRef = *Listener;
1866 std::move(Listener));
1869 switch (TheASTReader->ReadAST(
1872 &LoadedModuleFile)) {
1876 ListenerRef.registerAll();
1882 diag::warn_ast_file_config_mismatch)
1886 ListenerRef.markAllUnavailable();
1898 MS_PrebuiltModulePath,
1899 MS_ModuleBuildPragma
1907 const std::map<std::string, std::string, std::less<>> &BuiltModules,
1909 assert(ModuleFilename.
empty() &&
"Already has a module source?");
1913 auto BuiltModuleIt = BuiltModules.find(ModuleName);
1914 if (BuiltModuleIt != BuiltModules.end()) {
1916 return MS_ModuleBuildPragma;
1926 if (!ModuleFilename.
empty())
1927 return MS_PrebuiltModulePath;
1933 return MS_ModuleCache;
1936 return MS_ModuleNotFound;
1941 bool IsInclusionDirective) {
1945 HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
1955 ModuleFileName ModuleFilename;
1956 ModuleSource Source =
1958 SourceLocation ModuleNameLoc = ModuleNameRange.
getBegin();
1959 if (Source == MS_ModuleNotFound) {
1962 << ModuleName << ModuleNameRange;
1965 if (ModuleFilename.
empty()) {
1984 Timer.init(
"loading." + std::string(ModuleFilename.
str()),
1985 "Loading " + std::string(ModuleFilename.
str()), *timerGroup);
1986 llvm::TimeRegion TimeLoading(timerGroup ? &Timer :
nullptr);
1987 llvm::TimeTraceScope TimeScope(
"Module Load", ModuleName);
1991 unsigned ARRFlags = Source == MS_ModuleCache
1994 : Source == MS_PrebuiltModulePath
1998 Source == MS_PrebuiltModulePath
2000 : Source == MS_ModuleBuildPragma
2003 ImportLoc, ARRFlags)) {
2007 assert(Source != MS_ModuleCache &&
2008 "missing module, but file loaded from cache");
2012 M = HS.
lookupModule(ModuleName, ImportLoc,
true, !IsInclusionDirective);
2017 getASTReader()->getModuleManager().makeKey(ModuleFilename))
2022 return ModuleLoadResult();
2031 if (Source == MS_PrebuiltModulePath)
2035 diag::warn_ast_file_config_mismatch)
2044 return ModuleLoadResult();
2048 return ModuleLoadResult();
2052 if (Source != MS_ModuleCache) {
2056 return ModuleLoadResult();
2060 assert(M &&
"missing module, but trying to compile for cache");
2064 ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
2065 for (; Pos != PosEnd; ++Pos) {
2066 if (Pos->first == ModuleName)
2070 if (Pos != PosEnd) {
2071 SmallString<256> CyclePath;
2072 for (; Pos != PosEnd; ++Pos) {
2073 CyclePath += Pos->first;
2074 CyclePath +=
" -> ";
2076 CyclePath += ModuleName;
2079 << ModuleName << CyclePath;
2084 if (FailedModules.contains(ModuleName)) {
2086 << ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
2094 "undiagnosed error in compileModuleAndReadAST");
2095 FailedModules.insert(ModuleName);
2107 bool IsInclusionDirective) {
2109 StringRef ModuleName = Path[0].getIdentifierInfo()->getName();
2116 auto CacheIt = ModuleImportResults.find(ImportLoc);
2117 if (CacheIt != ModuleImportResults.end()) {
2118 if (CacheIt->second && ModuleName !=
getLangOpts().CurrentModule)
2119 TheASTReader->makeModuleVisible(CacheIt->second,
Visibility, ImportLoc);
2120 return CacheIt->second;
2135 }
else if (ModuleName ==
getLangOpts().CurrentModule) {
2137 Module = PP->getHeaderSearchInfo().lookupModule(
2138 ModuleName, ImportLoc,
true,
2139 !IsInclusionDirective);
2151 ModuleName, ImportLoc,
true, !IsInclusionDirective);
2154 PPCb->moduleLoadSkipped(
Module);
2157 std::vector<clang::Module *> Worklist{
Module};
2158 while (!Worklist.empty()) {
2160 Worklist.pop_back();
2163 Worklist.push_back(SubM);
2168 SourceLocation ModuleNameEndLoc = Path.back().getLoc().getLocWithOffset(
2169 Path.back().getIdentifierInfo()->getLength());
2172 IsInclusionDirective);
2176 DisableGeneratingGlobalModuleIndex =
true;
2188 bool MapPrivateSubModToTopLevel =
false;
2189 for (
unsigned I = 1, N = Path.size(); I != N; ++I) {
2190 StringRef Name = Path[I].getIdentifierInfo()->getName();
2199 PrivateModule.append(
"_Private");
2202 auto &II = PP->getIdentifierTable().get(
2203 PrivateModule, PP->getIdentifierInfo(
Module->
Name)->getTokenID());
2204 PrivPath.emplace_back(Path[0].getLoc(), &II);
2208 if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, ImportLoc,
true,
2209 !IsInclusionDirective) ||
2211 PP->getHeaderSearchInfo()) != MS_ModuleNotFound)
2214 MapPrivateSubModToTopLevel =
true;
2215 PP->markClangModuleAsAffecting(
Module);
2217 diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
2219 diag::warn_no_priv_submodule_use_toplevel)
2222 <<
SourceRange(Path[0].getLoc(), Path[I].getLoc())
2226 diag::note_private_top_level_defined);
2234 unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();
2238 Name.edit_distance(SubModule->Name,
2239 true, BestEditDistance);
2240 if (ED <= BestEditDistance) {
2241 if (ED < BestEditDistance) {
2243 BestEditDistance = ED;
2246 Best.push_back(SubModule->Name);
2251 if (Best.size() == 1) {
2253 diag::err_no_submodule_suggest)
2255 << Best[0] <<
SourceRange(Path[0].getLoc(), Path[I - 1].getLoc())
2268 <<
SourceRange(Path[0].getLoc(), Path[I - 1].getLoc());
2287 <<
SourceRange(Path.front().getLoc(), Path.back().getLoc());
2296 <<
SourceRange(Path.front().getLoc(), Path.back().getLoc());
2315 StringRef ModuleName,
2319 for (
auto &
C : CleanModuleName)
2328 if (std::error_code EC = llvm::sys::fs::createTemporaryFile(
2334 std::string ModuleMapFileName = (CleanModuleName +
".map").str();
2341 std::string NullTerminatedSource(Source.str());
2343 auto Other = cloneForModuleCompileImpl(ImportLoc, ModuleName, Input,
2349 ModuleMapFileName, NullTerminatedSource.size(), 0);
2350 Other->getSourceManager().overrideFileContents(
2351 ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));
2353 Other->BuiltModules = std::move(BuiltModules);
2354 Other->DeleteBuiltModules =
false;
2357 std::unique_ptr<llvm::MemoryBuffer> Buffer =
2359 BuiltModules = std::move(
Other->BuiltModules);
2362 llvm::raw_fd_ostream OS(FD,
true);
2363 BuiltModules[std::string(ModuleName)] = std::string(
ModuleFileName);
2364 OS << Buffer->getBuffer();
2377 TheASTReader->makeModuleVisible(Mod,
Visibility, ImportLoc);
2383 .getHeaderSearchInfo()
2384 .getSpecificModuleCachePath()
2394 TheASTReader->loadGlobalIndex();
2399 llvm::sys::fs::create_directories(
2400 getPreprocessor().getHeaderSearchInfo().getSpecificModuleCachePath());
2404 .getHeaderSearchInfo()
2405 .getSpecificModuleCachePath())) {
2410 consumeError(std::move(Err));
2413 TheASTReader->resetForReload();
2414 TheASTReader->loadGlobalIndex();
2415 GlobalIndex = TheASTReader->getGlobalIndex();
2419 if (!HaveFullGlobalModuleIndex && GlobalIndex && !
buildingModule()) {
2425 bool RecreateIndex =
false;
2428 Module *TheModule = I->second;
2431 Path.emplace_back(TriggerLoc,
2433 std::reverse(Path.begin(), Path.end());
2436 RecreateIndex =
true;
2439 if (RecreateIndex) {
2443 .getHeaderSearchInfo()
2444 .getSpecificModuleCachePath())) {
2446 consumeError(std::move(Err));
2449 TheASTReader->resetForReload();
2450 TheASTReader->loadGlobalIndex();
2451 GlobalIndex = TheASTReader->getGlobalIndex();
2453 HaveFullGlobalModuleIndex =
true;
2487 ExternalSemaSrc = std::move(ESS);
Defines the clang::ASTContext interface.
Defines a logger where each line is written atomically to the file.
Defines the Diagnostic-related interfaces.
static void collectVFSEntries(CompilerInstance &CI, std::shared_ptr< ModuleDependencyCollector > MDC)
static bool EnableCodeCompletion(Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column)
static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, ModuleFileName 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 readASTAfterCompileModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, ModuleFileName ModuleFileName, bool *OutOfDate, bool *Missing)
Read the AST right after compiling the module.
static CompileOrReadResult compileModuleBehindLockOrRead(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, ModuleFileName ModuleFileName)
Attempt to compile the module in a separate compiler instance behind a lock (to avoid building the sa...
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)
CompileOrReadResult
The result of compileModuleBehindLockOrRead().
@ Compiled
We successfully compiled the module and we still need to read it.
@ Read
We read a module file compiled by another instance.
@ FailedToRead
We failed to read the module file compiled by another instance.
@ FailedToCompile
We failed to compile the module.
static 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 ModuleSource selectModuleSource(Module *M, StringRef ModuleName, ModuleFileName &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 compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, ModuleFileName ModuleFileName)
Compile a module in a separate compiler instance.
static void checkConfigMacros(Preprocessor &PP, Module *M, SourceLocation ImportLoc)
static void SetUpDiagnosticLog(DiagnosticOptions &DiagOpts, const CodeGenOptions *CodeGenOpts, DiagnosticsEngine &Diags)
Defines the clang::FileManager interface and associated types.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
static void print(llvm::raw_ostream &OS, const T &V, const Context &Ctx, QualType Ty)
static StringRef getTriple(const Command &Job)
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the SourceManager interface.
Defines utilities for dealing with stack allocation and stack space.
Defines version macros and version-related utility functions for Clang.
virtual void Initialize(ASTContext &Context)
Initialize - This is called to initialize the consumer, providing the ASTContext.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void setASTMutationListener(ASTMutationListener *Listener)
Attach an AST mutation listener to the AST context.
void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)
Attach an external AST source to the AST context.
Abstract interface for callback invocations by the ASTReader.
RAII object to temporarily add an AST callback listener.
@ ARR_Missing
The client can handle an AST file that cannot load because it is missing.
@ ARR_None
The client can't handle any AST loading failures.
@ ARR_ConfigurationMismatch
The client can handle an AST file that cannot load because it's compiled configuration doesn't match ...
@ ARR_OutOfDate
The client can handle an AST file that cannot load because it is out-of-date relative to its input fi...
@ ARR_TreatModuleWithErrorsAsOutOfDate
If a module file is marked with errors treat it as out-of-date so the caller can rebuild it.
static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, ASTReaderListener &Listener, bool ValidateDiagnosticOptions, unsigned ClientLoadCapabilities=ARR_ConfigurationMismatch|ARR_OutOfDate)
Read the control block for the named AST file.
ASTReadResult
The result of reading the control block of an AST file, which can fail for various reasons.
@ Success
The control block was read successfully.
@ ConfigurationMismatch
The AST file was written with a different language/target configuration.
@ OutOfDate
The AST file is out-of-date relative to its input files, and needs to be regenerated.
@ Failure
The AST file itself appears corrupted.
@ VersionMismatch
The AST file was written by a different version of Clang.
@ HadErrors
The AST file has errors.
@ Missing
The AST file was missing.
ChainedDiagnosticConsumer - Chain two diagnostic clients so that diagnostics go to the first client a...
Abstract interface for a consumer of code-completion information.
Options controlling the behavior of code completion.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string DwarfDebugFlags
The string to embed in the debug information for the compile unit, if non-empty.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
bool hasOutputManager() const
bool loadModuleFile(ModuleFileName FileName, serialization::ModuleFile *&LoadedModuleFile)
void createPCHExternalASTSource(StringRef Path, DisableValidationForModuleKind DisableValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener, bool OwnDeserializationListener)
Create an external AST source to read a PCH file and attach it to the AST context.
DiagnosticConsumer & getDiagnosticClient() const
~CompilerInstance() override
void createPreprocessor(TranslationUnitKind TUKind)
Create the preprocessor, using the invocation, file, and source managers, and replace any existing on...
bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
Check global module index for missing imports.
void setOutputManager(IntrusiveRefCntPtr< llvm::vfs::OutputBackend > NewOutputs)
Set the output manager.
void createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
Create the diagnostics engine using the invocation's diagnostic options and replace any existing one ...
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false, bool SetOnlyIfDifferent=false)
Create the default output file (from the invocation's options) and add it to the list of tracked outp...
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.
void setExternalSemaSource(IntrusiveRefCntPtr< ExternalSemaSource > ESS)
GenModuleActionWrapperFunc getGenModuleActionWrapper() const
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) override
Attempt to load the given module.
FileSystemOptions & getFileSystemOpts()
llvm::Timer & getFrontendTimer() const
bool InitializeSourceManager(const FrontendInputFile &Input)
InitializeSourceManager - Initialize the source manager to set InputFile as the main file.
void createFileManager()
Create the file manager and replace any existing one with it.
FileManager & getFileManager() const
Return the current file manager to the caller.
void setBuildGlobalModuleIndex(bool Build)
Set the flag indicating whether we should (re)build the global module index.
void createOutputManager()
Create an output manager.
std::unique_ptr< Sema > takeSema()
std::unique_ptr< llvm::MemoryBuffer > 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 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.
bool hasASTContext() const
void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName, StringRef Source) override
Attempt to create the given module from the specified source buffer.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext & getASTContext() const
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
void LoadRequestedPlugins()
Load the list of plugins requested in the FrontendOptions.
TargetOptions & getTargetOpts()
void createVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS=llvm::vfs::getRealFileSystem(), DiagnosticConsumer *DC=nullptr)
Create a virtual file system instance based on the invocation.
void setASTReader(IntrusiveRefCntPtr< ASTReader > Reader)
FrontendOptions & getFrontendOpts()
std::shared_ptr< ModuleDependencyCollector > getModuleDepCollector() const
bool hasDiagnostics() const
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
std::unique_ptr< CompilerInstance > cloneForModuleCompile(SourceLocation ImportLoc, const Module *Module, StringRef ModuleFileName, std::optional< ThreadSafeCloneConfig > ThreadSafeConfig=std::nullopt)
Creates a new CompilerInstance for compiling a module.
std::unique_ptr< raw_pwrite_stream > createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal, bool UseTemporary, bool CreateMissingDirectories=false, bool SetOnlyIfDifferent=false)
Create a new output file, optionally deriving the output path name, and add it to the list of tracked...
void setSourceManager(llvm::IntrusiveRefCntPtr< SourceManager > Value)
setSourceManager - Replace the current source manager.
void setASTContext(llvm::IntrusiveRefCntPtr< ASTContext > Value)
setASTContext - Replace the current AST context.
HeaderSearchOptions & getHeaderSearchOpts()
void createFrontendTimer()
Create the frontend timer and replace any existing one with it.
void parseLLVMArgs()
Parse and apply LLVM command line arguments from FrontendOptions.
void createSourceManager()
Create the source manager and replace any existing one with it.
CompilerInvocation & getInvocation()
void setVerboseOutputStream(raw_ostream &Value)
Replace the current stream for verbose output.
PreprocessorOptions & getPreprocessorOpts()
IntrusiveRefCntPtr< ASTContext > getASTContextPtr() const
ASTConsumer & getASTConsumer() const
void setFileManager(IntrusiveRefCntPtr< FileManager > Value)
Replace the current file manager.
TargetInfo & getTarget() const
llvm::vfs::OutputBackend & getOutputManager()
llvm::vfs::FileSystem & getVirtualFileSystem() const
void createCodeCompletionConsumer()
Create a code completion consumer using the invocation; note that this will cause the source manager ...
void setCodeCompletionConsumer(CodeCompleteConsumer *Value)
setCodeCompletionConsumer - Replace the current code completion consumer; the compiler instance takes...
bool ExecuteAction(FrontendAction &Act)
ExecuteAction - Execute the provided action against the compiler's CompilerInvocation object.
std::shared_ptr< PCHContainerOperations > getPCHContainerOperations() const
void clearOutputFiles(bool EraseFiles)
clearOutputFiles - Clear the output file list.
DiagnosticOptions & getDiagnosticOpts()
LangOptions & getLangOpts()
llvm::vfs::OutputBackend & getOrCreateOutputManager()
CodeGenOptions & getCodeGenOpts()
SourceManager & getSourceManager() const
Return the current source manager.
void setDiagnostics(llvm::IntrusiveRefCntPtr< DiagnosticsEngine > Value)
setDiagnostics - Replace the current diagnostics engine.
bool shouldBuildGlobalModuleIndex() const
Indicates whether we should (re)build the global module index.
bool hasSourceManager() const
bool hasASTConsumer() const
APINotesOptions & getAPINotesOpts()
std::unique_ptr< raw_pwrite_stream > createNullOutputFile()
void setAuxTarget(TargetInfo *Value)
Replace the current AuxTarget.
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, SourceLocation ImportLoc) override
Make the given module visible.
bool hasPreprocessor() const
void setPreprocessor(std::shared_ptr< Preprocessor > Value)
Replace the current preprocessor.
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
LangOptions & getLangOpts()
Mutable getters.
FrontendOptions & getFrontendOpts()
std::string computeContextHash() const
Compute the context hash - a string that uniquely identifies compiler settings.
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
ShowIncludesDestination ShowIncludesDest
Destination of cl.exe style /showIncludes info.
std::string DOTOutputFile
The file to write GraphViz-formatted header dependencies to.
std::string ModuleDependencyOutputDir
The directory to copy module dependencies to when collecting them.
std::string OutputFile
The file to write dependency output to.
std::string HeaderIncludeOutputFile
The file to write header include output to.
unsigned ShowHeaderIncludes
Show header inclusions (-H).
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
unsigned getNumErrors() const
unsigned getNumWarnings() const
static llvm::IntrusiveRefCntPtr< DiagnosticIDs > create()
Options for controlling the compiler diagnostics engine.
std::string DiagnosticLogFile
The file to log diagnostic output to.
std::vector< std::string > SystemHeaderWarningsModules
The list of -Wsystem-headers-in-module=... options used to override whether -Wsystem-headers is enabl...
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool hasErrorOccurred() const
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
std::unique_ptr< DiagnosticConsumer > takeClient()
Return the current diagnostic client along with ownership of that client.
DiagnosticConsumer * getClient()
Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const
Based on the way the client configured the DiagnosticsEngine object, classify the specified diagnosti...
bool ownsClient() const
Determine whether this DiagnosticsEngine object own its client.
StringRef getName() const
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
StringRef getNameAsRequested() const
The name of this FileEntry, as originally requested without applying any remappings for VFS 'use-exte...
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
void AddStats(const FileManager &Other)
Import statistics from a child FileManager and add them to this current FileManager.
static bool fixupRelativePath(const FileSystemOptions &FileSystemOpts, SmallVectorImpl< char > &Path)
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Get a FileEntryRef if it exists, without doing anything on error.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
Abstract base class for actions which can be performed by the frontend.
virtual void EndSourceFile()
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
bool PrepareToExecute(CompilerInstance &CI)
Prepare the action to execute on the given compiler instance.
llvm::Error Execute()
Set the source manager's main input file, and run the action.
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
virtual bool isModelParsingAction() const
Is this action invoked on a model file?
FrontendOptions - Options for controlling the behavior of the frontend.
unsigned BuildingImplicitModule
Whether we are performing an implicit module build.
unsigned AllowPCMWithCompilerErrors
Output (and read) PCM files regardless of compiler errors.
unsigned BuildingImplicitModuleUsesLock
Whether to use a filesystem lock when building implicit modules.
unsigned ModulesShareFileManager
Whether to share the FileManager when building modules.
std::vector< std::string > LLVMArgs
A list of arguments to forward to LLVM's option processing; this should only be used for debugging an...
std::optional< std::string > AuxTargetCPU
Auxiliary target CPU for CUDA/HIP compilation.
std::string StatsFile
Filename to write statistics to.
std::string OutputFile
The output file, if any.
std::string ActionName
The name of the action to run when using a plugin action.
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
std::string OriginalModuleMap
When the input is a module map, the original module map file from which that map was inferred,...
unsigned GenerateGlobalModuleIndex
Whether we can generate the global module index if needed.
unsigned DisableFree
Disable memory freeing on exit.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
frontend::ActionKind ProgramAction
The frontend action to perform.
std::optional< std::vector< std::string > > AuxTargetFeatures
Auxiliary target features for CUDA/HIP compilation.
unsigned ImplicitModulesLockTimeoutSeconds
The time in seconds to wait on an implicit module lock before timing out.
A global index for a set of module files, providing information about the identifiers within those mo...
llvm::SmallPtrSet< ModuleFile *, 4 > HitSet
A set of module files in which we found a result.
bool lookupIdentifier(llvm::StringRef Name, HitSet &Hits)
Look for all of the module files with information about the given identifier, e.g....
static llvm::Error writeIndex(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, llvm::StringRef Path)
Write a global index into the given.
One of these records is kept for each identifier that is lexed.
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment.
llvm::MemoryBuffer & addBuiltPCM(llvm::StringRef Filename, std::unique_ptr< llvm::MemoryBuffer > Buffer, off_t Size, time_t ModTime)
Store a just-built PCM under the Filename.
@ 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.
AtomicLineLogger & getLogger()
virtual std::error_code write(StringRef Path, llvm::MemoryBufferRef Buffer, off_t &Size, time_t &ModTime)=0
Write the PCM contents to the given path in the module cache.
virtual InMemoryModuleCache & getInMemoryModuleCache()=0
Returns this process's view of the module cache.
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.
Identifies a module file to be loaded.
bool empty() const
Checks whether the module file name is empty.
static ModuleFileName makeExplicit(std::string Name)
Creates a file name for an explicit module.
StringRef str() const
Returns the plain module file name.
Describes the result of attempting to load a module.
bool buildingModule() const
Returns true if this instance is building a module.
ModuleLoader(bool BuildingModule=false)
llvm::StringMap< Module * >::const_iterator module_iterator
module_iterator module_begin() const
OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const
std::optional< Module * > getCachedModuleLoad(const IdentifierInfo &II)
Return a cached module load.
module_iterator module_end() const
FileID getContainingModuleMapFileID(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
void resolveLinkAsDependencies(Module *Mod)
Use PendingLinkAsModule information to mark top level link names that are going to be replaced by exp...
void cacheModuleLoad(const IdentifierInfo &II, Module *M)
Cache a module load. M might be nullptr.
void loadAllParsedModules()
Module * findOrLoadModule(StringRef Name)
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
unsigned IsUnimportable
Whether this module has declared itself unimportable, either because it's missing a requirement from ...
NameVisibilityKind
Describes the visibility of the various names within a particular module.
@ Hidden
All of the names in this module are hidden.
void print(raw_ostream &OS, unsigned Indent=0, bool Dump=false) const
Print the module map for this module to the given stream.
const ModuleFileKey * getASTFileKey() const
The serialized AST file key for this module, if one was created.
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()
ArrayRef< std::string > getDirectoryDependencies() const
OptionalDirectoryEntryRef Directory
The build directory of this module.
ModuleRef findSubmodule(StringRef Name) const
Find the submodule with the given name.
unsigned IsFromModuleFile
Whether this module was loaded from a module file.
unsigned HasIncompatibleModuleFile
Whether we tried and failed to load a module file for this module.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
unsigned IsAvailable
Whether this module is available in the current translation unit.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
This abstract interface provides operations for unwrapping containers for serialized ASTs (precompile...
virtual llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const =0
Returns the serialized AST inside the PCH container Buffer.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
@ ReplaceAction
Replace the main action.
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::vector< std::pair< std::string, std::string > > RemappedFiles
The set of file remappings, which take existing files on the system (the first part of each pair) and...
std::pair< unsigned, bool > PrecompiledPreambleBytes
If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...
bool RemappedFilesKeepOriginalName
True if the SourceManager should report the original file name for contents of files that were remapp...
bool RetainRemappedFileBuffers
Whether the compiler instance should retain (i.e., not free) the buffers associated with remapped fil...
bool DetailedRecord
Whether we should maintain a detailed record of all macro definitions and expansions.
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
DisableValidationForModuleKind DisablePCHOrModuleValidation
Whether to disable most of the normal validation performed on precompiled headers and module files.
std::vector< std::pair< std::string, bool > > Macros
std::vector< std::pair< std::string, llvm::MemoryBuffer * > > RemappedFileBuffers
The set of file-to-buffer remappings, which take existing files on the system (the first part of each...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
MacroDirective * getLocalMacroDirectiveHistory(const IdentifierInfo *II) const
Given an identifier, return the latest non-imported macro directive for that identifier.
bool SetCodeCompletionPoint(FileEntryRef File, unsigned Line, unsigned Column)
Specify the point at which code-completion will be performed.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
FileManager & getFileManager() const
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
HeaderSearch & getHeaderSearchInfo() const
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
A simple code-completion consumer that prints the results it receives in a simple format.
Sema - This implements semantic analysis and AST building for C.
ASTReaderListenter implementation to set SuggestedPredefines of ASTReader which is required to use a ...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
ModuleBuildStack getModuleBuildStack() const
Retrieve the module build stack.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
CharacteristicKind getFileCharacteristic() const
Return whether this is a system header or not.
This is a discriminated union of FileInfo and ExpansionInfo.
const FileInfo & getFile() const
Exposes information about the current target.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, TargetOptions &Opts)
Construct a target for the given options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual void setAuxTarget(const TargetInfo *Aux)
void noSignedCharForObjCBool()
virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts, const TargetInfo *Aux)
Set forced language options.
std::string CPU
If given, the name of the target CPU to generate code for.
static std::error_code setConvertersFromOptions(TextEncoding &TE, const clang::LangOptions &Opts)
VerifyDiagnosticConsumer - Create a diagnostic client which will use markers in the input source to c...
Information about a module that has been loaded by the ASTReader.
Defines the clang::TargetInfo interface.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
@ HeaderSearch
Remove unused header search paths including header maps.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ PluginAction
Run a plugin action,.
@ RewriteObjC
ObjC->C Rewriter.
@ 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.
Top level wrappers for InstallAPI frontend operations.
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
ArrayRef< IdentifierLoc > ModuleIdPath
A sequence of identifier/location pairs used to describe a particular module or submodule,...
ArrayRef< std::pair< std::string, FullSourceLoc > > ModuleBuildStack
The stack used when building modules on demand, which is used to provide a link between the source ma...
void ApplyHeaderSearchOptions(HeaderSearch &HS, const HeaderSearchOptions &HSOpts, const LangOptions &Lang, const llvm::Triple &triple)
Apply the header search options to get given HeaderSearch object.
std::shared_ptr< ModuleCache > createCrossProcessModuleCache()
Creates new ModuleCache backed by a file system directory that may be operated on by multiple process...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, const PCHContainerReader &PCHContainerRdr, const FrontendOptions &FEOpts, const CodeGenOptions &CodeGenOpts)
InitializePreprocessor - Initialize the preprocessor getting it and the environment ready to process ...
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
Language
The language for the input, used to select and validate the language standard and possible actions.
@ C
Languages that the frontend can parse and compile.
@ Result
The result type of a method or function.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
constexpr size_t DesiredStackSize
The amount of stack space that Clang would like to be provided with.
void noteBottomOfStack(bool ForceSet=false)
Call this once on each thread, as soon after starting the thread as feasible, to note the approximate...
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, llvm::vfs::FileSystem &VFS, bool ReportDiags=true)
ProcessWarningOptions - Initialize the diagnostic client and process the warning options specified on...
TranslationUnitKind
Describes the kind of translation unit being processed.
void AttachHeaderIncludeGen(Preprocessor &PP, const DependencyOutputOptions &DepOpts, bool ShowAllHeaders=false, StringRef OutputPath={}, bool ShowDepth=true, bool MSStyle=false)
AttachHeaderIncludeGen - Create a header include list generator, and attach it to the given preproces...
DisableValidationForModuleKind
Whether to disable the normal validation performed on precompiled headers and module files when they ...
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...
__builtin_riscv_nclipru_u32 __builtin_riscv_nclip_i32 int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 __builtin_riscv_mqwacc_i64 uint8_t
A source location that has been parsed on the command line.