43#include "llvm/ADT/ScopeExit.h"
44#include "llvm/ADT/SmallPtrSet.h"
45#include "llvm/ADT/StringRef.h"
46#include "llvm/Support/BuryPointer.h"
47#include "llvm/Support/ErrorHandling.h"
48#include "llvm/Support/FileSystem.h"
49#include "llvm/Support/Path.h"
50#include "llvm/Support/Timer.h"
51#include "llvm/Support/raw_ostream.h"
53#include <system_error>
73class DeserializedDeclsSourceRangePrinter :
public ASTConsumer,
76 explicit DeserializedDeclsSourceRangePrinter(
77 SourceManager &SM, std::unique_ptr<llvm::raw_fd_ostream> OS)
78 : ASTDeserializationListener(), SM(SM), OS(std::move(OS)) {}
80 ASTDeserializationListener *GetASTDeserializationListener()
override {
84 void DeclRead(GlobalDeclID ID,
const Decl *D)
override {
85 if (!IsCollectingDecls)
98 if (!DC || !shouldIncludeDeclsIn(DC))
101 PendingDecls.push_back(D);
103 ProcessedDeclContexts.insert(DC).second;
104 DC = DC->getLexicalParent()) {
117 bool operator<(
const Position &other)
const {
118 return std::tie(Line, Column) < std::tie(other.Line, other.Column);
121 static Position GetBeginSpelling(
const SourceManager &
SM,
122 const CharSourceRange &R) {
123 SourceLocation Begin =
R.getBegin();
124 return {
SM.getSpellingLineNumber(Begin),
125 SM.getSpellingColumnNumber(Begin)};
128 static Position GetEndSpelling(
const SourceManager &
SM,
129 const CharSourceRange &Range,
130 const LangOptions &LangOpts) {
133 SourceLocation End =
R.getEnd();
138 if (PossiblySemi.
is(tok::semi))
141 return {
SM.getSpellingLineNumber(End),
SM.getSpellingColumnNumber(End)};
145 struct RequiredRanges {
147 std::vector<std::pair<Position, Position>> FromTo;
149 void HandleTranslationUnit(ASTContext &Context)
override {
150 assert(IsCollectingDecls &&
"HandleTranslationUnit called twice?");
151 IsCollectingDecls =
false;
155 std::vector<std::pair<Position, Position>> FromTo;
158 llvm::DenseMap<const FileEntry *, FileData> FileToRanges;
160 for (
const Decl *D : PendingDecls) {
161 for (CharSourceRange R : getRangesToMark(D)) {
165 auto *F = SM.getFileEntryForID(SM.getFileID(
R.getBegin()));
166 if (F != SM.getFileEntryForID(SM.getFileID(
R.getEnd()))) {
171 auto &
Data = FileToRanges[F];
173 Data.Ref = SM.getFileEntryRefForID(SM.getFileID(
R.getBegin()));
174 Data.FromTo.push_back(
175 {Position::GetBeginSpelling(SM, R),
176 Position::GetEndSpelling(SM, R, D->
getLangOpts())});
181 std::vector<RequiredRanges>
Result;
182 for (
auto &[F,
Data] : FileToRanges) {
183 auto &FromTo =
Data.FromTo;
184 assert(!FromTo.empty());
191 std::vector<std::pair<Position, Position>> MergedRanges;
192 MergedRanges.push_back(FromTo.front());
193 for (
auto It = FromTo.begin() + 1; It < FromTo.end(); ++It) {
194 if (MergedRanges.back().second < It->first) {
195 MergedRanges.push_back(*It);
198 if (MergedRanges.back().second < It->second)
199 MergedRanges.back().second = It->second;
201 Result.push_back({
Data.Ref->getName(), std::move(MergedRanges)});
207 std::vector<const Decl *> PendingDecls;
208 llvm::SmallPtrSet<const DeclContext *, 0> ProcessedDeclContexts;
209 bool IsCollectingDecls =
true;
210 const SourceManager &SM;
211 std::unique_ptr<llvm::raw_ostream> OS;
213 static bool shouldIncludeDeclsIn(
const DeclContext *DC) {
214 assert(DC &&
"DC is null");
226 llvm_unreachable(
"DeclContext chain must end with a translation unit");
229 llvm::SmallVector<CharSourceRange, 2> getRangesToMark(
const Decl *D) {
230 if (
auto *ED = dyn_cast<ExportDecl>(D)) {
231 if (!ED->hasBraces())
232 return {SM.getExpansionRange(ED->getExportLoc())};
234 return {SM.getExpansionRange(SourceRange(
236 lexForLBrace(ED->getExportLoc(), D->
getLangOpts()))),
237 SM.getExpansionRange(ED->getRBraceLoc())};
240 auto *NS = dyn_cast<NamespaceDecl>(D);
244 SourceLocation LBraceLoc;
245 if (NS->isAnonymousNamespace()) {
246 LBraceLoc = NS->getLocation();
249 SourceLocation TokenBeforeLBrace = NS->getLocation();
250 if (NS->hasAttrs()) {
251 for (
auto *A : NS->getAttrs()) {
253 if (SM.isBeforeInTranslationUnit(TokenBeforeLBrace,
254 A->getRange().getEnd())) {
261 LBraceLoc = lexForLBrace(TokenBeforeLBrace, D->
getLangOpts());
263 return {SM.getExpansionRange(SourceRange(NS->getBeginLoc(), LBraceLoc)),
264 SM.getExpansionRange(NS->getRBraceLoc())};
267 void printJson(llvm::ArrayRef<RequiredRanges>
Result) {
269 *OS << R
"( "required_ranges": [)" << "\n";
270 for (
size_t I = 0; I <
Result.size(); ++I) {
271 auto &F =
Result[I].Filename;
272 auto &MergedRanges =
Result[I].FromTo;
273 *OS << R
"( {)" << "\n";
274 *OS << R
"( "file": ")" << F << "\"," <<
"\n";
275 *OS << R
"( "range": [)" << "\n";
276 for (
size_t J = 0; J < MergedRanges.size(); ++J) {
277 auto &From = MergedRanges[J].first;
278 auto &To = MergedRanges[J].second;
279 *OS << R
"( {)" << "\n";
280 *OS << R
"( "from": {)" << "\n";
281 *OS << R
"( "line": )" << From.Line << ",\n";
282 *OS << R
"( "column": )" << From.Column << "\n"
284 *OS << R
"( "to": {)" << "\n";
285 *OS << R
"( "line": )" << To.Line << ",\n";
286 *OS << R
"( "column": )" << To.Column << "\n"
289 if (J < MergedRanges.size() - 1) {
294 *OS <<
" ]" <<
"\n" <<
" }";
295 if (I <
Result.size() - 1)
305 SourceLocation lexForLBrace(SourceLocation TokenBeforeLBrace,
306 const LangOptions &LangOpts) {
314 return SourceLocation();
323 explicit DeserializedDeclsDumper(ASTDeserializationListener *
Previous,
325 : DelegatingDeserializationListener(
Previous, DeletePrevious) {}
327 void DeclRead(GlobalDeclID ID,
const Decl *D)
override {
329 if (
const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
330 llvm::outs() <<
" - ";
331 ND->printQualifiedName(llvm::outs());
333 llvm::outs() <<
"\n";
343 std::set<std::string> NamesToCheck;
346 DeserializedDeclsChecker(ASTContext &Ctx,
347 const std::set<std::string> &NamesToCheck,
348 ASTDeserializationListener *
Previous,
350 : DelegatingDeserializationListener(
Previous, DeletePrevious), Ctx(Ctx),
351 NamesToCheck(NamesToCheck) {}
353 void DeclRead(GlobalDeclID ID,
const Decl *D)
override {
354 if (
const NamedDecl *ND = dyn_cast<NamedDecl>(D))
355 if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
358 "%0 was deserialized");
359 Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->
getLocation()), DiagID)
374 std::unique_ptr<ASTUnit> AST) {
375 this->CurrentInput = CurrentInput;
376 CurrentASTUnit = std::move(AST);
385std::unique_ptr<ASTConsumer>
392 std::vector<std::unique_ptr<ASTConsumer>> Consumers;
393 llvm::StringRef DumpDeserializedDeclarationRangesPath =
395 if (!DumpDeserializedDeclarationRangesPath.empty()) {
396 std::error_code ErrorCode;
397 auto FileStream = std::make_unique<llvm::raw_fd_ostream>(
398 DumpDeserializedDeclarationRangesPath, ErrorCode,
399 llvm::sys::fs::OF_TextWithCRLF);
401 Consumers.push_back(std::make_unique<DeserializedDeclsSourceRangePrinter>(
404 llvm::errs() <<
"Failed to create output file for "
405 "-dump-minimization-hints flag, file path: "
406 << DumpDeserializedDeclarationRangesPath
407 <<
", error: " << ErrorCode.message() <<
"\n";
412 bool FoundAllPlugins =
true;
415 for (
const FrontendPluginRegistry::entry &Plugin :
416 FrontendPluginRegistry::entries()) {
417 if (Plugin.getName() == Arg)
422 FoundAllPlugins =
false;
425 if (!FoundAllPlugins)
434 std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
435 for (
const FrontendPluginRegistry::entry &Plugin :
436 FrontendPluginRegistry::entries()) {
437 std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
456 std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
458 Consumers.push_back(std::move(PluginConsumer));
460 AfterConsumers.push_back(std::move(PluginConsumer));
466 Consumers.push_back(std::move(Consumer));
467 if (!AfterConsumers.empty()) {
472 for (
auto &
C : AfterConsumers)
473 Consumers.push_back(std::move(
C));
476 assert(Consumers.size() >= 1 &&
"should have added the main consumer");
477 if (Consumers.size() == 1)
478 return std::move(Consumers.front());
479 return std::make_unique<MultiplexConsumer>(std::move(Consumers));
492 std::string &InputFile,
493 bool IsModuleMap =
false) {
497 auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);
501 auto RawLexer = std::make_unique<Lexer>(MainFileID, *MainFileBuf, SourceMgr,
510 if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
512 if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
513 T.getKind() != tok::numeric_constant)
521 .getAsInteger(10, LineNo))
525 RawLexer->LexFromRawLexer(T);
526 if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
531 if (Literal.hadError)
533 RawLexer->LexFromRawLexer(T);
534 if (T.isNot(tok::eof) && !T.isAtStartOfLine())
536 InputFile = Literal.GetString().str();
540 LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile),
false,
543 return T.getLocation();
548 Includes.append(RHS.begin(), RHS.end());
556 if (IsExternC && LangOpts.CPlusPlus)
557 Includes +=
"extern \"C\" {\n";
559 Includes +=
"#import \"";
561 Includes +=
"#include \"";
563 Includes += HeaderName;
566 if (IsExternC && LangOpts.CPlusPlus)
582 return std::error_code();
594 Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
595 << MissingHeader.IsUmbrella << MissingHeader.FileName;
596 return std::error_code();
613 if (std::optional<Module::Header> UmbrellaHeader =
620 }
else if (std::optional<Module::DirectoryName> UmbrellaDir =
625 llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);
627 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
629 for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
630 Dir != End && !EC; Dir.increment(EC)) {
633 if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
634 .Cases({
".h",
".H",
".hh",
".hpp"},
true)
640 auto PathIt = llvm::sys::path::rbegin(Dir->path());
641 for (
int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
642 Components.push_back(*PathIt);
644 UmbrellaDir->PathRelativeToRootModuleDirectory);
645 for (
auto It = Components.rbegin(), End = Components.rend(); It != End;
647 llvm::sys::path::append(RelativeHeader, *It);
649 HeaderPaths.push_back(
650 std::make_pair(Dir->path().str(), RelativeHeader.c_str()));
660 llvm::sort(HeaderPaths, llvm::less_first());
661 for (
auto &[Path, RelPath] : HeaderPaths) {
662 auto Header =
FileMgr.getOptionalFileRef(Path);
682 LangOpts,
FileMgr,
Diag, ModMap, Submodule, Includes))
685 return std::error_code();
690 std::string &PresumedModuleMapFile,
698 assert(
ModuleMap &&
"MainFileID without FileEntry");
703 if (IsPreprocessed) {
713 &Offset, PresumedModuleMapFile))
716 if (
SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)
722 llvm::sys::path::append(InferredFrameworkPath,
726 (void)HS.
getModuleMap().inferFrameworkModule(*Dir, IsSystem,
nullptr);
733 StringRef ModuleMapFilename) {
769 if (!OriginalModuleMapName.empty()) {
770 auto OriginalModuleMap =
773 if (!OriginalModuleMap) {
775 << OriginalModuleMapName;
783 *OriginalModuleMap, FileCharacter);
795 if (SourceMgr.getModuleBuildStack().empty())
802static std::unique_ptr<llvm::MemoryBuffer>
808 std::error_code Err = std::error_code();
809 if (std::optional<Module::Header> UmbrellaHeader =
824 return llvm::MemoryBuffer::getMemBufferCopy(
831 assert(!Instance &&
"Already processing a source file!");
832 assert(!Input.
isEmpty() &&
"Unexpected empty filename!");
836 bool HasBegunSourceFile =
false;
842 llvm::scope_exit FailureCleanup([&]() {
843 if (HasBegunSourceFile)
866 auto ASTDiags = llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(
867 Diags->getDiagnosticIDs(), Diags->getDiagnosticOptions());
868 ASTDiags->setClient(Diags->getClient(),
false);
871 StringRef InputFile = Input.
getFile();
896 if (
auto ASTReader = AST->getASTReader()) {
901 if (&MF != &PrimaryModule)
902 ModuleFiles.emplace_back(MF.FileName);
911 auto Kind = AST->getInputKind();
914 AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
917 assert(ASTModule &&
"module file does not define its own module");
920 auto &OldSM = AST->getSourceManager();
921 FileID ID = OldSM.getMainFileID();
922 if (
auto File = OldSM.getFileEntryRefForID(ID))
935 "This action does not have AST file support!");
940 StringRef InputFile = Input.
getFile();
952 HasBegunSourceFile =
true;
976 FailureCleanup.release();
1015 HasBegunSourceFile =
true;
1025 FailureCleanup.release();
1037 FileMgr.makeAbsolutePath(PCHIncludePath);
1038 llvm::sys::path::remove_dots(PCHIncludePath,
true);
1044 if (
auto PCHDir =
FileMgr.getOptionalDirectoryRef(PCHInclude)) {
1047 llvm::sys::path::native(PCHDir->getName(), DirNative);
1049 llvm::vfs::FileSystem &FS =
FileMgr.getVirtualFileSystem();
1054 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1056 Dir != DirEnd && !EC; Dir.increment(EC)) {
1063 SpecificModuleCachePath,
1086 HasBegunSourceFile =
true;
1098 "trying to build a header unit without a Pre-processor?");
1103 CWD.push_back({std::nullopt, *Dir});
1108 nullptr,
nullptr, CWD,
nullptr,
nullptr,
nullptr,
1109 nullptr,
nullptr,
nullptr);
1151 std::string PresumedModuleMapFile;
1152 unsigned OffsetToContents;
1155 PresumedModuleMapFile, OffsetToContents))
1162 CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
1164 if (OffsetToContents)
1176 auto BufferID = SourceMgr.
createFileID(std::move(Buffer), Kind);
1177 assert(BufferID.isValid() &&
"couldn't create module buffer ID");
1178 SourceMgr.setMainFileID(BufferID);
1190 *
File,
false,
false);
1218 std::unique_ptr<ASTConsumer> Consumer =
1219 CreateWrappedASTConsumer(CI, PresumedInputFile);
1239 assert(
hasPCHSupport() &&
"This action does not have PCH support!");
1241 Consumer->GetASTDeserializationListener();
1242 bool DeleteDeserialListener =
false;
1244 DeserialListener =
new DeserializedDeclsDumper(DeserialListener,
1245 DeleteDeserialListener);
1246 DeleteDeserialListener =
true;
1249 DeserialListener =
new DeserializedDeclsChecker(
1252 DeserialListener, DeleteDeserialListener);
1253 DeleteDeserialListener =
true;
1260 DeserialListener, DeleteDeserialListener);
1270 CI.
getASTReader()->setDeserializationListener(DeserialListener,
1271 DeleteDeserialListener);
1291 "modules enabled but created an external source that "
1292 "doesn't support modules");
1303 diag::warn_eagerly_load_for_standard_cplusplus_modules);
1307 for (
const auto &ModuleFile : ModuleFiles) {
1314 diag::warn_eagerly_load_for_standard_cplusplus_modules);
1321 auto Override = llvm::makeIntrusiveRefCnt<LayoutOverrideSource>(
1328 auto HLSLSema = llvm::makeIntrusiveRefCnt<HLSLExternalSemaSource>();
1329 if (
auto SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1331 auto MultiSema = llvm::makeIntrusiveRefCnt<MultiplexExternalSemaSource>(
1332 std::move(SemaSource), std::move(HLSLSema));
1338 FailureCleanup.release();
1352 if (!
Cache.empty()) {
1358 consumeError(std::move(Err));
1363 return llvm::Error::success();
1405 llvm::errs() <<
"\n";
1420 llvm::BuryPointer(std::move(CurrentASTUnit));
1468void PluginASTAction::anchor() { }
1470std::unique_ptr<ASTConsumer>
1473 llvm_unreachable(
"Invalid CreateASTConsumer on preprocessor action!");
1479std::unique_ptr<ASTConsumer>
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
LLVM_INSTANTIATE_REGISTRY_EX(CLANG_ABI_EXPORT, clang::tooling::ToolExecutorPluginRegistry) namespace clang
Defines interfaces for clang::FileEntry and clang::FileEntryRef.
static std::error_code collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag, ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl< char > &Includes)
Collect the set of header includes needed to construct the given module and update the TopHeaders fil...
static Module * prepareToBuildModule(CompilerInstance &CI, StringRef ModuleMapFilename)
static void addHeaderInclude(StringRef HeaderName, SmallVectorImpl< char > &Includes, const LangOptions &LangOpts, bool IsExternC)
static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem, bool IsPreprocessed, std::string &PresumedModuleMapFile, unsigned &Offset)
static SourceLocation ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile, bool IsModuleMap=false)
For preprocessed files, if the first line is the linemarker and specifies the original source file na...
static SmallVectorImpl< char > & operator+=(SmallVectorImpl< char > &Includes, StringRef RHS)
static std::unique_ptr< llvm::MemoryBuffer > getInputBufferForModule(CompilerInstance &CI, Module *M)
Compute the input buffer that should be used to build the specified module.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines the clang::Preprocessor interface.
Defines clang::SarifDocumentWriter, clang::SarifRule, clang::SarifResult.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines utilities for dealing with stack allocation and stack space.
Defines the clang::TokenKind enum and support functions.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
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.
IntrusiveRefCntPtr< ExternalASTSource > getExternalSourcePtr() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
void ExecuteAction() override
Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.
Reads an AST files chain containing the contents of a translation unit.
void visitTopLevelModuleMaps(serialization::ModuleFile &MF, llvm::function_ref< void(FileEntryRef)> Visitor)
Visit all the top-level module maps loaded when building the given module file.
ModuleManager & getModuleManager()
Retrieve the module manager.
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const CodeGenOptions &CGOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath, bool RequireStrictOptionMatches=false)
Determine whether the given AST file is acceptable to load into a translation unit with the given lan...
static std::unique_ptr< ASTUnit > LoadFromASTFile(StringRef Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, std::shared_ptr< DiagnosticOptions > DiagOpts, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, const HeaderSearchOptions &HSOpts, const LangOptions *LangOpts=nullptr, bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, bool AllowASTWithCompilerErrors=false, bool UserFilesAreVolatile=false)
Create a ASTUnit from an AST file.
@ LoadPreprocessorOnly
Load options and the preprocessor state.
@ LoadEverything
Load everything, including Sema.
void initializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)
Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...
Abstract interface for a consumer of code-completion information.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
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
void createPreprocessor(TranslationUnitKind TUKind)
Create the preprocessor, using the invocation, file, and source managers, and replace any existing on...
bool hasFileManager() const
const PCHContainerReader & getPCHContainerReader() const
Return the appropriate PCHContainerReader depending on the current CodeGenOptions.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
FileSystemOptions & getFileSystemOpts()
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.
void setVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
Use the given file system.
FileManager & getFileManager() const
Return the current file manager to the caller.
IntrusiveRefCntPtr< DiagnosticsEngine > getDiagnosticsPtr() const
void resetAndLeakSourceManager()
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
setASTConsumer - Replace the current AST consumer; the compiler instance takes ownership of Value.
ModuleCache & getModuleCache() const
IntrusiveRefCntPtr< ASTReader > getASTReader() const
void createASTContext()
Create the AST context.
bool hasASTContext() const
void resetAndLeakFileManager()
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext & getASTContext() const
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
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()
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
void setSourceManager(llvm::IntrusiveRefCntPtr< SourceManager > Value)
setSourceManager - Replace the current source manager.
void setASTContext(llvm::IntrusiveRefCntPtr< ASTContext > Value)
setASTContext - Replace the current AST context.
HeaderSearchOptions & getHeaderSearchOpts()
bool hasCodeCompletionConsumer() const
void resetAndLeakASTContext()
void createSourceManager()
Create the source manager and replace any existing one with it.
CompilerInvocation & getInvocation()
void resetAndLeakPreprocessor()
std::unique_ptr< ASTConsumer > takeASTConsumer()
takeASTConsumer - Remove the current AST consumer and give ownership to the caller.
PreprocessorOptions & getPreprocessorOpts()
void setFileManager(IntrusiveRefCntPtr< FileManager > Value)
Replace the current file manager.
TargetInfo & getTarget() const
void createCodeCompletionConsumer()
Create a code completion consumer using the invocation; note that this will cause the source manager ...
void clearOutputFiles(bool EraseFiles)
clearOutputFiles - Clear the output file list.
DiagnosticOptions & getDiagnosticOpts()
LangOptions & getLangOpts()
CodeGenOptions & getCodeGenOpts()
SourceManager & getSourceManager() const
Return the current source manager.
CodeCompleteConsumer & getCodeCompletionConsumer() const
bool shouldBuildGlobalModuleIndex() const
Indicates whether we should (re)build the global module index.
bool hasSourceManager() const
bool hasASTConsumer() const
bool hasPreprocessor() const
void setPreprocessor(std::shared_ptr< Preprocessor > Value)
Replace the current preprocessor.
bool hasVirtualFileSystem() const
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
std::string computeContextHash() const
Compute the context hash - a string that uniquely identifies compiler settings.
bool isFileContext() const
DeclContext * getLexicalParent()
getLexicalParent - Returns the containing lexical DeclContext.
SourceLocation getLocation() const
const char * getDeclKindName() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
void DeclRead(GlobalDeclID ID, const Decl *D) override
A decl was deserialized from the AST file.
virtual void EndSourceFile()
Callback to inform the diagnostic client that processing of a source file has ended.
virtual void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP=nullptr)
Callback to inform the diagnostic client that processing of a source file is beginning.
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
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.
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.
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Get a FileEntryRef if it exists, without doing anything on error.
OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)
Get a DirectoryEntryRef if it exists, without doing anything on error.
const FrontendInputFile & getCurrentInput() const
virtual void EndSourceFile()
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
virtual bool shouldEraseOutputFiles()
Callback at the end of processing a single input, to determine if the output files should be erased o...
virtual bool hasIRSupport() const
Does this action support use with IR files?
virtual void EndSourceFileAction()
Callback at the end of processing a single input.
virtual std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile)=0
Create the AST consumer object for this action, if supported.
CompilerInstance & getCompilerInstance() const
llvm::Error Execute()
Set the source manager's main input file, and run the action.
virtual bool hasASTFileSupport() const
Does this action support use with AST files?
Module * getCurrentModule() const
void setCurrentInput(const FrontendInputFile &CurrentInput, std::unique_ptr< ASTUnit > AST=nullptr)
virtual bool BeginSourceFileAction(CompilerInstance &CI)
Callback at the start of processing a single input.
virtual void ExecuteAction()=0
Callback to run the program action, using the initialized compiler instance.
void setCompilerInstance(CompilerInstance *Value)
virtual TranslationUnitKind getTranslationUnitKind()
For AST-based actions, the kind of translation unit we're handling.
virtual ~FrontendAction()
bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input)
Prepare the action for processing the input file Input.
virtual bool hasCodeCompletionSupport() const
Does this action support use with code completion?
StringRef getCurrentFileOrBufferName() const
virtual bool isModelParsingAction() const
Is this action invoked on a model file?
bool isCurrentFileAST() const
virtual bool usesPreprocessorOnly() const =0
Does this action only use the preprocessor?
friend class WrapperFrontendAction
virtual bool BeginInvocation(CompilerInstance &CI)
Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...
virtual bool hasPCHSupport() const
Does this action support use with PCH?
std::vector< std::string > ModuleFiles
The list of additional prebuilt module files to load before processing the input.
unsigned SkipFunctionBodies
Skip over function bodies to speed up parsing in cases you do not need them (e.g.
std::map< std::string, std::vector< std::string > > PluginArgs
Args to pass to the plugins.
unsigned ShowStats
Show frontend performance metrics and statistics.
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,...
std::vector< std::string > ModulesEmbedFiles
The list of files to embed into the compiled module file.
unsigned ModulesEmbedAllFiles
Whether we should embed all used files into the PCM file.
std::vector< std::string > AddPluginActions
The list of plugin actions to run in addition to the normal action.
std::string DumpMinimizationHintsPath
Output path to dump ranges of deserialized declarations to use as minimization hints.
unsigned DisableFree
Disable memory freeing on exit.
std::string OverrideRecordLayoutsFile
File name of the file that will provide record layouts (in the format produced by -fdump-record-layou...
std::vector< std::string > ModuleMapFiles
The list of module map files to load before processing the input.
A SourceLocation and its associated SourceManager.
static llvm::Error writeIndex(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, llvm::StringRef Path)
Write a global index into the given.
void PrintStats() const
Print some statistics to stderr that indicate how well the hashing is doing.
@ CMK_None
Not compiling a module interface at all.
@ CMK_ModuleMap
Compiling a module from a module map.
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.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
static CharSourceRange getAsCharRange(SourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Given a token range, produce a corresponding CharSourceRange that is not a token range.
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer,...
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
static ModuleFileName makeExplicit(std::string Name)
Creates a file name for an explicit module.
void finishModuleDeclarationScope()
Creates a new declaration scope for module names, allowing previously defined modules to shadow defin...
bool canInferFrameworkModule(const DirectoryEntry *Dir) const
Check whether a framework module can be inferred in the given directory.
bool isHeaderUnavailableInModule(FileEntryRef Header, const Module *RequestingModule) const
Determine whether the given header is unavailable as part of the specified module.
void resolveHeaderDirectives(const FileEntry *File) const
Resolve all lazy header directives for the specified file.
void setInferredModuleAllowedBy(Module *M, FileID ModMapFID)
Describes a module or submodule.
SmallVector< UnresolvedHeaderDirective, 1 > MissingHeaders
Headers that are mentioned in the module map file but could not be found on the file system.
Module * Parent
The parent of this module.
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers).
static StringRef getModuleInputBufferName()
llvm::iterator_range< submodule_iterator > submodules()
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "C"...
std::optional< Header > getUmbrellaHeaderAsWritten() const
Retrieve the umbrella header as written.
OptionalDirectoryEntryRef Directory
The build directory of this module.
std::string PresumedModuleMapFile
The presumed file name for the module map defining this module.
ArrayRef< Header > getHeaders(HeaderKind HK) const
bool isAvailable() const
Determine whether this module is available for use within the current translation unit.
std::optional< DirectoryName > getUmbrellaDirAsWritten() const
Retrieve the umbrella directory as written.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
void addTopHeader(FileEntryRef File)
Add a top-level header associated with this module.
@ AddAfterMainAction
Execute the action after the main action.
@ AddBeforeMainAction
Execute the action before the main action.
@ CmdlineBeforeMainAction
Execute the action before the main action if on the command line.
@ CmdlineAfterMainAction
Execute the action after the main action if on the command line.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Provide a default implementation which returns aborts; this method should never be called by Frontend...
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::set< std::string > DeserializedPCHDeclsToErrorOn
This is a set of names for decls that we do not want to be deserialized, and we emit an error if they...
std::vector< std::string > ChainedIncludes
Headers that will be converted to chained PCHs in memory.
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.
bool DumpDeserializedPCHDecls
Dump declarations that are deserialized from PCH, for testing.
bool AllowPCHWithCompilerErrors
When true, a PCH with compiler errors will not be rejected.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void setMainFileDir(DirectoryEntryRef Dir)
Set the directory in which the main file should be considered to have been found, if it is not a real...
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.
Module * getCurrentModuleImplementation()
Retrieves the module whose implementation we're current compiling, if any.
HeaderSearch & getHeaderSearchInfo() const
IdentifierTable & getIdentifierTable()
Builtin::Context & getBuiltinInfo()
void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine)
Instruct the preprocessor to skip part of the main source file.
const LangOptions & getLangOpts() const
void EndSourceFile()
Inform the preprocessor callbacks that processing is complete.
void setSarifWriter(std::unique_ptr< SarifDocumentWriter > SarifWriter)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
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.
FileIDAndOffset getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
void setAllFilesAreTransient(bool Transient)
Specify that all files that are read during this compilation are transient.
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, bool IsFileExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table for the FileID and offset specified by Loc.
void setFileIsTransient(FileEntryRef SourceFile)
Specify that a file is transient.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
void PrintStats() const
Print statistics to stderr.
FileID getMainFileID() const
Returns the FileID of the main source file.
void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc)
Push an entry to the module build stack.
void initializeForReplay(const SourceManager &Old)
Initialize this source manager suitably to replay the compilation described by Old.
FileID getOrCreateFileID(FileEntryRef SourceFile, SrcMgr::CharacteristicKind FileCharacter)
Get the FileID for SourceFile if it exists.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
Token - This structure provides full information about a lexed token.
SourceLocation getEndLoc() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool BeginSourceFileAction(CompilerInstance &CI) override
Callback at the start of processing a single input.
bool hasIRSupport() const override
Does this action support use with IR files?
bool PrepareToExecuteAction(CompilerInstance &CI) override
Prepare to execute the action on the given CompilerInstance.
bool hasASTFileSupport() const override
Does this action support use with AST files?
bool usesPreprocessorOnly() const override
Does this action only use the preprocessor?
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
bool hasCodeCompletionSupport() const override
Does this action support use with code completion?
bool shouldEraseOutputFiles() override
Callback at the end of processing a single input, to determine if the output files should be erased o...
TranslationUnitKind getTranslationUnitKind() override
For AST-based actions, the kind of translation unit we're handling.
void EndSourceFileAction() override
Callback at the end of processing a single input.
bool BeginInvocation(CompilerInstance &CI) override
Callback before starting processing a single input, giving the opportunity to modify the CompilerInvo...
bool hasPCHSupport() const override
Does this action support use with PCH?
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
std::unique_ptr< FrontendAction > WrappedAction
void EndSourceFile() override
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
Information about a module that has been loaded by the ASTReader.
bool StandardCXXModule
Whether this module file is a standard C++ module.
ModuleFile & getPrimaryModule()
Returns the primary module associated with the manager, that is, the first module loaded.
Public enums and private classes that are part of the SourceManager implementation.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
void ParseAST(Preprocessor &pp, ASTConsumer *C, ASTContext &Ctx, bool PrintStats=false, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr, bool SkipFunctionBodies=false)
Parse the entire file specified, notifying the ASTConsumer as the file is parsed.
@ Override
Merge availability attributes for an override, which requires an exact match or a weakening of constr...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Result
The result type of a method or function.
std::string createSpecificModuleCachePath(FileManager &FileMgr, StringRef ModuleCachePath, bool DisableModuleHash, std::string ContextHash)
IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ASTReader > &OutReader)
The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing.
llvm::Registry< PluginASTAction > FrontendPluginRegistry
The frontend plugin registry.
void noteBottomOfStack(bool ForceSet=false)
Call this once on each thread, as soon after starting the thread as feasible, to note the approximate...
TranslationUnitKind
Describes the kind of translation unit being processed.
U cast(CodeGen::Address addr)