clang: lib/Frontend/FrontendAction.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
37#include "llvm/ADT/ScopeExit.h"
38#include "llvm/Support/BuryPointer.h"
39#include "llvm/Support/ErrorHandling.h"
40#include "llvm/Support/FileSystem.h"
41#include "llvm/Support/Path.h"
42#include "llvm/Support/Timer.h"
43#include "llvm/Support/raw_ostream.h"
44#include
45#include <system_error>
46using namespace clang;
47
49
50namespace {
51
54 bool DeletePrevious;
55
56public:
57 explicit DelegatingDeserializationListener(
60 ~DelegatingDeserializationListener() override {
61 if (DeletePrevious)
63 }
64
65 DelegatingDeserializationListener(const DelegatingDeserializationListener &) =
66 delete;
67 DelegatingDeserializationListener &
68 operator=(const DelegatingDeserializationListener &) = delete;
69
71 if (Previous)
72 Previous->ReaderInitialized(Reader);
73 }
76 if (Previous)
77 Previous->IdentifierRead(ID, II);
78 }
80 if (Previous)
82 }
84 if (Previous)
86 }
88 if (Previous)
89 Previous->SelectorRead(ID, Sel);
90 }
93 if (Previous)
94 Previous->MacroDefinitionRead(PPID, MD);
95 }
96};
97
98
99class DeserializedDeclsDumper : public DelegatingDeserializationListener {
100public:
102 bool DeletePrevious)
103 : DelegatingDeserializationListener(Previous, DeletePrevious) {}
104
107 if (const NamedDecl *ND = dyn_cast(D)) {
108 llvm::outs() << " - ";
109 ND->printQualifiedName(llvm::outs());
110 }
111 llvm::outs() << "\n";
112
113 DelegatingDeserializationListener::DeclRead(ID, D);
114 }
115};
116
117
118
119class DeserializedDeclsChecker : public DelegatingDeserializationListener {
121 std::setstd::string NamesToCheck;
122
123public:
124 DeserializedDeclsChecker(ASTContext &Ctx,
125 const std::setstd::string &NamesToCheck,
127 bool DeletePrevious)
128 : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
129 NamesToCheck(NamesToCheck) {}
130
132 if (const NamedDecl *ND = dyn_cast(D))
133 if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
134 unsigned DiagID
136 "%0 was deserialized");
138 << ND;
139 }
140
141 DelegatingDeserializationListener::DeclRead(ID, D);
142 }
143};
144
145}
146
148
150
152 std::unique_ptr AST) {
153 this->CurrentInput = CurrentInput;
154 CurrentASTUnit = std::move(AST);
155}
156
161}
162
163std::unique_ptr
164FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
165 StringRef InFile) {
166 std::unique_ptr Consumer = CreateASTConsumer(CI, InFile);
167 if (!Consumer)
168 return nullptr;
169
170
171 bool FoundAllPlugins = true;
173 bool Found = false;
174 for (const FrontendPluginRegistry::entry &Plugin :
175 FrontendPluginRegistry::entries()) {
176 if (Plugin.getName() == Arg)
178 }
181 FoundAllPlugins = false;
182 }
183 }
184 if (!FoundAllPlugins)
185 return nullptr;
186
187
188 if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
189 return Consumer;
190
191
193 return Consumer;
194
195
196
197 std::vector<std::unique_ptr> Consumers;
198 std::vector<std::unique_ptr> AfterConsumers;
199 for (const FrontendPluginRegistry::entry &Plugin :
200 FrontendPluginRegistry::entries()) {
201 std::unique_ptr P = Plugin.instantiate();
205
206
208 Plugin.getName())) {
211 else
213 }
214 }
217 P->ParseArgs(
218 CI,
220 std::unique_ptr PluginConsumer = P->CreateASTConsumer(CI, InFile);
222 Consumers.push_back(std::move(PluginConsumer));
223 } else {
224 AfterConsumers.push_back(std::move(PluginConsumer));
225 }
226 }
227 }
228
229
230 Consumers.push_back(std::move(Consumer));
231 if (!AfterConsumers.empty()) {
232
233
234
236 for (auto &C : AfterConsumers)
237 Consumers.push_back(std::move(C));
238 }
239
240 return std::make_unique(std::move(Consumers));
241}
242
243
244
245
246
247
248
249
250
251
253 std::string &InputFile,
254 bool IsModuleMap = false) {
257
258 auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);
259 if (!MainFileBuf)
261
262 std::unique_ptr RawLexer(
263 new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));
264
265
266
267
268
269
271 if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
273 if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
274 T.getKind() != tok::numeric_constant)
276
277 unsigned LineNo;
279 if (IsModuleMap) {
282 .getAsInteger(10, LineNo))
284 }
285
286 RawLexer->LexFromRawLexer(T);
287 if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
289
291 if (Literal.hadError)
293 RawLexer->LexFromRawLexer(T);
294 if (T.isNot(tok::eof) && .isAtStartOfLine())
296 InputFile = Literal.GetString().str();
297
298 if (IsModuleMap)
300 LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
302
303 return T.getLocation();
304}
305
308 Includes.append(RHS.begin(), RHS.end());
309 return Includes;
310}
311
315 bool IsExternC) {
316 if (IsExternC && LangOpts.CPlusPlus)
317 Includes += "extern \"C\" {\n";
318 if (LangOpts.ObjC)
319 Includes += "#import \"";
320 else
321 Includes += "#include \"";
322
323 Includes += HeaderName;
324
325 Includes += "\"\n";
326 if (IsExternC && LangOpts.CPlusPlus)
327 Includes += "}\n";
328}
329
330
331
332
333
334
335
336
340
342 return std::error_code();
343
344
346
347
348
349
350
351
354 Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
355 << MissingHeader.IsUmbrella << MissingHeader.FileName;
356 return std::error_code();
357 }
358
359
363
364
365
366
367 addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
369 }
370 }
371
372
373 if (std::optionalModule::Header UmbrellaHeader =
377
378 addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
380 } else if (std::optionalModule::DirectoryName UmbrellaDir =
382
383 std::error_code EC;
385 llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);
386
389 for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
390 Dir != End && !EC; Dir.increment(EC)) {
391
392
393 if (!llvm::StringSwitch(llvm::sys::path::extension(Dir->path()))
394 .Cases(".h", ".H", ".hh", ".hpp", true)
395 .Default(false))
396 continue;
397
399
400
401 if (!Header)
402 continue;
403
404
405
407 continue;
408
409
411 auto PathIt = llvm::sys::path::rbegin(Dir->path());
412 for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
413 Components.push_back(*PathIt);
415 UmbrellaDir->PathRelativeToRootModuleDirectory);
416 for (auto It = Components.rbegin(), End = Components.rend(); It != End;
417 ++It)
418 llvm::sys::path::append(RelativeHeader, *It);
419
420 std::string RelName = RelativeHeader.c_str();
421 Headers.push_back(std::make_pair(RelName, *Header));
422 }
423
424 if (EC)
425 return EC;
426
427
428
429 llvm::sort(Headers, llvm::less_first());
430 for (auto &H : Headers) {
431
434 }
435 }
436
437
440 LangOpts, FileMgr, Diag, ModMap, Submodule, Includes))
441 return Err;
442
443 return std::error_code();
444}
445
447 bool IsPreprocessed,
448 std::string &PresumedModuleMapFile,
449 unsigned &Offset) {
452
453
454 FileID ModuleMapID = SrcMgr.getMainFileID();
456 assert(ModuleMap && "MainFileID without FileEntry");
457
458
459
460 Offset = 0;
461 if (IsPreprocessed) {
464 if (EndOfLineMarker.isValid())
466 }
467
468
470 PresumedModuleMapFile))
471 return true;
472
473 if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)
474 Offset = 0;
475
476
479 llvm::sys::path::append(InferredFrameworkPath,
481 if (auto Dir =
483 (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr);
484 }
485
486 return false;
487}
488
490 StringRef ModuleMapFilename) {
493
494
495
496
497
498 return nullptr;
499 }
500
501
504 true);
505 if (!M) {
508
509 return nullptr;
510 }
511
512
515 return nullptr;
516
517
518
520
521
522
523
524
526 if (!OriginalModuleMapName.empty()) {
527 auto OriginalModuleMap =
529 true);
530 if (!OriginalModuleMap) {
532 << OriginalModuleMapName;
533 return nullptr;
534 }
537 auto FileCharacter =
540 *OriginalModuleMap, FileCharacter);
545 }
546 }
547
548
549
550
555 return M;
556}
557
558
559static std::unique_ptrllvm::MemoryBuffer
562
563
565 std::error_code Err = std::error_code();
566 if (std::optionalModule::Header UmbrellaHeader =
568 addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
573 HeaderContents);
574
575 if (Err) {
578 return nullptr;
579 }
580
581 return llvm::MemoryBuffer::getMemBufferCopy(
583}
584
588 assert(!Instance && "Already processing a source file!");
589 assert(!Input.isEmpty() && "Unexpected empty filename!");
592
593 bool HasBegunSourceFile = false;
596
597
598
599 auto FailureCleanup = llvm::make_scope_exit([&]() {
600 if (HasBegunSourceFile)
607 });
608
610 return false;
611
612
613
614 if (ReplayASTFile) {
616
617
620 &Diags->getDiagnosticOptions()));
621 ASTDiags->setClient(Diags->getClient(), false);
622
623
624 StringRef InputFile = Input.getFile();
625
629 nullptr);
630 if (!AST)
631 return false;
632
633
634
638
639
640
644
645
646
647
648 if (auto ASTReader = AST->getASTReader()) {
651
653 if (&MF != &PrimaryModule)
655
658 std::string(FE.getName()));
659 });
660 }
661
662
663 auto Kind = AST->getInputKind();
666 AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
668 false);
669 assert(ASTModule && "module file does not define its own module");
671 } else {
672 auto &OldSM = AST->getSourceManager();
673 FileID ID = OldSM.getMainFileID();
674 if (auto File = OldSM.getFileEntryRefForID(ID))
676 else
678 }
680 }
681
682
683
687 "This action does not have AST file support!");
688
690
691
692 StringRef InputFile = Input.getFile();
693
698
699 if (!AST)
700 return false;
701
702
704 HasBegunSourceFile = true;
705
706
707
715
717
718
720 return false;
721
722
723 CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
725 return false;
726
727 FailureCleanup.release();
728 return true;
729 }
730
731
734 return false;
735 }
736 }
741 ->setSarifWriter(
742 std::make_unique(CI.getSourceManager()));
743 }
744 }
745
746
747
751 else
753 }
756
757
762 return false;
763 }
764
765
767 HasBegunSourceFile = true;
768
769
771 return false;
772
773
775 return false;
776
777 FailureCleanup.release();
778 return true;
779 }
780
781
782
789 std::error_code EC;
791 llvm::sys::path::native(PCHDir->getName(), DirNative);
792 bool Found = false;
794 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
795 DirEnd;
796 Dir != DirEnd && !EC; Dir.increment(EC)) {
797
802 SpecificModuleCachePath, true)) {
805 break;
806 }
807 }
808
811 return false;
812 }
813 }
814 }
815
816
817
820
821
824 HasBegunSourceFile = true;
825
826
827
828
829
836 "trying to build a header unit without a Pre-processor?");
838
841 CWD.push_back({std::nullopt, *Dir});
846 nullptr, nullptr, CWD, nullptr, nullptr, nullptr,
847 nullptr, nullptr, nullptr);
848 if (!FE) {
851 return false;
852 }
853
855
858 }
859
860
864 }
865
867 return false;
868
871
872
873
874
877
878
882 }
883
884
885
888
889 std::string PresumedModuleMapFile;
890 unsigned OffsetToContents;
893 PresumedModuleMapFile, OffsetToContents))
894 return false;
895
897 if (!CurrentModule)
898 return false;
899
900 CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
901
902 if (OffsetToContents)
903
905 else {
906
908 if (!Buffer)
909 return false;
910
911
914 auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
915 assert(BufferID.isValid() && "couldn't create module buffer ID");
916 SourceMgr.setMainFileID(BufferID);
917 }
918 }
919
920
922 return false;
923
924
928 *File, false);
929 else
931 }
932
933
935
936
937
942
943
944
946
949
950
951
955
956 std::unique_ptr Consumer =
957 CreateWrappedASTConsumer(CI, PresumedInputFile);
958 if (!Consumer)
959 return false;
960
961
964
966
969 if (!source)
970 return false;
975
976 assert(hasPCHSupport() && "This action does not have PCH support!");
978 Consumer->GetASTDeserializationListener();
979 bool DeleteDeserialListener = false;
981 DeserialListener = new DeserializedDeclsDumper(DeserialListener,
982 DeleteDeserialListener);
983 DeleteDeserialListener = true;
984 }
986 DeserialListener = new DeserializedDeclsChecker(
989 DeserialListener, DeleteDeserialListener);
990 DeleteDeserialListener = true;
991 }
997 DeserialListener, DeleteDeserialListener);
999 return false;
1000 }
1001
1002
1003
1007 CI.getASTReader()->setDeserializationListener(DeserialListener,
1008 DeleteDeserialListener);
1009 }
1010 }
1011
1014 return false;
1015 }
1016
1017
1018
1024 } else {
1025
1026
1028 "modules enabled but created an external source that "
1029 "doesn't support modules");
1030 }
1031
1032
1036 return false;
1037
1040 diag::warn_eagerly_load_for_standard_cplusplus_modules);
1041 }
1042
1043
1044
1051 }
1052
1053
1057 if (auto *SemaSource = dyn_cast_if_present(
1062 } else
1064 }
1065
1066 FailureCleanup.release();
1067 return true;
1068}
1069
1073
1074
1075
1078 StringRef Cache =
1080 if (.empty()) {
1083
1084
1085
1086 consumeError(std::move(Err));
1087 }
1088 }
1089 }
1090
1091 return llvm::Error::success();
1092}
1093
1096
1097
1099
1100
1103
1104
1106
1107
1108
1109
1111 if (DisableFree) {
1115 } else {
1119 }
1120
1127 llvm::errs() << "\n";
1128 }
1129
1130
1131
1133
1134
1135
1136
1138 if (DisableFree) {
1142 llvm::BuryPointer(std::move(CurrentASTUnit));
1143 } else {
1147 }
1148 }
1149
1153}
1154
1157}
1158
1159
1160
1161
1162
1166 return;
1167
1168
1169
1171
1172
1173
1177
1178
1182
1185
1188}
1189
1190void PluginASTAction::anchor() { }
1191
1192std::unique_ptr
1194 StringRef InFile) {
1195 llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
1196}
1197
1199 return WrappedAction->PrepareToExecuteAction(CI);
1200}
1201std::unique_ptr
1203 StringRef InFile) {
1204 return WrappedAction->CreateASTConsumer(CI, InFile);
1205}
1208}
1212 auto Ret = WrappedAction->BeginSourceFileAction(CI);
1213
1215 return Ret;
1216}
1219}
1223}
1226}
1227
1230}
1233}
1236}
1239}
1242}
1244 return WrappedAction->hasCodeCompletionSupport();
1245}
1246
1248 std::unique_ptr WrappedAction)
1249 : WrappedAction(std::move(WrappedAction)) {}
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
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...
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 utilities for dealing with stack allocation and stack space.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
FullSourceLoc getFullLoc(SourceLocation Loc) const
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.
DiagnosticsEngine & getDiagnostics() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD)
A macro definition was read from the AST file.
virtual void TypeRead(serialization::TypeIdx Idx, QualType T)
A type was deserialized from the AST file.
virtual void SelectorRead(serialization::SelectorID iD, Selector Sel)
A selector was read from the AST file.
virtual void ReaderInitialized(ASTReader *Reader)
The ASTReader was initialized.
virtual void DeclRead(GlobalDeclID ID, const Decl *D)
A decl was deserialized from the AST file.
virtual void IdentifierRead(serialization::IdentifierID ID, IdentifierInfo *II)
An identifier was deserialized from the AST file.
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 InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts, StringRef ExistingModuleCachePath, bool RequireStrictOptionMatches=false)
Determine whether the given AST file is acceptable to load into a translation unit with the given lan...
@ LoadPreprocessorOnly
Load options and the preprocessor state.
@ LoadEverything
Load everything, including Sema.
static std::unique_ptr< ASTUnit > LoadFromASTFile(StringRef Filename, const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, const FileSystemOptions &FileSystemOpts, std::shared_ptr< HeaderSearchOptions > HSOpts, std::shared_ptr< LangOptions > LangOpts=nullptr, bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, bool AllowASTWithCompilerErrors=false, bool UserFilesAreVolatile=false, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=llvm::vfs::getRealFileSystem())
Create a ASTUnit from an AST file.
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.
void setFileManager(FileManager *Value)
Replace the current file manager and virtual file system.
void setSourceManager(SourceManager *Value)
setSourceManager - Replace the current source manager.
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...
void createSourceManager(FileManager &FileMgr)
Create the source manager and replace any existing one with it.
FileManager * createFileManager(IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Create the file manager and replace any existing one with it.
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.
FileManager & getFileManager() const
Return the current file manager to the caller.
void resetAndLeakSourceManager()
void setASTConsumer(std::unique_ptr< ASTConsumer > Value)
setASTConsumer - Replace the current AST consumer; the compiler instance takes ownership of Value.
IntrusiveRefCntPtr< ASTReader > getASTReader() const
std::shared_ptr< LangOptions > getLangOptsPtr() const
InMemoryModuleCache & getModuleCache() const
void createASTContext()
Create the AST context.
bool hasASTContext() const
void resetAndLeakFileManager()
std::shared_ptr< HeaderSearchOptions > getHeaderSearchOptsPtr() const
void setASTContext(ASTContext *Value)
setASTContext - Replace the current AST context.
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext & getASTContext() const
TargetOptions & getTargetOpts()
void setASTReader(IntrusiveRefCntPtr< ASTReader > Reader)
FrontendOptions & getFrontendOpts()
void setSema(Sema *S)
Replace the current Sema; the compiler instance takes ownership of S.
HeaderSearchOptions & getHeaderSearchOpts()
bool hasCodeCompletionConsumer() const
void resetAndLeakASTContext()
void resetAndLeakPreprocessor()
std::unique_ptr< ASTConsumer > takeASTConsumer()
takeASTConsumer - Remove the current AST consumer and give ownership to the caller.
PreprocessorOptions & getPreprocessorOpts()
std::string getSpecificModuleCachePath(StringRef ModuleHash)
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 loadModuleFile(StringRef FileName, serialization::ModuleFile *&LoadedModuleFile)
bool hasPreprocessor() const
void setPreprocessor(std::shared_ptr< Preprocessor > Value)
Replace the current preprocessor.
void createSema(TranslationUnitKind TUKind, CodeCompleteConsumer *CompletionConsumer)
Create the Sema object to be used for parsing.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
const char * getDeclKindName() const
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.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
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.
llvm::vfs::FileSystem & getVirtualFileSystem() const
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
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?
An input file for the front end.
bool isPreprocessed() const
InputKind getKind() const
StringRef getFile() const
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.
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.
One of these records is kept for each identifier that is lexed.
void PrintStats() const
Print some statistics to stderr that indicate how well the hashing is doing.
The kind of a file that we've been handed as an input.
bool isPreprocessed() const
InputKind withHeaderUnit(HeaderUnitKind HU) const
bool isHeaderUnit() const
HeaderUnitKind getHeaderUnitKind() const
Language getLanguage() const
@ 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.
An external AST source that overrides the layout of a specified set of record types.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
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,...
Record the location of a macro definition.
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.
An abstract interface that should be implemented by external AST sources that also provide informatio...
This represents a decl that may have a name.
@ 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.
A (possibly-)qualified type.
Smart pointer class that efficiently represents Objective-C method names.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
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.
ModuleBuildStack getModuleBuildStack() const
Retrieve the module build stack.
FileID getMainFileID() const
Returns the FileID of the main source file.
void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc)
Push an entry to the module build stack.
void 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.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
Token - This structure provides full information about a lexed token.
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.
A type index; the type ID with the qualifier bits removed.
uint32_t SelectorID
An ID number that refers to an ObjC selector in an AST file.
uint32_t PreprocessedEntityID
An ID number that refers to an entity in the detailed preprocessing record.
uint64_t IdentifierID
An ID number that refers to an identifier in an AST file.
The JSON file list parser is used to communicate input to InstallAPI.
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.
void noteBottomOfStack()
Call this once on each thread, as soon after starting the thread as feasible, to note the approximate...
IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ExternalSemaSource > &Reader)
The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing.
llvm::Registry< PluginASTAction > FrontendPluginRegistry
The frontend plugin registry.
TranslationUnitKind
Describes the kind of translation unit being processed.
const FunctionProtoType * T