17#include "llvm/ADT/IntrusiveRefCntPtr.h"
18#include "llvm/ADT/ScopeExit.h"
19#include "llvm/Support/AdvisoryLock.h"
20#include "llvm/Support/CrashRecoveryContext.h"
21#include "llvm/Support/VirtualFileSystem.h"
22#include "llvm/TargetParser/Host.h"
34 DependencyConsumerForwarder(std::unique_ptr<DependencyOutputOptions> Opts,
35 StringRef WorkingDirectory, DependencyConsumer &C)
36 : DependencyFileGenerator(*Opts), WorkingDirectory(WorkingDirectory),
37 Opts(std::move(Opts)), C(C) {}
39 void finishedMainFile(DiagnosticsEngine &Diags)
override {
40 C.handleDependencyOutputOpts(*Opts);
41 llvm::SmallString<256> CanonPath;
42 for (
const auto &
File : getDependencies()) {
44 llvm::sys::path::remove_dots(CanonPath,
true);
45 llvm::sys::path::make_absolute(WorkingDirectory, CanonPath);
46 C.handleFileDependency(CanonPath);
51 StringRef WorkingDirectory;
52 std::unique_ptr<DependencyOutputOptions> Opts;
53 DependencyConsumer &C;
60 if (LangOpts.Modules) {
63 Diags->
Report(diag::warn_pch_vfsoverlay_mismatch);
65 if (VFSOverlays.empty()) {
66 Diags->
Report(diag::note_pch_vfsoverlay_empty) <<
Type;
68 std::string Files = llvm::join(VFSOverlays,
"\n");
69 Diags->
Report(diag::note_pch_vfsoverlay_files) <<
Type << Files;
87 PrebuiltModuleListener(PrebuiltModuleFilesT &PrebuiltModuleFiles,
88 llvm::SmallVector<std::string> &NewModuleFiles,
90 const HeaderSearchOptions &HSOpts,
91 const LangOptions &LangOpts, DiagnosticsEngine &Diags,
92 const ArrayRef<StringRef> StableDirs)
93 : PrebuiltModuleFiles(PrebuiltModuleFiles),
94 NewModuleFiles(NewModuleFiles),
95 PrebuiltModulesASTMap(PrebuiltModulesASTMap), ExistingHSOpts(HSOpts),
96 ExistingLangOpts(LangOpts), Diags(Diags), StableDirs(StableDirs) {}
98 bool needsImportVisitation()
const override {
return true; }
99 bool needsInputFileVisitation()
override {
return true; }
100 bool needsSystemInputFileVisitation()
override {
return true; }
104 void visitImport(StringRef ModuleName, StringRef Filename)
override {
105 if (PrebuiltModuleFiles.insert({ModuleName.str(), Filename.str()}).second)
106 NewModuleFiles.push_back(Filename.str());
108 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(Filename);
109 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;
110 if (PrebuiltMapEntry.second)
113 if (
auto It = PrebuiltModulesASTMap.find(CurrentFile);
114 It != PrebuiltModulesASTMap.end() && CurrentFile != Filename)
121 bool visitInputFileAsRequested(StringRef FilenameAsRequested,
122 StringRef Filename,
bool isSystem,
123 bool isOverridden, time_t StoredTime,
124 bool isExplicitModule)
override {
125 if (StableDirs.empty())
127 auto PrebuiltEntryIt = PrebuiltModulesASTMap.find(CurrentFile);
128 if ((PrebuiltEntryIt == PrebuiltModulesASTMap.end()) ||
129 (!PrebuiltEntryIt->second.isInStableDir()))
132 PrebuiltEntryIt->second.setInStableDir(
134 return PrebuiltEntryIt->second.isInStableDir();
138 void visitModuleFile(StringRef Filename,
142 auto PrebuiltEntryIt = PrebuiltModulesASTMap.find(CurrentFile);
143 if ((PrebuiltEntryIt != PrebuiltModulesASTMap.end()) &&
144 !PrebuiltEntryIt->second.isInStableDir())
145 PrebuiltEntryIt->second.updateDependentsNotInStableDirs(
146 PrebuiltModulesASTMap);
147 CurrentFile = Filename;
152 bool ReadHeaderSearchOptions(
const HeaderSearchOptions &HSOpts,
153 StringRef ModuleFilename,
154 StringRef SpecificModuleCachePath,
155 bool Complain)
override {
157 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(CurrentFile);
158 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;
159 if (PrebuiltMapEntry.second)
169 bool ReadHeaderSearchPaths(
const HeaderSearchOptions &HSOpts,
170 bool Complain)
override {
172 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(CurrentFile);
173 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;
174 if (PrebuiltMapEntry.second)
180 return checkHeaderSearchPaths(
181 HSOpts, ExistingHSOpts, Complain ? &Diags :
nullptr, ExistingLangOpts);
185 PrebuiltModuleFilesT &PrebuiltModuleFiles;
186 llvm::SmallVector<std::string> &NewModuleFiles;
188 const HeaderSearchOptions &ExistingHSOpts;
189 const LangOptions &ExistingLangOpts;
190 DiagnosticsEngine &Diags;
191 std::string CurrentFile;
192 const ArrayRef<StringRef> StableDirs;
197static bool visitPrebuiltModule(StringRef PrebuiltModuleFilename,
199 PrebuiltModuleFilesT &ModuleFiles,
206 PrebuiltModuleListener Listener(ModuleFiles, Worklist, PrebuiltModulesASTMap,
210 Listener.visitModuleFile(PrebuiltModuleFilename,
219 while (!Worklist.empty()) {
232static std::string makeObjFileName(StringRef
FileName) {
234 llvm::sys::path::replace_extension(ObjFileName,
"o");
235 return std::string(ObjFileName);
240deduceDepTarget(
const std::string &OutputFile,
242 if (OutputFile !=
"-")
245 if (InputFiles.empty() || !InputFiles.front().isFile())
246 return "clang-scan-deps\\ dependency";
248 return makeObjFileName(InputFiles.front().getFile());
261static std::optional<StringRef> getSimpleMacroName(StringRef
Macro) {
262 StringRef Name =
Macro.split(
"=").first.ltrim(
" \t");
265 auto FinishName = [&]() -> std::optional<StringRef> {
266 StringRef SimpleName = Name.slice(0, I);
267 if (SimpleName.empty())
272 for (; I != Name.size(); ++I) {
281 if (llvm::isAlnum(Name[I]))
290 using MacroOpt = std::pair<StringRef, std::size_t>;
291 std::vector<MacroOpt> SimpleNames;
292 SimpleNames.reserve(PPOpts.
Macros.size());
293 std::size_t Index = 0;
294 for (
const auto &M : PPOpts.
Macros) {
295 auto SName = getSimpleMacroName(M.first);
299 SimpleNames.emplace_back(*SName, Index);
303 llvm::stable_sort(SimpleNames, llvm::less_first());
305 auto NewEnd = std::unique(
306 SimpleNames.rbegin(), SimpleNames.rend(),
307 [](
const MacroOpt &A,
const MacroOpt &B) { return A.first == B.first; });
308 SimpleNames.erase(SimpleNames.begin(), NewEnd.base());
311 decltype(PPOpts.
Macros) NewMacros;
312 NewMacros.reserve(SimpleNames.size());
313 for (std::size_t I = 0, E = SimpleNames.size(); I != E; ++I) {
314 std::size_t OriginalIndex = SimpleNames[I].second;
316 NewMacros.push_back(std::move(PPOpts.
Macros[OriginalIndex]));
318 std::swap(PPOpts.
Macros, NewMacros);
322 DependencyScanningWorkerFilesystem *DepFS;
325 ScanningDependencyDirectivesGetter(FileManager &FileMgr) : DepFS(
nullptr) {
327 auto *
DFS = llvm::dyn_cast<DependencyScanningWorkerFilesystem>(&FS);
329 assert(!DepFS &&
"Found multiple scanning VFSs");
333 assert(DepFS &&
"Did not find scanning VFS");
336 std::unique_ptr<DependencyDirectivesGetter>
337 cloneFor(FileManager &FileMgr)
override {
338 return std::make_unique<ScanningDependencyDirectivesGetter>(FileMgr);
341 std::optional<ArrayRef<dependency_directives_scan::Directive>>
342 operator()(FileEntryRef
File)
override {
343 return DepFS->getDirectiveTokens(
File.getName());
350 DiagOpts.ShowCarets =
false;
361 return llvm::StringSwitch<bool>(Warning)
362 .Cases({
"pch-vfs-diff",
"error=pch-vfs-diff"},
false)
363 .StartsWith(
"no-error=",
false)
369std::unique_ptr<DiagnosticOptions>
371 std::vector<const char *> CLI;
372 for (
const std::string &Arg : CommandLine)
373 CLI.push_back(Arg.c_str());
375 sanitizeDiagOpts(*DiagOpts);
382 std::vector<const char *> CCommandLine(CommandLine.size(),
nullptr);
383 llvm::transform(CommandLine, CCommandLine.begin(),
384 [](
const std::string &Str) { return Str.c_str(); });
391std::unique_ptr<CompilerInvocation>
394 llvm::opt::ArgStringList Argv;
395 for (
const std::string &Str :
ArrayRef(CommandLine).drop_front())
396 Argv.push_back(Str.c_str());
398 auto Invocation = std::make_unique<CompilerInvocation>();
419 DepFS->resetBypassedPathPrefix();
424 if (!ModulesCachePath.empty())
425 DepFS->setBypassedPathPrefix(ModulesCachePath);
428 std::make_unique<ScanningDependencyDirectivesGetter>(
434static std::shared_ptr<CompilerInvocation>
437 auto ScanInvocation = std::make_shared<CompilerInvocation>(Invocation);
439 sanitizeDiagOpts(ScanInvocation->getDiagnosticOpts());
441 ScanInvocation->getPreprocessorOpts().AllowPCHWithDifferentModulesCachePath =
444 if (ScanInvocation->getHeaderSearchOpts().ModulesValidateOncePerBuildSession)
445 ScanInvocation->getHeaderSearchOpts().BuildSessionTimestamp =
448 ScanInvocation->getFrontendOpts().DisableFree =
false;
449 ScanInvocation->getFrontendOpts().GenerateGlobalModuleIndex =
false;
450 ScanInvocation->getFrontendOpts().UseGlobalModuleIndex =
false;
451 ScanInvocation->getFrontendOpts().GenReducedBMI =
false;
452 ScanInvocation->getFrontendOpts().ModuleOutputPath.clear();
455 ScanInvocation->getFrontendOpts().ModulesShareFileManager =
true;
456 ScanInvocation->getHeaderSearchOpts().ModuleFormat =
"raw";
457 ScanInvocation->getHeaderSearchOpts().ModulesIncludeVFSUsage =
465 ScanInvocation->getHeaderSearchOpts().ModulesStrictContextHash =
true;
466 ScanInvocation->getHeaderSearchOpts().ModulesSerializeOnlyPreprocessor =
true;
467 ScanInvocation->getHeaderSearchOpts().ModulesSkipDiagnosticOptions =
true;
468 ScanInvocation->getHeaderSearchOpts().ModulesSkipHeaderSearchPaths =
true;
469 ScanInvocation->getHeaderSearchOpts().ModulesSkipPragmaDiagnosticMappings =
471 ScanInvocation->getHeaderSearchOpts().ModulesForceValidateUserHeaders =
false;
474 ScanInvocation->getPreprocessorOpts().ModulesCheckRelocated =
false;
478 ScanInvocation->getDependencyOutputOpts() = {};
480 return ScanInvocation;
483llvm::SmallVector<StringRef>
490 if (!Sysroot.empty() && (llvm::sys::path::root_directory(Sysroot) != Sysroot))
495std::optional<PrebuiltModulesAttrsMap>
505 if (visitPrebuiltModule(
508 PrebuiltModulesASTMap, ScanInstance.
getDiagnostics(), StableDirs))
511 return PrebuiltModulesASTMap;
516static std::unique_ptr<DependencyOutputOptions>
518 auto Opts = std::make_unique<DependencyOutputOptions>(
522 if (Opts->Targets.empty())
525 Opts->IncludeSystemHeaders =
true;
530std::shared_ptr<ModuleDepCollector>
533 std::unique_ptr<DependencyOutputOptions> DepOutputOpts,
539 std::shared_ptr<ModuleDepCollector> MDC;
543 std::make_shared<DependencyConsumerForwarder>(
544 std::move(DepOutputOpts), WorkingDirectory, Consumer));
548 MDC = std::make_shared<ModuleDepCollector>(
549 Service, std::move(DepOutputOpts), ScanInstance, Consumer, Controller,
550 Inv, std::move(PrebuiltModulesASTMap), StableDirs);
563 std::vector<std::thread> Compiles;
568 void add(llvm::unique_function<
void()> Compile) {
569 std::lock_guard<std::mutex> Lock(Mutex);
571 Compiles.emplace_back(std::move(Compile));
577 std::lock_guard<std::mutex> Lock(Mutex);
582 for (std::thread &Compile : Compiles)
618 if (Timestamp >
CI.getHeaderSearchOpts().BuildSessionTimestamp)
621 if (!
CI.getASTReader())
622 CI.createASTReader();
628 switch (
CI.getASTReader()->ReadASTCore(
630 nullptr, Imported, {}, {}, {},
650 auto Lock = ModCache.
getLock(ModuleFileName);
652 llvm::Error LockErr = Lock->tryLock().moveInto(Owned);
654 if (!LockErr && !Owned)
658 llvm::makeIntrusiveRefCnt<DependencyScanningWorkerFilesystem>(
661 CI.getDiagnostics(), std::move(
VFS));
662 auto DC = std::make_unique<DiagnosticConsumer>();
674 Compiles.add([Lock = std::move(Lock), ModCI1 = std::move(ModCI1),
675 ModCI2 = std::move(ModCI2), DC = std::move(DC),
677 llvm::CrashRecoveryContext CRC;
678 (void)CRC.RunSafely([&] {
680 SingleModuleWithAsyncModuleCompiles Action1(*Service, *Compiles);
681 (void)ModCI1->ExecuteAction(Action1);
683 ModCI2->getPreprocessorOpts().SingleModuleParseMode = false;
684 GenerateModuleFromModuleMapAction Action2;
685 (void)ModCI2->ExecuteAction(Action2);
718 std::string Executable,
719 std::unique_ptr<CompilerInvocation> OriginalInvocation,
721 std::shared_ptr<PCHContainerOperations> PCHContainerOps,
726 canonicalizeDefines(OriginalInvocation->getPreprocessorOpts());
734 MDC->applyDiscoveredDependencies(*OriginalInvocation);
735 Consumer.handleBuildCommand(
736 {Executable, OriginalInvocation->getCC1CommandLine()});
743 auto ScanInvocation =
747 std::optional<AsyncModuleCompiles> AsyncCompiles;
748 if (Service.getOpts().AsyncScanModules) {
750 auto ScanInstanceStorage = std::make_unique<CompilerInstance>(
751 std::make_shared<CompilerInvocation>(*ScanInvocation), PCHContainerOps,
752 std::move(ModCache));
761 auto MaybePrebuiltModulesASTMap =
763 if (!MaybePrebuiltModulesASTMap)
770 AsyncCompiles.emplace();
776 ScanInstanceStorage.emplace(std::move(ScanInvocation),
777 std::move(PCHContainerOps), std::move(ModCache));
780 assert(!DiagConsumerFinished &&
"attempt to reuse finished consumer");
785 auto MaybePrebuiltModulesASTMap =
787 if (!MaybePrebuiltModulesASTMap)
793 ScanInstance, std::move(DepOutputOpts), WorkingDirectory, Consumer,
794 Service, *OriginalInvocation, Controller, *MaybePrebuiltModulesASTMap,
804 DiagConsumerFinished =
true;
808 MDC->applyDiscoveredDependencies(*OriginalInvocation);
809 Consumer.handleBuildCommand(
810 {Executable, OriginalInvocation->getCC1CommandLine()});
817 std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
819 assert(DiagEngineWithDiagOpts &&
"Valid diagnostics engine required!");
820 DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);
821 DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();
824 assert(OverlayFS &&
"OverlayFS required!");
825 bool SawDepFS =
false;
826 OverlayFS->visit([&](llvm::vfs::FileSystem &
VFS) {
827 SawDepFS |= &
VFS == Worker.DepFS.get();
829 assert(SawDepFS &&
"OverlayFS not based on DepFS");
833 CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine);
834 if (!OriginalInvocation) {
835 DiagEngineWithCmdAndOpts->DiagEngine->Report(
836 diag::err_fe_expected_compiler_job)
837 << llvm::join(CommandLine,
" ");
841 if (
any(Worker.Service.getOpts().OptimizeArgs &
843 canonicalizeDefines(OriginalInvocation->getPreprocessorOpts());
846 std::shared_ptr<ModuleCache> ModCache =
848 CIPtr = std::make_unique<CompilerInstance>(
850 Worker.PCHContainerOps, std::move(ModCache));
854 CI, OverlayFS, DiagEngineWithCmdAndOpts->DiagEngine->getClient(),
855 Worker.Service, Worker.DepFS);
858 auto MaybePrebuiltModulesASTMap =
860 if (!MaybePrebuiltModulesASTMap)
863 PrebuiltModuleASTMap = std::move(*MaybePrebuiltModulesASTMap);
879 assert(CIPtr &&
"CIPtr must be initialized before calling this method");
889 llvm::scope_exit CleanUp([&]() {
898 CI, std::make_unique<DependencyOutputOptions>(*OutputOpts), CWD, Consumer,
903 *OriginalInvocation, Controller, PrebuiltModuleASTMap, StableDirs);
908 std::unique_ptr<FrontendAction> Action =
909 std::make_unique<PreprocessOnlyAction>();
911 bool ActionBeginSucceeded = Action->BeginSourceFile(CI, *InputFile);
912 assert(ActionBeginSucceeded &&
"Action BeginSourceFile must succeed");
913 (void)ActionBeginSucceeded;
918 FileID MainFileID =
SM.getMainFileID();
926 assert(!PPFailed &&
"Preprocess must be able to enter the main file.");
928 CB = MDC->getPPCallbacks();
933 MDC->attachToPreprocessor(PP);
934 CB = MDC->getPPCallbacks();
940 FileType, PrevFID, IDLocation);
948 Path.emplace_back(IDLocation,
ModuleID);
951 assert(CB &&
"Must have PPCallbacks after module loading");
962 MDC->applyDiscoveredDependencies(ModuleInvocation);
970 DiagConsumer->finish();
static std::unique_ptr< DependencyOutputOptions > createDependencyOutputOptions(const CompilerInvocation &Invocation)
Creates dependency output options to be reported to the dependency consumer, deducing missing informa...
static std::shared_ptr< CompilerInvocation > createScanCompilerInvocation(const CompilerInvocation &Invocation, const DependencyScanningService &Service)
Creates a CompilerInvocation suitable for the dependency scanner.
Manages (and terminates) the asynchronous compilation of modules.
void add(llvm::unique_function< void()> Compile)
Registers the module compilation, unless this instance is about to be destroyed.
Abstract interface for callback invocations by the ASTReader.
@ ARR_Missing
The client can handle an AST file that cannot load because it is missing.
@ 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.
@ Success
The control block was read successfully.
@ OutOfDate
The AST file is out-of-date relative to its input files, and needs to be regenerated.
@ Missing
The AST file was missing.
Configuration object for making the result of cloneForModuleCompile() thread-safe.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
void clearDependencyCollectors()
void createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)
Create the diagnostics engine using the invocation's diagnostic options and replace any existing one ...
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) override
Attempt to load the given module.
void createFileManager()
Create the file manager and replace any existing one with it.
FileManager & getFileManager() const
Return the current file manager to the caller.
ModuleCache & getModuleCache() const
void addDependencyCollector(std::shared_ptr< DependencyCollector > Listener)
Preprocessor & getPreprocessor() const
Return the current preprocessor.
void createVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS=llvm::vfs::getRealFileSystem(), DiagnosticConsumer *DC=nullptr)
Create a virtual file system instance based on the invocation.
FrontendOptions & getFrontendOpts()
HeaderSearchOptions & getHeaderSearchOpts()
void createSourceManager()
Create the source manager and replace any existing one with it.
CompilerInvocation & getInvocation()
PreprocessorOptions & getPreprocessorOpts()
bool ExecuteAction(FrontendAction &Act)
ExecuteAction - Execute the provided action against the compiler's CompilerInvocation object.
LangOptions & getLangOpts()
void setDependencyDirectivesGetter(std::unique_ptr< DependencyDirectivesGetter > Getter)
std::vector< std::string > getCC1CommandLine() const
Generate cc1-compatible command line arguments from this instance, wrapping the result as a std::vect...
Helper class for holding the data necessary to invoke the compiler.
PreprocessorOptions & getPreprocessorOpts()
static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0=nullptr)
Create a compiler invocation from a list of input options.
DependencyOutputOptions & getDependencyOutputOpts()
FrontendOptions & getFrontendOpts()
Functor that returns the dependency directives for a given file.
Builds a dependency file when attached to a Preprocessor (for includes) and ASTReader (for module imp...
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
Options for controlling the compiler diagnostics engine.
std::vector< std::string > Warnings
The list of -W... options used to alter the diagnostic mappings, with the prefixes removed.
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 Reset(bool soft=false)
Reset the state of the diagnostic object to its initial configuration.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
llvm::vfs::FileSystem & getVirtualFileSystem() const
std::string OutputFile
The output file, if any.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
frontend::ActionKind ProgramAction
The frontend action to perform.
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
The module cache used for compiling modules implicitly.
virtual void prepareForGetLock(StringRef ModuleFilename)=0
May perform any work that only needs to be performed once for multiple calls getLock() with the same ...
virtual std::time_t getModuleTimestamp(StringRef ModuleFilename)=0
Returns 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.
void setBuildingModule(bool BuildingModuleFlag)
Flag indicating whether this instance is building a module.
Describes a module or submodule.
@ Hidden
All of the names in this module are hidden.
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
virtual void EndOfMainFile()
Callback invoked when the end of the main file is reached.
virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID, SourceLocation Loc)
Callback invoked whenever the Lexer moves to a different file for lexing.
virtual void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported)
Callback invoked whenever there was an explicit module-import syntax.
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::string ImplicitPCHInclude
The implicit PCH included at the start of the translation unit, or empty.
bool SingleModuleParseMode
When enabled, preprocessor is in a mode for parsing a single module only.
std::vector< std::pair< std::string, bool > > Macros
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)
Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
Preprocessor-based frontend action that also loads PCH files.
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
The base class of the type hierarchy.
bool initialize(std::unique_ptr< DiagnosticsEngineWithDiagOpts > DiagEngineWithDiagOpts, IntrusiveRefCntPtr< llvm::vfs::OverlayFileSystem > OverlayFS)
bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer, DependencyActionController &Controller)
Dependency scanner callbacks that are used during scanning to influence the behaviour of the scan - f...
virtual void handleBuildCommand(Command Cmd)
bool runInvocation(std::string Executable, std::unique_ptr< CompilerInvocation > Invocation, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, DiagnosticConsumer *DiagConsumer)
The dependency scanning service contains shared configuration and state that is used by the individua...
const DependencyScanningServiceOptions & getOpts() const
void setVFS(llvm::StringSet<> &&VFS)
Update the VFSMap to the one discovered from serializing the AST file.
bool isInStableDir() const
Read-only access to whether the module is made up of dependencies in stable directories.
void addDependent(StringRef ModuleFile)
Add a direct dependent module file, so it can be updated if the current module is from stable directo...
void setInStableDir(bool V=false)
Update whether the prebuilt module resolves entirely in a stable directories.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
SmallVector< StringRef > getInitialStableDirs(const CompilerInstance &ScanInstance)
bool areOptionsInStableDir(const ArrayRef< StringRef > Directories, const HeaderSearchOptions &HSOpts)
Determine if options collected from a module's compilation can safely be considered as stable.
@ VFS
Remove unused -ivfsoverlay arguments.
@ Macros
Canonicalize -D and -U options.
void initializeScanCompilerInstance(CompilerInstance &ScanInstance, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, DiagnosticConsumer *DiagConsumer, DependencyScanningService &Service, IntrusiveRefCntPtr< DependencyScanningWorkerFilesystem > DepFS)
llvm::StringMap< PrebuiltModuleASTAttrs > PrebuiltModulesAttrsMap
Attributes loaded from AST files of prebuilt modules collected prior to ModuleDepCollector creation.
std::unique_ptr< CompilerInvocation > createCompilerInvocation(ArrayRef< std::string > CommandLine, DiagnosticsEngine &Diags)
std::optional< PrebuiltModulesAttrsMap > computePrebuiltModulesASTMap(CompilerInstance &ScanInstance, SmallVector< StringRef > &StableDirs)
std::shared_ptr< ModuleCache > makeInProcessModuleCache(ModuleCacheEntries &Entries)
std::shared_ptr< ModuleDepCollector > initializeScanInstanceDependencyCollector(CompilerInstance &ScanInstance, std::unique_ptr< DependencyOutputOptions > DepOutputOpts, StringRef WorkingDirectory, DependencyConsumer &Consumer, DependencyScanningService &Service, CompilerInvocation &Inv, DependencyActionController &Controller, PrebuiltModulesAttrsMap PrebuiltModulesASTMap, llvm::SmallVector< StringRef > &StableDirs)
Create the dependency collector that will collect the produced dependencies.
std::unique_ptr< DiagnosticOptions > createDiagOptions(ArrayRef< std::string > CommandLine)
bool isPathInStableDir(const ArrayRef< StringRef > Directories, const StringRef Input)
Determine if Input can be resolved within a stable directory.
@ Make
This is the Makefile compatible dep format.
@ Full
This outputs the full clang module dependency graph suitable for use for explicitly building modules.
@ P1689
This outputs the dependency graph for standard c++ modules in P1689R5 format.
@ DependencyDirectivesScan
This mode is used to compute the dependencies by running the preprocessor with special kind of lexing...
@ GeneratePCH
Generate pre-compiled header.
ModuleKind
Specifies the kind of module that has been loaded.
@ MK_ExplicitModule
File is an explicitly-loaded module.
@ MK_ImplicitModule
File is an implicitly-loaded module.
The JSON file list parser is used to communicate input to InstallAPI.
std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Result
The result type of a method or function.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
void normalizeModuleCachePath(FileManager &FileMgr, StringRef Path, SmallVectorImpl< char > &NormalizedPath)
int __ovld __cnfn any(char)
Returns 1 if the most significant bit in any component of x is set; otherwise returns 0.
void moduleLoadSkipped(Module *M) override
Callback invoked whenever a module load was skipped due to enabled single-module-parse-mode.
AsyncModuleCompiles & Compiles
AsyncModuleCompile(CompilerInstance &CI, DependencyScanningService &Service, AsyncModuleCompiles &Compiles)
DependencyScanningService & Service
AsyncModuleCompiles & Compiles
bool BeginSourceFileAction(CompilerInstance &CI) override
Callback at the start of processing a single input.
SingleModuleWithAsyncModuleCompiles(DependencyScanningService &Service, AsyncModuleCompiles &Compiles)
DependencyScanningService & Service
Runs the preprocessor on a TU with single-module-parse-mode and compiles modules asynchronously witho...
bool BeginSourceFileAction(CompilerInstance &CI) override
Callback at the start of processing a single input.
AsyncModuleCompiles & Compiles
DependencyScanningService & Service
SingleTUWithAsyncModuleCompiles(DependencyScanningService &Service, AsyncModuleCompiles &Compiles)
ScanningMode Mode
Whether to use optimized dependency directive scan or full preprocessing.
std::time_t BuildSessionTimestamp
The build session timestamp for validate-once-per-build-session logic.
ScanningOptimizations OptimizeArgs
How to optimize resulting explicit module command lines.
ScanningOutputFormat Format
What output format are we expected to produce.
IntrusiveRefCntPtr< DiagnosticsEngine > DiagEngine
DiagnosticsEngineWithDiagOpts(ArrayRef< std::string > CommandLine, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, DiagnosticConsumer &DC)
std::unique_ptr< DiagnosticOptions > DiagOpts
This is used to identify a specific module.