Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp
35232 views
1
//===--- FrontendAction.cpp -----------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "clang/Frontend/FrontendAction.h"
10
#include "clang/AST/ASTConsumer.h"
11
#include "clang/AST/ASTContext.h"
12
#include "clang/AST/DeclGroup.h"
13
#include "clang/Basic/Builtins.h"
14
#include "clang/Basic/DiagnosticOptions.h"
15
#include "clang/Basic/FileEntry.h"
16
#include "clang/Basic/LangStandard.h"
17
#include "clang/Basic/Sarif.h"
18
#include "clang/Basic/Stack.h"
19
#include "clang/Frontend/ASTUnit.h"
20
#include "clang/Frontend/CompilerInstance.h"
21
#include "clang/Frontend/FrontendDiagnostic.h"
22
#include "clang/Frontend/FrontendPluginRegistry.h"
23
#include "clang/Frontend/LayoutOverrideSource.h"
24
#include "clang/Frontend/MultiplexConsumer.h"
25
#include "clang/Frontend/SARIFDiagnosticPrinter.h"
26
#include "clang/Frontend/Utils.h"
27
#include "clang/Lex/HeaderSearch.h"
28
#include "clang/Lex/LiteralSupport.h"
29
#include "clang/Lex/Preprocessor.h"
30
#include "clang/Lex/PreprocessorOptions.h"
31
#include "clang/Parse/ParseAST.h"
32
#include "clang/Sema/HLSLExternalSemaSource.h"
33
#include "clang/Sema/MultiplexExternalSemaSource.h"
34
#include "clang/Serialization/ASTDeserializationListener.h"
35
#include "clang/Serialization/ASTReader.h"
36
#include "clang/Serialization/GlobalModuleIndex.h"
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 <memory>
45
#include <system_error>
46
using namespace clang;
47
48
LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
49
50
namespace {
51
52
class DelegatingDeserializationListener : public ASTDeserializationListener {
53
ASTDeserializationListener *Previous;
54
bool DeletePrevious;
55
56
public:
57
explicit DelegatingDeserializationListener(
58
ASTDeserializationListener *Previous, bool DeletePrevious)
59
: Previous(Previous), DeletePrevious(DeletePrevious) {}
60
~DelegatingDeserializationListener() override {
61
if (DeletePrevious)
62
delete Previous;
63
}
64
65
DelegatingDeserializationListener(const DelegatingDeserializationListener &) =
66
delete;
67
DelegatingDeserializationListener &
68
operator=(const DelegatingDeserializationListener &) = delete;
69
70
void ReaderInitialized(ASTReader *Reader) override {
71
if (Previous)
72
Previous->ReaderInitialized(Reader);
73
}
74
void IdentifierRead(serialization::IdentifierID ID,
75
IdentifierInfo *II) override {
76
if (Previous)
77
Previous->IdentifierRead(ID, II);
78
}
79
void TypeRead(serialization::TypeIdx Idx, QualType T) override {
80
if (Previous)
81
Previous->TypeRead(Idx, T);
82
}
83
void DeclRead(GlobalDeclID ID, const Decl *D) override {
84
if (Previous)
85
Previous->DeclRead(ID, D);
86
}
87
void SelectorRead(serialization::SelectorID ID, Selector Sel) override {
88
if (Previous)
89
Previous->SelectorRead(ID, Sel);
90
}
91
void MacroDefinitionRead(serialization::PreprocessedEntityID PPID,
92
MacroDefinitionRecord *MD) override {
93
if (Previous)
94
Previous->MacroDefinitionRead(PPID, MD);
95
}
96
};
97
98
/// Dumps deserialized declarations.
99
class DeserializedDeclsDumper : public DelegatingDeserializationListener {
100
public:
101
explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
102
bool DeletePrevious)
103
: DelegatingDeserializationListener(Previous, DeletePrevious) {}
104
105
void DeclRead(GlobalDeclID ID, const Decl *D) override {
106
llvm::outs() << "PCH DECL: " << D->getDeclKindName();
107
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
108
llvm::outs() << " - ";
109
ND->printQualifiedName(llvm::outs());
110
}
111
llvm::outs() << "\n";
112
113
DelegatingDeserializationListener::DeclRead(ID, D);
114
}
115
};
116
117
/// Checks deserialized declarations and emits error if a name
118
/// matches one given in command-line using -error-on-deserialized-decl.
119
class DeserializedDeclsChecker : public DelegatingDeserializationListener {
120
ASTContext &Ctx;
121
std::set<std::string> NamesToCheck;
122
123
public:
124
DeserializedDeclsChecker(ASTContext &Ctx,
125
const std::set<std::string> &NamesToCheck,
126
ASTDeserializationListener *Previous,
127
bool DeletePrevious)
128
: DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
129
NamesToCheck(NamesToCheck) {}
130
131
void DeclRead(GlobalDeclID ID, const Decl *D) override {
132
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
133
if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
134
unsigned DiagID
135
= Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
136
"%0 was deserialized");
137
Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
138
<< ND;
139
}
140
141
DelegatingDeserializationListener::DeclRead(ID, D);
142
}
143
};
144
145
} // end anonymous namespace
146
147
FrontendAction::FrontendAction() : Instance(nullptr) {}
148
149
FrontendAction::~FrontendAction() {}
150
151
void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput,
152
std::unique_ptr<ASTUnit> AST) {
153
this->CurrentInput = CurrentInput;
154
CurrentASTUnit = std::move(AST);
155
}
156
157
Module *FrontendAction::getCurrentModule() const {
158
CompilerInstance &CI = getCompilerInstance();
159
return CI.getPreprocessor().getHeaderSearchInfo().lookupModule(
160
CI.getLangOpts().CurrentModule, SourceLocation(), /*AllowSearch*/false);
161
}
162
163
std::unique_ptr<ASTConsumer>
164
FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
165
StringRef InFile) {
166
std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
167
if (!Consumer)
168
return nullptr;
169
170
// Validate -add-plugin args.
171
bool FoundAllPlugins = true;
172
for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
173
bool Found = false;
174
for (const FrontendPluginRegistry::entry &Plugin :
175
FrontendPluginRegistry::entries()) {
176
if (Plugin.getName() == Arg)
177
Found = true;
178
}
179
if (!Found) {
180
CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << Arg;
181
FoundAllPlugins = false;
182
}
183
}
184
if (!FoundAllPlugins)
185
return nullptr;
186
187
// If there are no registered plugins we don't need to wrap the consumer
188
if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
189
return Consumer;
190
191
// If this is a code completion run, avoid invoking the plugin consumers
192
if (CI.hasCodeCompletionConsumer())
193
return Consumer;
194
195
// Collect the list of plugins that go before the main action (in Consumers)
196
// or after it (in AfterConsumers)
197
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
198
std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
199
for (const FrontendPluginRegistry::entry &Plugin :
200
FrontendPluginRegistry::entries()) {
201
std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
202
PluginASTAction::ActionType ActionType = P->getActionType();
203
if (ActionType == PluginASTAction::CmdlineAfterMainAction ||
204
ActionType == PluginASTAction::CmdlineBeforeMainAction) {
205
// This is O(|plugins| * |add_plugins|), but since both numbers are
206
// way below 50 in practice, that's ok.
207
if (llvm::is_contained(CI.getFrontendOpts().AddPluginActions,
208
Plugin.getName())) {
209
if (ActionType == PluginASTAction::CmdlineBeforeMainAction)
210
ActionType = PluginASTAction::AddBeforeMainAction;
211
else
212
ActionType = PluginASTAction::AddAfterMainAction;
213
}
214
}
215
if ((ActionType == PluginASTAction::AddBeforeMainAction ||
216
ActionType == PluginASTAction::AddAfterMainAction) &&
217
P->ParseArgs(
218
CI,
219
CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())])) {
220
std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
221
if (ActionType == PluginASTAction::AddBeforeMainAction) {
222
Consumers.push_back(std::move(PluginConsumer));
223
} else {
224
AfterConsumers.push_back(std::move(PluginConsumer));
225
}
226
}
227
}
228
229
// Add to Consumers the main consumer, then all the plugins that go after it
230
Consumers.push_back(std::move(Consumer));
231
if (!AfterConsumers.empty()) {
232
// If we have plugins after the main consumer, which may be the codegen
233
// action, they likely will need the ASTContext, so don't clear it in the
234
// codegen action.
235
CI.getCodeGenOpts().ClearASTBeforeBackend = false;
236
for (auto &C : AfterConsumers)
237
Consumers.push_back(std::move(C));
238
}
239
240
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
241
}
242
243
/// For preprocessed files, if the first line is the linemarker and specifies
244
/// the original source file name, use that name as the input file name.
245
/// Returns the location of the first token after the line marker directive.
246
///
247
/// \param CI The compiler instance.
248
/// \param InputFile Populated with the filename from the line marker.
249
/// \param IsModuleMap If \c true, add a line note corresponding to this line
250
/// directive. (We need to do this because the directive will not be
251
/// visited by the preprocessor.)
252
static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
253
std::string &InputFile,
254
bool IsModuleMap = false) {
255
auto &SourceMgr = CI.getSourceManager();
256
auto MainFileID = SourceMgr.getMainFileID();
257
258
auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);
259
if (!MainFileBuf)
260
return SourceLocation();
261
262
std::unique_ptr<Lexer> RawLexer(
263
new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));
264
265
// If the first line has the syntax of
266
//
267
// # NUM "FILENAME"
268
//
269
// we use FILENAME as the input file name.
270
Token T;
271
if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
272
return SourceLocation();
273
if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
274
T.getKind() != tok::numeric_constant)
275
return SourceLocation();
276
277
unsigned LineNo;
278
SourceLocation LineNoLoc = T.getLocation();
279
if (IsModuleMap) {
280
llvm::SmallString<16> Buffer;
281
if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
282
.getAsInteger(10, LineNo))
283
return SourceLocation();
284
}
285
286
RawLexer->LexFromRawLexer(T);
287
if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
288
return SourceLocation();
289
290
StringLiteralParser Literal(T, CI.getPreprocessor());
291
if (Literal.hadError)
292
return SourceLocation();
293
RawLexer->LexFromRawLexer(T);
294
if (T.isNot(tok::eof) && !T.isAtStartOfLine())
295
return SourceLocation();
296
InputFile = Literal.GetString().str();
297
298
if (IsModuleMap)
299
CI.getSourceManager().AddLineNote(
300
LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
301
false, SrcMgr::C_User_ModuleMap);
302
303
return T.getLocation();
304
}
305
306
static SmallVectorImpl<char> &
307
operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
308
Includes.append(RHS.begin(), RHS.end());
309
return Includes;
310
}
311
312
static void addHeaderInclude(StringRef HeaderName,
313
SmallVectorImpl<char> &Includes,
314
const LangOptions &LangOpts,
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
/// Collect the set of header includes needed to construct the given
331
/// module and update the TopHeaders file set of the module.
332
///
333
/// \param Module The module we're collecting includes from.
334
///
335
/// \param Includes Will be augmented with the set of \#includes or \#imports
336
/// needed to load all of the named headers.
337
static std::error_code collectModuleHeaderIncludes(
338
const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag,
339
ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl<char> &Includes) {
340
// Don't collect any headers for unavailable modules.
341
if (!Module->isAvailable())
342
return std::error_code();
343
344
// Resolve all lazy header directives to header files.
345
ModMap.resolveHeaderDirectives(Module, /*File=*/std::nullopt);
346
347
// If any headers are missing, we can't build this module. In most cases,
348
// diagnostics for this should have already been produced; we only get here
349
// if explicit stat information was provided.
350
// FIXME: If the name resolves to a file with different stat information,
351
// produce a better diagnostic.
352
if (!Module->MissingHeaders.empty()) {
353
auto &MissingHeader = Module->MissingHeaders.front();
354
Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
355
<< MissingHeader.IsUmbrella << MissingHeader.FileName;
356
return std::error_code();
357
}
358
359
// Add includes for each of these headers.
360
for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
361
for (Module::Header &H : Module->Headers[HK]) {
362
Module->addTopHeader(H.Entry);
363
// Use the path as specified in the module map file. We'll look for this
364
// file relative to the module build directory (the directory containing
365
// the module map file) so this will find the same file that we found
366
// while parsing the module map.
367
addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
368
Module->IsExternC);
369
}
370
}
371
// Note that Module->PrivateHeaders will not be a TopHeader.
372
373
if (std::optional<Module::Header> UmbrellaHeader =
374
Module->getUmbrellaHeaderAsWritten()) {
375
Module->addTopHeader(UmbrellaHeader->Entry);
376
if (Module->Parent)
377
// Include the umbrella header for submodules.
378
addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
379
Includes, LangOpts, Module->IsExternC);
380
} else if (std::optional<Module::DirectoryName> UmbrellaDir =
381
Module->getUmbrellaDirAsWritten()) {
382
// Add all of the headers we find in this subdirectory.
383
std::error_code EC;
384
SmallString<128> DirNative;
385
llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);
386
387
llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
388
SmallVector<std::pair<std::string, FileEntryRef>, 8> Headers;
389
for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
390
Dir != End && !EC; Dir.increment(EC)) {
391
// Check whether this entry has an extension typically associated with
392
// headers.
393
if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
394
.Cases(".h", ".H", ".hh", ".hpp", true)
395
.Default(false))
396
continue;
397
398
auto Header = FileMgr.getOptionalFileRef(Dir->path());
399
// FIXME: This shouldn't happen unless there is a file system race. Is
400
// that worth diagnosing?
401
if (!Header)
402
continue;
403
404
// If this header is marked 'unavailable' in this module, don't include
405
// it.
406
if (ModMap.isHeaderUnavailableInModule(*Header, Module))
407
continue;
408
409
// Compute the relative path from the directory to this file.
410
SmallVector<StringRef, 16> Components;
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);
414
SmallString<128> RelativeHeader(
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
// Sort header paths and make the header inclusion order deterministic
428
// across different OSs and filesystems.
429
llvm::sort(Headers, llvm::less_first());
430
for (auto &H : Headers) {
431
// Include this header as part of the umbrella directory.
432
Module->addTopHeader(H.second);
433
addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC);
434
}
435
}
436
437
// Recurse into submodules.
438
for (auto *Submodule : Module->submodules())
439
if (std::error_code Err = collectModuleHeaderIncludes(
440
LangOpts, FileMgr, Diag, ModMap, Submodule, Includes))
441
return Err;
442
443
return std::error_code();
444
}
445
446
static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
447
bool IsPreprocessed,
448
std::string &PresumedModuleMapFile,
449
unsigned &Offset) {
450
auto &SrcMgr = CI.getSourceManager();
451
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
452
453
// Map the current input to a file.
454
FileID ModuleMapID = SrcMgr.getMainFileID();
455
OptionalFileEntryRef ModuleMap = SrcMgr.getFileEntryRefForID(ModuleMapID);
456
assert(ModuleMap && "MainFileID without FileEntry");
457
458
// If the module map is preprocessed, handle the initial line marker;
459
// line directives are not part of the module map syntax in general.
460
Offset = 0;
461
if (IsPreprocessed) {
462
SourceLocation EndOfLineMarker =
463
ReadOriginalFileName(CI, PresumedModuleMapFile, /*IsModuleMap*/ true);
464
if (EndOfLineMarker.isValid())
465
Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
466
}
467
468
// Load the module map file.
469
if (HS.loadModuleMapFile(*ModuleMap, IsSystem, ModuleMapID, &Offset,
470
PresumedModuleMapFile))
471
return true;
472
473
if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)
474
Offset = 0;
475
476
// Infer framework module if possible.
477
if (HS.getModuleMap().canInferFrameworkModule(ModuleMap->getDir())) {
478
SmallString<128> InferredFrameworkPath = ModuleMap->getDir().getName();
479
llvm::sys::path::append(InferredFrameworkPath,
480
CI.getLangOpts().ModuleName + ".framework");
481
if (auto Dir =
482
CI.getFileManager().getOptionalDirectoryRef(InferredFrameworkPath))
483
(void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr);
484
}
485
486
return false;
487
}
488
489
static Module *prepareToBuildModule(CompilerInstance &CI,
490
StringRef ModuleMapFilename) {
491
if (CI.getLangOpts().CurrentModule.empty()) {
492
CI.getDiagnostics().Report(diag::err_missing_module_name);
493
494
// FIXME: Eventually, we could consider asking whether there was just
495
// a single module described in the module map, and use that as a
496
// default. Then it would be fairly trivial to just "compile" a module
497
// map with a single module (the common case).
498
return nullptr;
499
}
500
501
// Dig out the module definition.
502
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
503
Module *M = HS.lookupModule(CI.getLangOpts().CurrentModule, SourceLocation(),
504
/*AllowSearch=*/true);
505
if (!M) {
506
CI.getDiagnostics().Report(diag::err_missing_module)
507
<< CI.getLangOpts().CurrentModule << ModuleMapFilename;
508
509
return nullptr;
510
}
511
512
// Check whether we can build this module at all.
513
if (Preprocessor::checkModuleIsAvailable(CI.getLangOpts(), CI.getTarget(), *M,
514
CI.getDiagnostics()))
515
return nullptr;
516
517
// Inform the preprocessor that includes from within the input buffer should
518
// be resolved relative to the build directory of the module map file.
519
CI.getPreprocessor().setMainFileDir(*M->Directory);
520
521
// If the module was inferred from a different module map (via an expanded
522
// umbrella module definition), track that fact.
523
// FIXME: It would be preferable to fill this in as part of processing
524
// the module map, rather than adding it after the fact.
525
StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
526
if (!OriginalModuleMapName.empty()) {
527
auto OriginalModuleMap =
528
CI.getFileManager().getOptionalFileRef(OriginalModuleMapName,
529
/*openFile*/ true);
530
if (!OriginalModuleMap) {
531
CI.getDiagnostics().Report(diag::err_module_map_not_found)
532
<< OriginalModuleMapName;
533
return nullptr;
534
}
535
if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
536
CI.getSourceManager().getMainFileID())) {
537
M->IsInferred = true;
538
auto FileCharacter =
539
M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
540
FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(
541
*OriginalModuleMap, FileCharacter);
542
CI.getPreprocessor()
543
.getHeaderSearchInfo()
544
.getModuleMap()
545
.setInferredModuleAllowedBy(M, OriginalModuleMapFID);
546
}
547
}
548
549
// If we're being run from the command-line, the module build stack will not
550
// have been filled in yet, so complete it now in order to allow us to detect
551
// module cycles.
552
SourceManager &SourceMgr = CI.getSourceManager();
553
if (SourceMgr.getModuleBuildStack().empty())
554
SourceMgr.pushModuleBuildStack(CI.getLangOpts().CurrentModule,
555
FullSourceLoc(SourceLocation(), SourceMgr));
556
return M;
557
}
558
559
/// Compute the input buffer that should be used to build the specified module.
560
static std::unique_ptr<llvm::MemoryBuffer>
561
getInputBufferForModule(CompilerInstance &CI, Module *M) {
562
FileManager &FileMgr = CI.getFileManager();
563
564
// Collect the set of #includes we need to build the module.
565
SmallString<256> HeaderContents;
566
std::error_code Err = std::error_code();
567
if (std::optional<Module::Header> UmbrellaHeader =
568
M->getUmbrellaHeaderAsWritten())
569
addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
570
HeaderContents, CI.getLangOpts(), M->IsExternC);
571
Err = collectModuleHeaderIncludes(
572
CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
573
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), M,
574
HeaderContents);
575
576
if (Err) {
577
CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
578
<< M->getFullModuleName() << Err.message();
579
return nullptr;
580
}
581
582
return llvm::MemoryBuffer::getMemBufferCopy(
583
HeaderContents, Module::getModuleInputBufferName());
584
}
585
586
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
587
const FrontendInputFile &RealInput) {
588
FrontendInputFile Input(RealInput);
589
assert(!Instance && "Already processing a source file!");
590
assert(!Input.isEmpty() && "Unexpected empty filename!");
591
setCurrentInput(Input);
592
setCompilerInstance(&CI);
593
594
bool HasBegunSourceFile = false;
595
bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled &&
596
usesPreprocessorOnly();
597
598
// If we fail, reset state since the client will not end up calling the
599
// matching EndSourceFile(). All paths that return true should release this.
600
auto FailureCleanup = llvm::make_scope_exit([&]() {
601
if (HasBegunSourceFile)
602
CI.getDiagnosticClient().EndSourceFile();
603
CI.setASTConsumer(nullptr);
604
CI.clearOutputFiles(/*EraseFiles=*/true);
605
CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
606
setCurrentInput(FrontendInputFile());
607
setCompilerInstance(nullptr);
608
});
609
610
if (!BeginInvocation(CI))
611
return false;
612
613
// If we're replaying the build of an AST file, import it and set up
614
// the initial state from its build.
615
if (ReplayASTFile) {
616
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
617
618
// The AST unit populates its own diagnostics engine rather than ours.
619
IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags(
620
new DiagnosticsEngine(Diags->getDiagnosticIDs(),
621
&Diags->getDiagnosticOptions()));
622
ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
623
624
// FIXME: What if the input is a memory buffer?
625
StringRef InputFile = Input.getFile();
626
627
std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
628
std::string(InputFile), CI.getPCHContainerReader(),
629
ASTUnit::LoadPreprocessorOnly, ASTDiags, CI.getFileSystemOpts(),
630
/*HeaderSearchOptions=*/nullptr);
631
if (!AST)
632
return false;
633
634
// Options relating to how we treat the input (but not what we do with it)
635
// are inherited from the AST unit.
636
CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts();
637
CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
638
CI.getLangOpts() = AST->getLangOpts();
639
640
// Set the shared objects, these are reset when we finish processing the
641
// file, otherwise the CompilerInstance will happily destroy them.
642
CI.setFileManager(&AST->getFileManager());
643
CI.createSourceManager(CI.getFileManager());
644
CI.getSourceManager().initializeForReplay(AST->getSourceManager());
645
646
// Preload all the module files loaded transitively by the AST unit. Also
647
// load all module map files that were parsed as part of building the AST
648
// unit.
649
if (auto ASTReader = AST->getASTReader()) {
650
auto &MM = ASTReader->getModuleManager();
651
auto &PrimaryModule = MM.getPrimaryModule();
652
653
for (serialization::ModuleFile &MF : MM)
654
if (&MF != &PrimaryModule)
655
CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
656
657
ASTReader->visitTopLevelModuleMaps(PrimaryModule, [&](FileEntryRef FE) {
658
CI.getFrontendOpts().ModuleMapFiles.push_back(
659
std::string(FE.getName()));
660
});
661
}
662
663
// Set up the input file for replay purposes.
664
auto Kind = AST->getInputKind();
665
if (Kind.getFormat() == InputKind::ModuleMap) {
666
Module *ASTModule =
667
AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
668
AST->getLangOpts().CurrentModule, SourceLocation(),
669
/*AllowSearch*/ false);
670
assert(ASTModule && "module file does not define its own module");
671
Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
672
} else {
673
auto &OldSM = AST->getSourceManager();
674
FileID ID = OldSM.getMainFileID();
675
if (auto File = OldSM.getFileEntryRefForID(ID))
676
Input = FrontendInputFile(File->getName(), Kind);
677
else
678
Input = FrontendInputFile(OldSM.getBufferOrFake(ID), Kind);
679
}
680
setCurrentInput(Input, std::move(AST));
681
}
682
683
// AST files follow a very different path, since they share objects via the
684
// AST unit.
685
if (Input.getKind().getFormat() == InputKind::Precompiled) {
686
assert(!usesPreprocessorOnly() && "this case was handled above");
687
assert(hasASTFileSupport() &&
688
"This action does not have AST file support!");
689
690
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
691
692
// FIXME: What if the input is a memory buffer?
693
StringRef InputFile = Input.getFile();
694
695
std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
696
std::string(InputFile), CI.getPCHContainerReader(),
697
ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(),
698
CI.getHeaderSearchOptsPtr(), CI.getLangOptsPtr());
699
700
if (!AST)
701
return false;
702
703
// Inform the diagnostic client we are processing a source file.
704
CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
705
HasBegunSourceFile = true;
706
707
// Set the shared objects, these are reset when we finish processing the
708
// file, otherwise the CompilerInstance will happily destroy them.
709
CI.setFileManager(&AST->getFileManager());
710
CI.setSourceManager(&AST->getSourceManager());
711
CI.setPreprocessor(AST->getPreprocessorPtr());
712
Preprocessor &PP = CI.getPreprocessor();
713
PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
714
PP.getLangOpts());
715
CI.setASTContext(&AST->getASTContext());
716
717
setCurrentInput(Input, std::move(AST));
718
719
// Initialize the action.
720
if (!BeginSourceFileAction(CI))
721
return false;
722
723
// Create the AST consumer.
724
CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
725
if (!CI.hasASTConsumer())
726
return false;
727
728
FailureCleanup.release();
729
return true;
730
}
731
732
// Set up the file and source managers, if needed.
733
if (!CI.hasFileManager()) {
734
if (!CI.createFileManager()) {
735
return false;
736
}
737
}
738
if (!CI.hasSourceManager()) {
739
CI.createSourceManager(CI.getFileManager());
740
if (CI.getDiagnosticOpts().getFormat() == DiagnosticOptions::SARIF) {
741
static_cast<SARIFDiagnosticPrinter *>(&CI.getDiagnosticClient())
742
->setSarifWriter(
743
std::make_unique<SarifDocumentWriter>(CI.getSourceManager()));
744
}
745
}
746
747
// Set up embedding for any specified files. Do this before we load any
748
// source files, including the primary module map for the compilation.
749
for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
750
if (auto FE = CI.getFileManager().getOptionalFileRef(F, /*openFile*/true))
751
CI.getSourceManager().setFileIsTransient(*FE);
752
else
753
CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
754
}
755
if (CI.getFrontendOpts().ModulesEmbedAllFiles)
756
CI.getSourceManager().setAllFilesAreTransient(true);
757
758
// IR files bypass the rest of initialization.
759
if (Input.getKind().getLanguage() == Language::LLVM_IR) {
760
if (!hasIRSupport()) {
761
CI.getDiagnostics().Report(diag::err_ast_action_on_llvm_ir)
762
<< Input.getFile();
763
return false;
764
}
765
766
// Inform the diagnostic client we are processing a source file.
767
CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
768
HasBegunSourceFile = true;
769
770
// Initialize the action.
771
if (!BeginSourceFileAction(CI))
772
return false;
773
774
// Initialize the main file entry.
775
if (!CI.InitializeSourceManager(CurrentInput))
776
return false;
777
778
FailureCleanup.release();
779
return true;
780
}
781
782
// If the implicit PCH include is actually a directory, rather than
783
// a single file, search for a suitable PCH file in that directory.
784
if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
785
FileManager &FileMgr = CI.getFileManager();
786
PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
787
StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
788
std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
789
if (auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude)) {
790
std::error_code EC;
791
SmallString<128> DirNative;
792
llvm::sys::path::native(PCHDir->getName(), DirNative);
793
bool Found = false;
794
llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
795
for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
796
DirEnd;
797
Dir != DirEnd && !EC; Dir.increment(EC)) {
798
// Check whether this is an acceptable AST file.
799
if (ASTReader::isAcceptableASTFile(
800
Dir->path(), FileMgr, CI.getModuleCache(),
801
CI.getPCHContainerReader(), CI.getLangOpts(),
802
CI.getTargetOpts(), CI.getPreprocessorOpts(),
803
SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
804
PPOpts.ImplicitPCHInclude = std::string(Dir->path());
805
Found = true;
806
break;
807
}
808
}
809
810
if (!Found) {
811
CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
812
return false;
813
}
814
}
815
}
816
817
// Set up the preprocessor if needed. When parsing model files the
818
// preprocessor of the original source is reused.
819
if (!isModelParsingAction())
820
CI.createPreprocessor(getTranslationUnitKind());
821
822
// Inform the diagnostic client we are processing a source file.
823
CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
824
&CI.getPreprocessor());
825
HasBegunSourceFile = true;
826
827
// Handle C++20 header units.
828
// Here, the user has the option to specify that the header name should be
829
// looked up in the pre-processor search paths (and the main filename as
830
// passed by the driver might therefore be incomplete until that look-up).
831
if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
832
!Input.getKind().isPreprocessed()) {
833
StringRef FileName = Input.getFile();
834
InputKind Kind = Input.getKind();
835
if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) {
836
assert(CI.hasPreprocessor() &&
837
"trying to build a header unit without a Pre-processor?");
838
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
839
// Relative searches begin from CWD.
840
auto Dir = CI.getFileManager().getOptionalDirectoryRef(".");
841
SmallVector<std::pair<OptionalFileEntryRef, DirectoryEntryRef>, 1> CWD;
842
CWD.push_back({std::nullopt, *Dir});
843
OptionalFileEntryRef FE =
844
HS.LookupFile(FileName, SourceLocation(),
845
/*Angled*/ Input.getKind().getHeaderUnitKind() ==
846
InputKind::HeaderUnit_System,
847
nullptr, nullptr, CWD, nullptr, nullptr, nullptr,
848
nullptr, nullptr, nullptr);
849
if (!FE) {
850
CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
851
<< FileName;
852
return false;
853
}
854
// We now have the filename...
855
FileName = FE->getName();
856
// ... still a header unit, but now use the path as written.
857
Kind = Input.getKind().withHeaderUnit(InputKind::HeaderUnit_Abs);
858
Input = FrontendInputFile(FileName, Kind, Input.isSystem());
859
}
860
// Unless the user has overridden the name, the header unit module name is
861
// the pathname for the file.
862
if (CI.getLangOpts().ModuleName.empty())
863
CI.getLangOpts().ModuleName = std::string(FileName);
864
CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
865
}
866
867
if (!CI.InitializeSourceManager(Input))
868
return false;
869
870
if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
871
Input.getKind().isPreprocessed() && !usesPreprocessorOnly()) {
872
// We have an input filename like foo.iih, but we want to find the right
873
// module name (and original file, to build the map entry).
874
// Check if the first line specifies the original source file name with a
875
// linemarker.
876
std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
877
ReadOriginalFileName(CI, PresumedInputFile);
878
// Unless the user overrides this, the module name is the name by which the
879
// original file was known.
880
if (CI.getLangOpts().ModuleName.empty())
881
CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
882
CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
883
}
884
885
// For module map files, we first parse the module map and synthesize a
886
// "<module-includes>" buffer before more conventional processing.
887
if (Input.getKind().getFormat() == InputKind::ModuleMap) {
888
CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
889
890
std::string PresumedModuleMapFile;
891
unsigned OffsetToContents;
892
if (loadModuleMapForModuleBuild(CI, Input.isSystem(),
893
Input.isPreprocessed(),
894
PresumedModuleMapFile, OffsetToContents))
895
return false;
896
897
auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
898
if (!CurrentModule)
899
return false;
900
901
CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
902
903
if (OffsetToContents)
904
// If the module contents are in the same file, skip to them.
905
CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
906
else {
907
// Otherwise, convert the module description to a suitable input buffer.
908
auto Buffer = getInputBufferForModule(CI, CurrentModule);
909
if (!Buffer)
910
return false;
911
912
// Reinitialize the main file entry to refer to the new input.
913
auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
914
auto &SourceMgr = CI.getSourceManager();
915
auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
916
assert(BufferID.isValid() && "couldn't create module buffer ID");
917
SourceMgr.setMainFileID(BufferID);
918
}
919
}
920
921
// Initialize the action.
922
if (!BeginSourceFileAction(CI))
923
return false;
924
925
// If we were asked to load any module map files, do so now.
926
for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
927
if (auto File = CI.getFileManager().getOptionalFileRef(Filename))
928
CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
929
*File, /*IsSystem*/false);
930
else
931
CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
932
}
933
934
// If compiling implementation of a module, load its module map file now.
935
(void)CI.getPreprocessor().getCurrentModuleImplementation();
936
937
// Add a module declaration scope so that modules from -fmodule-map-file
938
// arguments may shadow modules found implicitly in search paths.
939
CI.getPreprocessor()
940
.getHeaderSearchInfo()
941
.getModuleMap()
942
.finishModuleDeclarationScope();
943
944
// Create the AST context and consumer unless this is a preprocessor only
945
// action.
946
if (!usesPreprocessorOnly()) {
947
// Parsing a model file should reuse the existing ASTContext.
948
if (!isModelParsingAction())
949
CI.createASTContext();
950
951
// For preprocessed files, check if the first line specifies the original
952
// source file name with a linemarker.
953
std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
954
if (Input.isPreprocessed())
955
ReadOriginalFileName(CI, PresumedInputFile);
956
957
std::unique_ptr<ASTConsumer> Consumer =
958
CreateWrappedASTConsumer(CI, PresumedInputFile);
959
if (!Consumer)
960
return false;
961
962
// FIXME: should not overwrite ASTMutationListener when parsing model files?
963
if (!isModelParsingAction())
964
CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
965
966
if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
967
// Convert headers to PCH and chain them.
968
IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
969
source = createChainedIncludesSource(CI, FinalReader);
970
if (!source)
971
return false;
972
CI.setASTReader(static_cast<ASTReader *>(FinalReader.get()));
973
CI.getASTContext().setExternalSource(source);
974
} else if (CI.getLangOpts().Modules ||
975
!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
976
// Use PCM or PCH.
977
assert(hasPCHSupport() && "This action does not have PCH support!");
978
ASTDeserializationListener *DeserialListener =
979
Consumer->GetASTDeserializationListener();
980
bool DeleteDeserialListener = false;
981
if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
982
DeserialListener = new DeserializedDeclsDumper(DeserialListener,
983
DeleteDeserialListener);
984
DeleteDeserialListener = true;
985
}
986
if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
987
DeserialListener = new DeserializedDeclsChecker(
988
CI.getASTContext(),
989
CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
990
DeserialListener, DeleteDeserialListener);
991
DeleteDeserialListener = true;
992
}
993
if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
994
CI.createPCHExternalASTSource(
995
CI.getPreprocessorOpts().ImplicitPCHInclude,
996
CI.getPreprocessorOpts().DisablePCHOrModuleValidation,
997
CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
998
DeserialListener, DeleteDeserialListener);
999
if (!CI.getASTContext().getExternalSource())
1000
return false;
1001
}
1002
// If modules are enabled, create the AST reader before creating
1003
// any builtins, so that all declarations know that they might be
1004
// extended by an external source.
1005
if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1006
!CI.getASTContext().getExternalSource()) {
1007
CI.createASTReader();
1008
CI.getASTReader()->setDeserializationListener(DeserialListener,
1009
DeleteDeserialListener);
1010
}
1011
}
1012
1013
CI.setASTConsumer(std::move(Consumer));
1014
if (!CI.hasASTConsumer())
1015
return false;
1016
}
1017
1018
// Initialize built-in info as long as we aren't using an external AST
1019
// source.
1020
if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1021
!CI.getASTContext().getExternalSource()) {
1022
Preprocessor &PP = CI.getPreprocessor();
1023
PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
1024
PP.getLangOpts());
1025
} else {
1026
// FIXME: If this is a problem, recover from it by creating a multiplex
1027
// source.
1028
assert((!CI.getLangOpts().Modules || CI.getASTReader()) &&
1029
"modules enabled but created an external source that "
1030
"doesn't support modules");
1031
}
1032
1033
// If we were asked to load any module files, do so now.
1034
for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
1035
serialization::ModuleFile *Loaded = nullptr;
1036
if (!CI.loadModuleFile(ModuleFile, Loaded))
1037
return false;
1038
1039
if (Loaded && Loaded->StandardCXXModule)
1040
CI.getDiagnostics().Report(
1041
diag::warn_eagerly_load_for_standard_cplusplus_modules);
1042
}
1043
1044
// If there is a layout overrides file, attach an external AST source that
1045
// provides the layouts from that file.
1046
if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
1047
CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
1048
IntrusiveRefCntPtr<ExternalASTSource>
1049
Override(new LayoutOverrideSource(
1050
CI.getFrontendOpts().OverrideRecordLayoutsFile));
1051
CI.getASTContext().setExternalSource(Override);
1052
}
1053
1054
// Setup HLSL External Sema Source
1055
if (CI.getLangOpts().HLSL && CI.hasASTContext()) {
1056
IntrusiveRefCntPtr<ExternalSemaSource> HLSLSema(
1057
new HLSLExternalSemaSource());
1058
if (auto *SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1059
CI.getASTContext().getExternalSource())) {
1060
IntrusiveRefCntPtr<ExternalSemaSource> MultiSema(
1061
new MultiplexExternalSemaSource(SemaSource, HLSLSema.get()));
1062
CI.getASTContext().setExternalSource(MultiSema);
1063
} else
1064
CI.getASTContext().setExternalSource(HLSLSema);
1065
}
1066
1067
FailureCleanup.release();
1068
return true;
1069
}
1070
1071
llvm::Error FrontendAction::Execute() {
1072
CompilerInstance &CI = getCompilerInstance();
1073
1074
if (CI.hasFrontendTimer()) {
1075
llvm::TimeRegion Timer(CI.getFrontendTimer());
1076
ExecuteAction();
1077
}
1078
else ExecuteAction();
1079
1080
// If we are supposed to rebuild the global module index, do so now unless
1081
// there were any module-build failures.
1082
if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
1083
CI.hasPreprocessor()) {
1084
StringRef Cache =
1085
CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
1086
if (!Cache.empty()) {
1087
if (llvm::Error Err = GlobalModuleIndex::writeIndex(
1088
CI.getFileManager(), CI.getPCHContainerReader(), Cache)) {
1089
// FIXME this drops the error on the floor, but
1090
// Index/pch-from-libclang.c seems to rely on dropping at least some of
1091
// the error conditions!
1092
consumeError(std::move(Err));
1093
}
1094
}
1095
}
1096
1097
return llvm::Error::success();
1098
}
1099
1100
void FrontendAction::EndSourceFile() {
1101
CompilerInstance &CI = getCompilerInstance();
1102
1103
// Inform the diagnostic client we are done with this source file.
1104
CI.getDiagnosticClient().EndSourceFile();
1105
1106
// Inform the preprocessor we are done.
1107
if (CI.hasPreprocessor())
1108
CI.getPreprocessor().EndSourceFile();
1109
1110
// Finalize the action.
1111
EndSourceFileAction();
1112
1113
// Sema references the ast consumer, so reset sema first.
1114
//
1115
// FIXME: There is more per-file stuff we could just drop here?
1116
bool DisableFree = CI.getFrontendOpts().DisableFree;
1117
if (DisableFree) {
1118
CI.resetAndLeakSema();
1119
CI.resetAndLeakASTContext();
1120
llvm::BuryPointer(CI.takeASTConsumer().get());
1121
} else {
1122
CI.setSema(nullptr);
1123
CI.setASTContext(nullptr);
1124
CI.setASTConsumer(nullptr);
1125
}
1126
1127
if (CI.getFrontendOpts().ShowStats) {
1128
llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n";
1129
CI.getPreprocessor().PrintStats();
1130
CI.getPreprocessor().getIdentifierTable().PrintStats();
1131
CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
1132
CI.getSourceManager().PrintStats();
1133
llvm::errs() << "\n";
1134
}
1135
1136
// Cleanup the output streams, and erase the output files if instructed by the
1137
// FrontendAction.
1138
CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
1139
1140
// The resources are owned by AST when the current file is AST.
1141
// So we reset the resources here to avoid users accessing it
1142
// accidently.
1143
if (isCurrentFileAST()) {
1144
if (DisableFree) {
1145
CI.resetAndLeakPreprocessor();
1146
CI.resetAndLeakSourceManager();
1147
CI.resetAndLeakFileManager();
1148
llvm::BuryPointer(std::move(CurrentASTUnit));
1149
} else {
1150
CI.setPreprocessor(nullptr);
1151
CI.setSourceManager(nullptr);
1152
CI.setFileManager(nullptr);
1153
}
1154
}
1155
1156
setCompilerInstance(nullptr);
1157
setCurrentInput(FrontendInputFile());
1158
CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
1159
}
1160
1161
bool FrontendAction::shouldEraseOutputFiles() {
1162
return getCompilerInstance().getDiagnostics().hasErrorOccurred();
1163
}
1164
1165
//===----------------------------------------------------------------------===//
1166
// Utility Actions
1167
//===----------------------------------------------------------------------===//
1168
1169
void ASTFrontendAction::ExecuteAction() {
1170
CompilerInstance &CI = getCompilerInstance();
1171
if (!CI.hasPreprocessor())
1172
return;
1173
// This is a fallback: If the client forgets to invoke this, we mark the
1174
// current stack as the bottom. Though not optimal, this could help prevent
1175
// stack overflow during deep recursion.
1176
clang::noteBottomOfStack();
1177
1178
// FIXME: Move the truncation aspect of this into Sema, we delayed this till
1179
// here so the source manager would be initialized.
1180
if (hasCodeCompletionSupport() &&
1181
!CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
1182
CI.createCodeCompletionConsumer();
1183
1184
// Use a code completion consumer?
1185
CodeCompleteConsumer *CompletionConsumer = nullptr;
1186
if (CI.hasCodeCompletionConsumer())
1187
CompletionConsumer = &CI.getCodeCompletionConsumer();
1188
1189
if (!CI.hasSema())
1190
CI.createSema(getTranslationUnitKind(), CompletionConsumer);
1191
1192
ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats,
1193
CI.getFrontendOpts().SkipFunctionBodies);
1194
}
1195
1196
void PluginASTAction::anchor() { }
1197
1198
std::unique_ptr<ASTConsumer>
1199
PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
1200
StringRef InFile) {
1201
llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
1202
}
1203
1204
bool WrapperFrontendAction::PrepareToExecuteAction(CompilerInstance &CI) {
1205
return WrappedAction->PrepareToExecuteAction(CI);
1206
}
1207
std::unique_ptr<ASTConsumer>
1208
WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
1209
StringRef InFile) {
1210
return WrappedAction->CreateASTConsumer(CI, InFile);
1211
}
1212
bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) {
1213
return WrappedAction->BeginInvocation(CI);
1214
}
1215
bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI) {
1216
WrappedAction->setCurrentInput(getCurrentInput());
1217
WrappedAction->setCompilerInstance(&CI);
1218
auto Ret = WrappedAction->BeginSourceFileAction(CI);
1219
// BeginSourceFileAction may change CurrentInput, e.g. during module builds.
1220
setCurrentInput(WrappedAction->getCurrentInput());
1221
return Ret;
1222
}
1223
void WrapperFrontendAction::ExecuteAction() {
1224
WrappedAction->ExecuteAction();
1225
}
1226
void WrapperFrontendAction::EndSourceFile() { WrappedAction->EndSourceFile(); }
1227
void WrapperFrontendAction::EndSourceFileAction() {
1228
WrappedAction->EndSourceFileAction();
1229
}
1230
bool WrapperFrontendAction::shouldEraseOutputFiles() {
1231
return WrappedAction->shouldEraseOutputFiles();
1232
}
1233
1234
bool WrapperFrontendAction::usesPreprocessorOnly() const {
1235
return WrappedAction->usesPreprocessorOnly();
1236
}
1237
TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() {
1238
return WrappedAction->getTranslationUnitKind();
1239
}
1240
bool WrapperFrontendAction::hasPCHSupport() const {
1241
return WrappedAction->hasPCHSupport();
1242
}
1243
bool WrapperFrontendAction::hasASTFileSupport() const {
1244
return WrappedAction->hasASTFileSupport();
1245
}
1246
bool WrapperFrontendAction::hasIRSupport() const {
1247
return WrappedAction->hasIRSupport();
1248
}
1249
bool WrapperFrontendAction::hasCodeCompletionSupport() const {
1250
return WrappedAction->hasCodeCompletionSupport();
1251
}
1252
1253
WrapperFrontendAction::WrapperFrontendAction(
1254
std::unique_ptr<FrontendAction> WrappedAction)
1255
: WrappedAction(std::move(WrappedAction)) {}
1256
1257