19 #include "clang/Config/config.h"
36 #include "llvm/ADT/Statistic.h"
37 #include "llvm/Support/CrashRecoveryContext.h"
38 #include "llvm/Support/Errc.h"
39 #include "llvm/Support/FileSystem.h"
40 #include "llvm/Support/Host.h"
41 #include "llvm/Support/LockFileManager.h"
42 #include "llvm/Support/MemoryBuffer.h"
43 #include "llvm/Support/Path.h"
44 #include "llvm/Support/Program.h"
45 #include "llvm/Support/Signals.h"
46 #include "llvm/Support/Timer.h"
47 #include "llvm/Support/raw_ostream.h"
49 #include <system_error>
52 using namespace clang;
54 CompilerInstance::CompilerInstance(
55 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
58 ModuleManager(nullptr), ThePCHContainerOperations(PCHContainerOps),
59 BuildGlobalModuleIndex(
false), HaveFullGlobalModuleIndex(
false),
60 ModuleBuildFailed(
false) {}
63 assert(OutputFiles.empty() &&
"Still output files in flight?");
71 return (BuildGlobalModuleIndex ||
72 (ModuleManager && ModuleManager->isGlobalIndexUnavailable() &&
90 VirtualFileSystem.reset();
106 Consumer = std::move(Value);
110 CompletionConsumer.reset(Value);
114 return std::move(TheSema);
118 return ModuleManager;
121 ModuleManager = Reader;
124 std::shared_ptr<ModuleDependencyCollector>
126 return ModuleDepCollector;
130 std::shared_ptr<ModuleDependencyCollector> Collector) {
131 ModuleDepCollector = Collector;
139 std::unique_ptr<raw_ostream> StreamOwner;
140 raw_ostream *OS = &llvm::errs();
143 auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>(
145 llvm::sys::fs::F_Append | llvm::sys::fs::F_Text);
147 Diags.
Report(diag::warn_fe_cc_log_diagnostics_failure)
150 FileOS->SetUnbuffered();
151 FileOS->SetUseAtomicWrites(
true);
153 StreamOwner = std::move(FileOS);
158 auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
159 std::move(StreamOwner));
169 StringRef OutputFile) {
170 auto SerializedConsumer =
175 Diags.
takeClient(), std::move(SerializedConsumer)));
178 Diags.
getClient(), std::move(SerializedConsumer)));
183 bool ShouldOwnClient) {
191 bool ShouldOwnClient,
200 Diags->setClient(Client, ShouldOwnClient);
205 if (Opts->VerifyDiagnostics)
250 Diags.
Report(diag::err_fe_remap_missing_from_file) << RB.first;
267 Diags.
Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
275 Diags.
Report(diag::err_fe_remap_missing_from_file) << RF.first;
314 PP->setPTHManager(PTHMgr);
318 PP->createPreprocessingRecord();
322 PP->getFileManager(), PPOpts);
330 PP->getLangOpts(), PP->getTargetInfo().getTriple());
334 if (PP->getLangOpts().Modules)
340 TheDependencyFileGenerator.reset(
346 for (
auto &Listener : DependencyCollectors)
347 Listener->attachToPreprocessor(*PP);
352 ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
360 if (OutputPath ==
"-")
378 llvm::sys::path::append(SpecificModuleCache,
380 return SpecificModuleCache.str();
396 StringRef Path,
bool DisablePCHValidation,
bool AllowPCHWithCompilerErrors,
397 void *DeserializationListener,
bool OwnDeserializationListener) {
403 OwnDeserializationListener, Preamble,
408 StringRef Path, StringRef Sysroot,
bool DisablePCHValidation,
411 void *DeserializationListener,
bool OwnDeserializationListener,
412 bool Preamble,
bool UseGlobalModuleIndex) {
416 PP, Context, PCHContainerRdr, Sysroot.empty() ?
"" : Sysroot.data(),
417 DisablePCHValidation, AllowPCHWithCompilerErrors,
419 UseGlobalModuleIndex));
425 Reader->setDeserializationListener(
426 static_cast<ASTDeserializationListener *>(DeserializationListener),
427 OwnDeserializationListener);
428 switch (Reader->ReadAST(Path,
459 const std::string &Filename,
478 if (!CompletionConsumer) {
484 if (!CompletionConsumer)
492 if (CompletionConsumer->isOutputBinary() &&
493 llvm::sys::ChangeStdoutToBinary()) {
500 FrontendTimerGroup.reset(
new llvm::TimerGroup(
"Clang front-end time report"));
502 new llvm::Timer(
"Clang front-end timer", *FrontendTimerGroup));
522 TUKind, CompletionConsumer));
528 assert(OutFile.OS &&
"Attempt to add empty stream to output list!");
529 OutputFiles.push_back(std::move(OutFile));
533 for (OutputFile &OF : OutputFiles) {
537 if (!OF.TempFilename.empty()) {
539 llvm::sys::fs::remove(OF.TempFilename);
545 FileMgr->FixupRelativePath(NewOutFile);
546 if (std::error_code ec =
547 llvm::sys::fs::rename(OF.TempFilename, NewOutFile)) {
549 << OF.TempFilename << OF.Filename << ec.message();
551 llvm::sys::fs::remove(OF.TempFilename);
554 }
else if (!OF.Filename.empty() && EraseFiles)
555 llvm::sys::fs::remove(OF.Filename);
559 NonSeekStream.reset();
564 StringRef Extension) {
566 true, InFile, Extension,
571 auto OS = llvm::make_unique<llvm::raw_null_ostream>();
572 llvm::raw_null_ostream *Ret = OS.get();
579 bool RemoveFileOnSignal, StringRef InFile,
580 StringRef Extension,
bool UseTemporary,
581 bool CreateMissingDirectories) {
582 std::string OutputPathName, TempPathName;
585 OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension,
586 UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName);
593 raw_pwrite_stream *Ret = OS.get();
596 addOutputFile(OutputFile((OutputPathName !=
"-") ? OutputPathName :
"",
597 TempPathName, std::move(OS)));
603 StringRef OutputPath, std::error_code &
Error,
bool Binary,
604 bool RemoveFileOnSignal, StringRef InFile, StringRef Extension,
605 bool UseTemporary,
bool CreateMissingDirectories,
606 std::string *ResultPathName, std::string *TempPathName) {
607 assert((!CreateMissingDirectories || UseTemporary) &&
608 "CreateMissingDirectories is only allowed when using temporary files");
610 std::string OutFile, TempFile;
611 if (!OutputPath.empty()) {
612 OutFile = OutputPath;
613 }
else if (InFile ==
"-") {
615 }
else if (!Extension.empty()) {
617 llvm::sys::path::replace_extension(Path, Extension);
618 OutFile = Path.str();
623 std::unique_ptr<llvm::raw_fd_ostream> OS;
628 UseTemporary =
false;
630 llvm::sys::fs::file_status Status;
631 llvm::sys::fs::status(OutputPath, Status);
632 if (llvm::sys::fs::exists(Status)) {
634 if (!llvm::sys::fs::can_write(OutputPath))
639 if (!llvm::sys::fs::is_regular_file(Status))
640 UseTemporary =
false;
649 TempPath +=
"-%%%%%%%%";
652 llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath);
654 if (CreateMissingDirectories &&
655 EC == llvm::errc::no_such_file_or_directory) {
656 StringRef Parent = llvm::sys::path::parent_path(OutputPath);
657 EC = llvm::sys::fs::create_directories(Parent);
659 EC = llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath);
664 OS.reset(
new llvm::raw_fd_ostream(fd,
true));
665 OSFile = TempFile = TempPath.str();
674 OS.reset(
new llvm::raw_fd_ostream(
676 (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text)));
682 if (RemoveFileOnSignal)
683 llvm::sys::RemoveFileOnSignal(OSFile);
686 *ResultPathName = OutFile;
688 *TempPathName = TempFile;
690 if (!Binary || OS->supportsSeeking())
691 return std::move(OS);
693 auto B = llvm::make_unique<llvm::buffer_ostream>(*OS);
694 assert(!NonSeekStream);
695 NonSeekStream = std::move(OS);
717 std::unique_ptr<llvm::MemoryBuffer>(Input.
getBuffer()), Kind));
719 "Couldn't establish MainFileID!");
723 StringRef InputFile = Input.
getFile();
726 if (InputFile !=
"-") {
729 Diags.
Report(diag::err_fe_error_reading) << InputFile;
742 File = FileMgr.
getVirtualFile(InputFile, (*MB)->getBufferSize(), 0);
745 Diags.
Report(diag::err_cannot_open_file) << InputFile
746 << MB.getError().message();
754 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr =
755 llvm::MemoryBuffer::getSTDIN();
756 if (std::error_code EC = SBOrErr.getError()) {
757 Diags.
Report(diag::err_fe_error_reading_stdin) << EC.message();
760 std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get());
763 SB->getBufferSize(), 0);
770 "Couldn't establish MainFileID!");
777 assert(
hasDiagnostics() &&
"Diagnostics engine is not initialized!");
779 assert(!
getFrontendOpts().ShowVersion &&
"Client must handle '-version'!");
783 raw_ostream &OS = llvm::errs();
804 <<
" based upon " << BACKEND_PACKAGE_STRING
805 <<
" default target " << llvm::sys::getDefaultTargetTriple() <<
"\n";
811 llvm::EnableStatistics();
813 for (
unsigned i = 0, e =
getFrontendOpts().Inputs.size(); i != e; ++i) {
835 OS << NumWarnings <<
" warning" << (NumWarnings == 1 ?
"" :
"s");
836 if (NumWarnings && NumErrors)
839 OS << NumErrors <<
" error" << (NumErrors == 1 ?
"" :
"s");
840 if (NumWarnings || NumErrors)
841 OS <<
" generated.\n";
870 StringRef ModuleFileName) {
882 Invocation->getLangOpts()->resetNonModularOptions();
889 std::remove_if(PPOpts.
Macros.begin(), PPOpts.
Macros.end(),
890 [&HSOpts](
const std::pair<std::string, bool> &def) {
891 StringRef MacroDef = def.first;
912 FrontendOpts.
OutputFile = ModuleFileName.str();
915 FrontendOpts.
Inputs.clear();
921 Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
923 Invocation->getModuleHash() &&
"Module hash mismatch!");
940 Instance.createSourceManager(Instance.getFileManager());
952 std::string InferredModuleMapContent;
956 FrontendOpts.
Inputs.emplace_back(ModuleMapFile->getName(), IK);
959 llvm::sys::path::append(FakeModuleMapFile,
"__inferred_module.map");
960 FrontendOpts.
Inputs.emplace_back(FakeModuleMapFile, IK);
962 llvm::raw_string_ostream OS(InferredModuleMapContent);
966 std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
967 llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
968 ModuleMapFile = Instance.getFileManager().getVirtualFile(
969 FakeModuleMapFile, InferredModuleMapContent.size(), 0);
979 diag::remark_module_build)
980 << Module->
Name << ModuleFileName;
984 const unsigned ThreadStackSize = 8 << 20;
985 llvm::CrashRecoveryContext CRC;
986 CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); },
990 diag::remark_module_build_done)
997 Instance.clearOutputFiles(
true);
1005 return !Instance.getDiagnostics().hasErrorOccurred();
1011 StringRef ModuleFileName) {
1014 auto diagnoseBuildFailure = [&] {
1015 Diags.
Report(ModuleNameLoc, diag::err_module_not_built)
1021 StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
1022 llvm::sys::fs::create_directories(Dir);
1026 llvm::LockFileManager Locked(ModuleFileName);
1028 case llvm::LockFileManager::LFS_Error:
1029 Diags.
Report(ModuleNameLoc, diag::err_module_lock_failure)
1033 case llvm::LockFileManager::LFS_Owned:
1037 diagnoseBuildFailure();
1042 case llvm::LockFileManager::LFS_Shared:
1045 switch (Locked.waitForUnlock()) {
1046 case llvm::LockFileManager::Res_Success:
1049 case llvm::LockFileManager::Res_OwnerDied:
1051 case llvm::LockFileManager::Res_Timeout:
1052 Diags.
Report(ModuleNameLoc, diag::err_module_lock_timeout)
1055 Locked.unsafeRemoveLockFile();
1065 ModuleLoadCapabilities);
1068 Locked == llvm::LockFileManager::LFS_Shared) {
1074 diagnoseBuildFailure();
1078 diagnoseBuildFailure();
1099 for (
auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {
1104 if (
auto *DMD = dyn_cast<DefMacroDirective>(MD))
1105 CmdLineDefinition = DMD->getMacroInfo();
1110 if (CurrentDefinition == CmdLineDefinition) {
1112 }
else if (!CurrentDefinition) {
1115 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1117 auto LatestDef = LatestLocalMD->getDefinition();
1118 assert(LatestDef.isUndefined() &&
1119 "predefined macro went away with no #undef?");
1120 PP.
Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
1123 }
else if (!CmdLineDefinition) {
1126 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1128 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1129 diag::note_module_def_undef_here)
1131 }
else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
1134 PP.
Diag(ImportLoc, diag::warn_module_config_macro_undef)
1136 PP.
Diag(CurrentDefinition->getDefinitionLoc(),
1137 diag::note_module_def_undef_here)
1145 llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None);
1151 struct stat StatBuf;
1154 llvm::sys::path::append(TimestampFile,
"modules.timestamp");
1157 if (::stat(TimestampFile.c_str(), &StatBuf)) {
1159 if (errno == ENOENT) {
1167 time_t TimeStampModTime = StatBuf.st_mtime;
1168 time_t CurrentTime = time(
nullptr);
1181 llvm::sys::path::native(HSOpts.
ModuleCachePath, ModuleCachePathNative);
1182 for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd;
1183 Dir != DirEnd && !EC; Dir.increment(EC)) {
1185 if (!llvm::sys::fs::is_directory(Dir->path()))
1189 for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd;
1190 File != FileEnd && !EC; File.increment(EC)) {
1192 StringRef Extension = llvm::sys::path::extension(File->path());
1193 if (Extension !=
".pcm" && Extension !=
".timestamp" &&
1194 llvm::sys::path::filename(File->path()) !=
"modules.idx")
1199 if (::stat(File->path().c_str(), &StatBuf))
1203 time_t FileAccessTime = StatBuf.st_atime;
1204 if (CurrentTime - FileAccessTime <=
1210 llvm::sys::fs::remove(File->path());
1213 std::string TimpestampFilename = File->path() +
".timestamp";
1214 llvm::sys::fs::remove(TimpestampFilename);
1219 if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
1220 llvm::sys::fs::directory_iterator() && !EC)
1221 llvm::sys::fs::remove(Dir->path());
1226 if (!ModuleManager) {
1240 std::string Sysroot = HSOpts.
Sysroot;
1242 std::unique_ptr<llvm::Timer> ReadTimer;
1243 if (FrontendTimerGroup)
1244 ReadTimer = llvm::make_unique<llvm::Timer>(
"Reading modules",
1245 *FrontendTimerGroup);
1253 std::move(ReadTimer));
1262 ModuleManager->InitializeSema(
getSema());
1270 if (FrontendTimerGroup)
1271 Timer.init(
"Preloading " + FileName.str(), *FrontendTimerGroup);
1272 llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer :
nullptr);
1279 std::vector<StringRef> ModuleFileStack;
1280 std::vector<StringRef> ModuleNameStack;
1282 bool TopFileIsModule;
1285 : CI(CI), Failed(
false), TopFileIsModule(
false) {}
1287 bool needsImportVisitation()
const override {
return true; }
1289 void visitImport(StringRef FileName)
override {
1290 if (!CI.ExplicitlyLoadedModuleFiles.insert(FileName).second) {
1291 if (ModuleFileStack.size() == 0)
1292 TopFileIsModule =
true;
1296 ModuleFileStack.push_back(FileName);
1297 ModuleNameStack.push_back(StringRef());
1303 ? diag::err_module_file_invalid
1304 : diag::err_module_file_not_found)
1306 for (
int I = ModuleFileStack.size() - 2; I >= 0; --I)
1308 diag::note_module_file_imported_by)
1309 << ModuleFileStack[I]
1310 << !ModuleNameStack[I].empty() << ModuleNameStack[I];
1313 ModuleNameStack.pop_back();
1314 ModuleFileStack.pop_back();
1317 void ReadModuleName(StringRef ModuleName)
override {
1318 if (ModuleFileStack.size() == 1)
1319 TopFileIsModule =
true;
1320 ModuleNameStack.back() = ModuleName;
1322 auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
1323 if (!ModuleFile.empty() &&
1327 diag::err_conflicting_module_files)
1328 << ModuleName << ModuleFile << ModuleFileStack.back();
1329 ModuleFile = ModuleFileStack.back();
1346 RMN.visitImport(FileName);
1353 if (!RMN.TopFileIsModule) {
1366 bool IsInclusionDirective) {
1368 StringRef ModuleName = Path[0].first->getName();
1374 if (!ImportLoc.
isInvalid() && LastModuleImportLoc == ImportLoc) {
1378 ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility,
1380 return LastModuleImportResult;
1386 llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
1387 = KnownModules.find(Path[0].first);
1388 if (Known != KnownModules.end()) {
1390 Module = Known->second;
1394 Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
1395 Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
1398 Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
1403 ModuleBuildFailed =
true;
1407 auto Override = ModuleFileOverrides.find(ModuleName);
1408 bool Explicit = Override != ModuleFileOverrides.end();
1409 if (!Explicit && !
getLangOpts().ImplicitModules) {
1412 ModuleBuildFailed =
true;
1416 std::string ModuleFileName =
1417 Explicit ? Override->second
1418 : PP->getHeaderSearchInfo().getModuleFileName(Module);
1424 if (TheDependencyFileGenerator)
1425 TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
1427 if (ModuleDepCollector)
1428 ModuleDepCollector->attachToASTReader(*ModuleManager);
1430 for (
auto &Listener : DependencyCollectors)
1431 Listener->attachToASTReader(*ModuleManager);
1434 if (FrontendTimerGroup)
1435 Timer.init(
"Loading " + ModuleFileName, *FrontendTimerGroup);
1436 llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer :
nullptr);
1441 switch (ModuleManager->ReadAST(ModuleFileName,
1444 ImportLoc, ARRFlags)) {
1453 KnownModules[Path[0].first] =
nullptr;
1458 assert(Module &&
"missing module file");
1461 ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
1462 for (; Pos != PosEnd; ++Pos) {
1463 if (Pos->first == ModuleName)
1467 if (Pos != PosEnd) {
1469 for (; Pos != PosEnd; ++Pos) {
1470 CyclePath += Pos->first;
1471 CyclePath +=
" -> ";
1473 CyclePath += ModuleName;
1476 << ModuleName << CyclePath;
1487 ModuleBuildFailed =
true;
1495 "undiagnosed error in compileAndLoadModule");
1498 KnownModules[Path[0].first] =
nullptr;
1499 ModuleBuildFailed =
true;
1513 KnownModules[Path[0].first] =
nullptr;
1519 KnownModules[Path[0].first] =
nullptr;
1520 ModuleBuildFailed =
true;
1525 Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
1534 if (Path.size() > 1) {
1535 for (
unsigned I = 1, N = Path.size(); I != N; ++I) {
1536 StringRef Name = Path[I].first->getName();
1547 unsigned ED = Name.edit_distance((*J)->Name,
1550 if (ED <= BestEditDistance) {
1551 if (ED < BestEditDistance) {
1553 BestEditDistance = ED;
1556 Best.push_back((*J)->Name);
1561 if (Best.size() == 1) {
1563 diag::err_no_submodule_suggest)
1587 if (ModuleName ==
getLangOpts().ImplementationOfModule)
1602 <<
SourceRange(Path.front().second, Path.back().second);
1614 diag::err_module_header_missing)
1619 << Requirement.second << Requirement.first
1620 <<
SourceRange(Path.front().second, Path.back().second);
1622 LastModuleImportLoc = ImportLoc;
1627 ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc);
1632 for (
unsigned I = 0, N = TopModule->
ConfigMacros.size(); I != N; ++I) {
1637 LastModuleImportLoc = ImportLoc;
1639 return LastModuleImportResult;
1650 ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc);
1662 ModuleManager->loadGlobalIndex();
1667 llvm::sys::fs::create_directories(
1672 ModuleManager->resetForReload();
1673 ModuleManager->loadGlobalIndex();
1674 GlobalIndex = ModuleManager->getGlobalIndex();
1678 if (!HaveFullGlobalModuleIndex && GlobalIndex && !
buildingModule()) {
1680 bool RecreateIndex =
false;
1683 Module *TheModule = I->second;
1687 Path.push_back(std::make_pair(
1689 std::reverse(Path.begin(), Path.end());
1693 RecreateIndex =
true;
1696 if (RecreateIndex) {
1700 ModuleManager->resetForReload();
1701 ModuleManager->loadGlobalIndex();
1702 GlobalIndex = ModuleManager->getGlobalIndex();
1704 HaveFullGlobalModuleIndex =
true;
void AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders=false, StringRef OutputPath="", bool ShowDepth=true, bool MSStyle=false)
std::string OutputFile
The output file, if any.
SourceManager & getSourceManager() const
void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)
Attach an external AST source to the AST context.
static bool compileAndLoadModule(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName)
Defines the clang::ASTContext interface.
virtual bool isModelParsingAction() const
Is this action invoked on a model file?
LangOptions & getLangOpts()
ASTReadResult
The result of reading the control block of an AST file, which can fail for various reasons...
bool hasFileManager() const
ASTContext & getASTContext() const
std::string Name
The name of this module.
CompilerInvocation & getInvocation()
PreprocessorOptions & getPreprocessorOpts()
void createCodeCompletionConsumer()
std::vector< std::pair< std::string, bool > > Macros
std::string ModuleDependencyOutputDir
The directory to copy module dependencies to when collecting them.
DiagnosticConsumer * getClient()
module_iterator module_begin() const
std::string DwarfDebugFlags
SelectorTable & getSelectorTable()
std::string DOTOutputFile
The file to write GraphViz-formatted header dependencies to.
bool hasASTConsumer() const
void createFrontendTimer()
Create the frontend timer and replace any existing one with it.
bool RemappedFilesKeepOriginalName
True if the SourceManager should report the original file name for contents of files that were remapp...
Implements support for file system lookup, file system caching, and directory search management...
void setCodeCompletionConsumer(CodeCompleteConsumer *Value)
vfs::FileSystem & getVirtualFileSystem() const
Defines the clang::FileManager interface and associated types.
void EndSourceFile()
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
void createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
submodule_iterator submodule_begin()
static void writeTimestampFile(StringRef TimestampFile)
Write a new timestamp file with the given path.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Defines the SourceManager interface.
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
Abstract base class for actions which can be performed by the frontend.
DiagnosticOptions & getDiagnosticOpts()
std::string HeaderIncludeOutputFile
bool hasErrorOccurred() const
static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, ASTReaderListener &Listener)
Read the control block for the named AST file.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool InitializeSourceManager(const FrontendInputFile &Input)
std::unique_ptr< DiagnosticConsumer > takeClient()
Return the current diagnostic client along with ownership of that client.
The client can handle an AST file that cannot load because it is out-of-date relative to its input fi...
void setModuleManager(IntrusiveRefCntPtr< ASTReader > Reader)
TargetInfo & getTarget() const
void setSourceManager(SourceManager *Value)
setSourceManager - Replace the current source manager.
std::string getModuleHash() const
Retrieve a module hash string that is suitable for uniquely identifying the conditions under which th...
const FileEntry * getASTFile() const
The serialized AST file for this module, if one was created.
SourceManager & getSourceManager() const
Return the current source manager.
static PTHManager * Create(StringRef file, DiagnosticsEngine &Diags)
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
DependencyOutputOptions & getDependencyOutputOpts()
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Builtin::Context & getBuiltinInfo()
void setPredefines(const char *P)
Set the predefines for this Preprocessor.
The client can handle an AST file that cannot load because it is missing.
virtual void adjust(const LangOptions &Opts)
Set forced language options.
std::string getFullModuleName() const
Retrieve the full name of this module, including the path from its top-level module.
void setMainFileID(FileID FID)
Set the file ID for the main source file.
unsigned getNumWarnings() const
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, DiagnosticsEngine &Diags, StringRef OutputFile)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
void createFileManager()
Create the file manager and replace any existing one with it.
void createSourceManager(FileManager &FileMgr)
Create the source manager and replace any existing one with it.
A source location that has been parsed on the command line.
llvm::SmallPtrSet< ModuleFile *, 4 > HitSet
A set of module files in which we found a result.
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
unsigned DetailedRecord
Whether we should maintain a detailed record of all macro definitions and expansions.
void setASTContext(ASTContext *Value)
setASTContext - Replace the current AST context.
CodeGenOptions & getCodeGenOpts()
bool buildingModule() const
Returns true if this instance is building a module.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
ASTConsumer & getASTConsumer() const
Describes a module or submodule.
FileManager & getFileManager() const
void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, SourceLocation ImportLoc) override
Make the given module visible.
bool SetCodeCompletionPoint(const FileEntry *File, unsigned Line, unsigned Column)
Specify the point at which code-completion will be performed.
void setBuildGlobalModuleIndex(bool Build)
Set the flag indicating whether we should (re)build the global module index.
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
FrontendOptions & getFrontendOpts()
IntrusiveRefCntPtr< vfs::FileSystem > getVirtualFileSystem() const
Visibility
Describes the different kinds of visibility that a declaration may have.
DiagnosticConsumer & getDiagnosticClient() const
PreprocessorOutputOptions & getPreprocessorOutputOpts()
Concrete class used by the front-end to report problems and issues.
HeaderSearch & getHeaderSearchInfo() const
IntrusiveRefCntPtr< FailedModulesSet > FailedModules
The set of modules that failed to build.
module_iterator module_end() const
bool RetainRemappedFileBuffers
Whether the compiler instance should retain (i.e., not free) the buffers associated with remapped fil...
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
unsigned IsFromModuleFile
Whether this module was loaded from a module file.
const FileEntry * getContainingModuleMapFile(const Module *Module) const
Retrieve the module map file containing the definition of the given module.
IntrusiveRefCntPtr< ASTReader > getModuleManager() const
submodule_iterator submodule_end()
void setFileManager(FileManager *Value)
Replace the current file manager and virtual file system.
HeaderSearchOptions & getHeaderSearchOpts()
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...
The AST file itself appears corrupted.
bool DisablePCHValidation
When true, disables most of the normal validation performed on precompiled headers.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
std::vector< Module * >::iterator submodule_iterator
void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener, bool OwnDeserializationListener)
bool hasVirtualFileSystem() const
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...
static ErrorCode writeIndex(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, StringRef Path)
Write a global index into the given.
llvm::StringMap< Module * >::const_iterator module_iterator
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
static DependencyFileGenerator * CreateAndAttachToPreprocessor(Preprocessor &PP, const DependencyOutputOptions &Opts)
Sema - This implements semantic analysis and AST building for C.
void setPreprocessor(Preprocessor *Value)
Replace the current preprocessor.
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, const CodeGenOptions *CodeGenOpts, DiagnosticsEngine &Diags)
std::string CurrentModule
The name of the current module.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
void setVirtualFileSystem(IntrusiveRefCntPtr< vfs::FileSystem > FS)
Replace the current virtual file system.
Describes the result of attempting to load a module.
Exposes information about the current target.
A simple code-completion consumer that prints the results it receives in a simple format...
void setInvocation(CompilerInvocation *Value)
setInvocation - Replace the current invocation.
static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts)
Determine the appropriate source input kind based on language options.
ModuleBuildStack getModuleBuildStack() const
Retrieve the module build stack.
std::string getSpecificModuleCachePath()
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, unsigned LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
Defines version macros and version-related utility functions for Clang.
Defines the clang::Preprocessor interface.
bool hasDiagnostics() const
void createASTContext()
Create the AST context.
unsigned ShowHeaderIncludes
Show header inclusions (-H).
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
static bool EnableCodeCompletion(Preprocessor &PP, const std::string &Filename, unsigned Line, unsigned Column)
void addOutputFile(OutputFile &&OutFile)
The client can't handle any AST loading failures.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
The AST file was missing.
bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
std::unique_ptr< Sema > takeSema()
Options controlling the behavior of code completion.
const DirectoryEntry * Directory
The build directory of this module. This is the directory in which the module is notionally built...
void overrideFileContents(const FileEntry *SourceFile, llvm::MemoryBuffer *Buffer, bool DoNotFree)
Override the contents of the given source file by providing an already-allocated buffer.
bool hasSourceManager() const
FileSystemOptions & getFileSystemOpts()
bool isNamedPipe() const
Check whether the file is a named pipe (and thus can't be opened by the native FileManager methods)...
The control block was read successfully. Aside from failures, the AST file is safe to read into the c...
void setPreprocessor(Preprocessor *pp)
void ApplyHeaderSearchOptions(HeaderSearch &HS, const HeaderSearchOptions &HSOpts, const LangOptions &Lang, const llvm::Triple &triple)
Apply the header search options to get given HeaderSearch object.
bool ExecuteAction(FrontendAction &Act)
File is a PCH file treated as the preamble.
void print(raw_ostream &OS, unsigned Indent=0) const
Print the module map for this module to the given stream.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
const PCHContainerReader & getPCHContainerReader() const
bool Execute()
Set the source manager's main input file, and run the action.
File is a PCH file treated as such.
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
bool isValid() const
Return true if this is a valid SourceLocation object.
Options for controlling the compiler diagnostics engine.
static bool compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName)
Compile a module file for the given module, using the options provided by the importing compiler inst...
std::vector< FrontendInputFile > Inputs
The input files and their types.
virtual void finish()
Callback to inform the diagnostic client that processing of all source files has ended.
All of the names in this module are hidden.
File is an implicitly-loaded module.
IdentifierTable & getIdentifierTable()
Cached information about one file (either on disk or in the virtual file system). ...
void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, StringRef SysRoot)
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
Diagnostic consumer that forwards diagnostics along to an existing, already-initialized diagnostic co...
void ProcessWarningOptions(DiagnosticsEngine &Diags, const DiagnosticOptions &Opts, bool ReportDiags=true)
const FileEntry * getVirtualFile(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...
std::shared_ptr< PCHContainerOperations > getPCHContainerOperations() const
void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc)
Push an entry to the module build stack.
FileID getMainFileID() const
Returns the FileID of the main source file.
unsigned GenerateGlobalModuleIndex
void createPreprocessor(TranslationUnitKind TUKind)
void resetNonModularOptions()
Reset any options that are not considered when building a module.
A global index for a set of module files, providing information about the identifiers within those mo...
The AST file was writtten with a different language/target configuration.
DiagnosticsEngine & getDiagnostics() const
const char * getName() const
FileID getPredefinesFileID() const
Returns the FileID for the preprocessor predefines.
std::string OutputFile
The file to write dependency output to.
Abstract interface for a consumer of code-completion information.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
void setDeserializationListener(ASTDeserializationListener *Listener, bool TakeOwnership=false)
Set the AST deserialization listener.
llvm::raw_null_ostream * createNullOutputFile()
PreprocessorOptions & getPreprocessorOpts()
static void InitializeFileRemapping(DiagnosticsEngine &Diags, SourceManager &SourceMgr, FileManager &FileMgr, const PreprocessorOptions &InitOpts)
Reads an AST files chain containing the contents of a translation unit.
File is an explicitly-loaded module.
FileManager & getFileManager() const
Return the current file manager to the caller.
bool loadModuleFile(StringRef FileName)
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const FileEntry *Entry, bool isVolatile=false, bool ShouldCloseOpenFile=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
unsigned UseGlobalModuleIndex
Used for handling and querying diagnostic IDs.
void setASTMutationListener(ASTMutationListener *Listener)
Attach an AST mutation listener to the AST context.
Helper class for holding the data necessary to invoke the compiler.
static void pruneModuleCache(const HeaderSearchOptions &HSOpts)
Prune the module cache of modules that haven't been accessed in a long time.
FrontendOptions - Options for controlling the behavior of the frontend.
Abstract interface for a module loader.
std::string ImplementationOfModule
The name of the module that the translation unit is an implementation of. Prevents semantic imports...
Defines the Diagnostic-related interfaces.
Encapsulates the data about a macro definition (e.g. its tokens).
SourceLocation DefinitionLoc
The location of the module definition.
void clearOutputFiles(bool EraseFiles)
void BuryPointer(const void *Ptr)
const FileEntry * getModuleMapFileForUniquing(const Module *M) const
Get the module map file that (along with the module name) uniquely identifies this module...
Abstract interface for callback invocations by the ASTReader.
MacroDirective * getLocalMacroDirectiveHistory(const IdentifierInfo *II) const
Given an identifier, return the latest non-imported macro directive for that identifier.
void setOverridenFilesKeepOriginalName(bool value)
Set true if the SourceManager should report the original file name for contents of files that were ov...
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature...
bool hasASTContext() const
void setTarget(TargetInfo *Value)
Replace the current diagnostics engine.
unsigned DisableFree
Disable memory freeing on exit.
raw_pwrite_stream * createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="")
~CompilerInstance() override
bool shouldBuildGlobalModuleIndex() const
Indicates whether we should (re)build the global module index.
std::shared_ptr< ModuleDependencyCollector > getModuleDepCollector() const
void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, const PCHContainerReader &PCHContainerRdr, const FrontendOptions &FEOpts)
void setModuleBuildStack(ModuleBuildStack stack)
Set the module build stack.
TranslationUnitKind
Describes the kind of translation unit being processed.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
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...
Defines the clang::TargetInfo interface.
The AST file is out-of-date relative to its input files, and needs to be regenerated.
A SourceLocation and its associated SourceManager.
NameVisibilityKind
Describes the visibility of the various names within a particular module.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
bool hasPreprocessor() const
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
unsigned getNumErrors() const
The AST file was written by a different version of Clang.
#define CLANG_VERSION_STRING
A string that describes the Clang version number, e.g., "1.0".
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) override
Attempt to load the given module.
void createModuleManager()
}
void setModuleDepCollector(std::shared_ptr< ModuleDependencyCollector > Collector)
GlobalModuleIndex * loadGlobalModuleIndex(SourceLocation TriggerLoc) override
Load, create, or return global module. This function returns an existing global module index...
void InitBuiltinTypes(const TargetInfo &Target)
Initialize built-in types.
bool hadMacroDefinition() const
Returns true if this identifier was #defined to some value at any moment. In this case there should b...
bool ownsClient() const
Determine whether this DiagnosticsEngine object own its client.
A trivial tuple used to represent a source range.
unsigned PrintShowIncludes
Print cl.exe style /showIncludes info.
Records the set of modules.
raw_pwrite_stream * createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal, StringRef BaseInput, StringRef Extension, bool UseTemporary, bool CreateMissingDirectories=false)
This class handles loading and caching of source files into memory.
void setDiagnostics(DiagnosticsEngine *Value)
setDiagnostics - Replace the current diagnostics engine.
void noSignedCharForObjCBool()
std::string DiagnosticLogFile
The file to log diagnostic output to.
std::string TokenCache
If given, a PTH cache file to use for speeding up header parsing.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool lookupIdentifier(StringRef Name, HitSet &Hits)
Look for all of the module files with information about the given identifier, e.g., a global function, variable, or type with that name.