1*67e74705SXin Li //===--- FrontendAction.cpp -----------------------------------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "clang/Frontend/FrontendAction.h"
11*67e74705SXin Li #include "clang/AST/ASTConsumer.h"
12*67e74705SXin Li #include "clang/AST/ASTContext.h"
13*67e74705SXin Li #include "clang/AST/DeclGroup.h"
14*67e74705SXin Li #include "clang/Frontend/ASTUnit.h"
15*67e74705SXin Li #include "clang/Frontend/CompilerInstance.h"
16*67e74705SXin Li #include "clang/Frontend/FrontendDiagnostic.h"
17*67e74705SXin Li #include "clang/Frontend/FrontendPluginRegistry.h"
18*67e74705SXin Li #include "clang/Frontend/LayoutOverrideSource.h"
19*67e74705SXin Li #include "clang/Frontend/MultiplexConsumer.h"
20*67e74705SXin Li #include "clang/Frontend/Utils.h"
21*67e74705SXin Li #include "clang/Lex/HeaderSearch.h"
22*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
23*67e74705SXin Li #include "clang/Parse/ParseAST.h"
24*67e74705SXin Li #include "clang/Serialization/ASTDeserializationListener.h"
25*67e74705SXin Li #include "clang/Serialization/ASTReader.h"
26*67e74705SXin Li #include "clang/Serialization/GlobalModuleIndex.h"
27*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
28*67e74705SXin Li #include "llvm/Support/FileSystem.h"
29*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h"
30*67e74705SXin Li #include "llvm/Support/Timer.h"
31*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
32*67e74705SXin Li #include <system_error>
33*67e74705SXin Li using namespace clang;
34*67e74705SXin Li
35*67e74705SXin Li template class llvm::Registry<clang::PluginASTAction>;
36*67e74705SXin Li
37*67e74705SXin Li namespace {
38*67e74705SXin Li
39*67e74705SXin Li class DelegatingDeserializationListener : public ASTDeserializationListener {
40*67e74705SXin Li ASTDeserializationListener *Previous;
41*67e74705SXin Li bool DeletePrevious;
42*67e74705SXin Li
43*67e74705SXin Li public:
DelegatingDeserializationListener(ASTDeserializationListener * Previous,bool DeletePrevious)44*67e74705SXin Li explicit DelegatingDeserializationListener(
45*67e74705SXin Li ASTDeserializationListener *Previous, bool DeletePrevious)
46*67e74705SXin Li : Previous(Previous), DeletePrevious(DeletePrevious) {}
~DelegatingDeserializationListener()47*67e74705SXin Li ~DelegatingDeserializationListener() override {
48*67e74705SXin Li if (DeletePrevious)
49*67e74705SXin Li delete Previous;
50*67e74705SXin Li }
51*67e74705SXin Li
ReaderInitialized(ASTReader * Reader)52*67e74705SXin Li void ReaderInitialized(ASTReader *Reader) override {
53*67e74705SXin Li if (Previous)
54*67e74705SXin Li Previous->ReaderInitialized(Reader);
55*67e74705SXin Li }
IdentifierRead(serialization::IdentID ID,IdentifierInfo * II)56*67e74705SXin Li void IdentifierRead(serialization::IdentID ID,
57*67e74705SXin Li IdentifierInfo *II) override {
58*67e74705SXin Li if (Previous)
59*67e74705SXin Li Previous->IdentifierRead(ID, II);
60*67e74705SXin Li }
TypeRead(serialization::TypeIdx Idx,QualType T)61*67e74705SXin Li void TypeRead(serialization::TypeIdx Idx, QualType T) override {
62*67e74705SXin Li if (Previous)
63*67e74705SXin Li Previous->TypeRead(Idx, T);
64*67e74705SXin Li }
DeclRead(serialization::DeclID ID,const Decl * D)65*67e74705SXin Li void DeclRead(serialization::DeclID ID, const Decl *D) override {
66*67e74705SXin Li if (Previous)
67*67e74705SXin Li Previous->DeclRead(ID, D);
68*67e74705SXin Li }
SelectorRead(serialization::SelectorID ID,Selector Sel)69*67e74705SXin Li void SelectorRead(serialization::SelectorID ID, Selector Sel) override {
70*67e74705SXin Li if (Previous)
71*67e74705SXin Li Previous->SelectorRead(ID, Sel);
72*67e74705SXin Li }
MacroDefinitionRead(serialization::PreprocessedEntityID PPID,MacroDefinitionRecord * MD)73*67e74705SXin Li void MacroDefinitionRead(serialization::PreprocessedEntityID PPID,
74*67e74705SXin Li MacroDefinitionRecord *MD) override {
75*67e74705SXin Li if (Previous)
76*67e74705SXin Li Previous->MacroDefinitionRead(PPID, MD);
77*67e74705SXin Li }
78*67e74705SXin Li };
79*67e74705SXin Li
80*67e74705SXin Li /// \brief Dumps deserialized declarations.
81*67e74705SXin Li class DeserializedDeclsDumper : public DelegatingDeserializationListener {
82*67e74705SXin Li public:
DeserializedDeclsDumper(ASTDeserializationListener * Previous,bool DeletePrevious)83*67e74705SXin Li explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
84*67e74705SXin Li bool DeletePrevious)
85*67e74705SXin Li : DelegatingDeserializationListener(Previous, DeletePrevious) {}
86*67e74705SXin Li
DeclRead(serialization::DeclID ID,const Decl * D)87*67e74705SXin Li void DeclRead(serialization::DeclID ID, const Decl *D) override {
88*67e74705SXin Li llvm::outs() << "PCH DECL: " << D->getDeclKindName();
89*67e74705SXin Li if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
90*67e74705SXin Li llvm::outs() << " - " << *ND;
91*67e74705SXin Li llvm::outs() << "\n";
92*67e74705SXin Li
93*67e74705SXin Li DelegatingDeserializationListener::DeclRead(ID, D);
94*67e74705SXin Li }
95*67e74705SXin Li };
96*67e74705SXin Li
97*67e74705SXin Li /// \brief Checks deserialized declarations and emits error if a name
98*67e74705SXin Li /// matches one given in command-line using -error-on-deserialized-decl.
99*67e74705SXin Li class DeserializedDeclsChecker : public DelegatingDeserializationListener {
100*67e74705SXin Li ASTContext &Ctx;
101*67e74705SXin Li std::set<std::string> NamesToCheck;
102*67e74705SXin Li
103*67e74705SXin Li public:
DeserializedDeclsChecker(ASTContext & Ctx,const std::set<std::string> & NamesToCheck,ASTDeserializationListener * Previous,bool DeletePrevious)104*67e74705SXin Li DeserializedDeclsChecker(ASTContext &Ctx,
105*67e74705SXin Li const std::set<std::string> &NamesToCheck,
106*67e74705SXin Li ASTDeserializationListener *Previous,
107*67e74705SXin Li bool DeletePrevious)
108*67e74705SXin Li : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
109*67e74705SXin Li NamesToCheck(NamesToCheck) {}
110*67e74705SXin Li
DeclRead(serialization::DeclID ID,const Decl * D)111*67e74705SXin Li void DeclRead(serialization::DeclID ID, const Decl *D) override {
112*67e74705SXin Li if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
113*67e74705SXin Li if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
114*67e74705SXin Li unsigned DiagID
115*67e74705SXin Li = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
116*67e74705SXin Li "%0 was deserialized");
117*67e74705SXin Li Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
118*67e74705SXin Li << ND->getNameAsString();
119*67e74705SXin Li }
120*67e74705SXin Li
121*67e74705SXin Li DelegatingDeserializationListener::DeclRead(ID, D);
122*67e74705SXin Li }
123*67e74705SXin Li };
124*67e74705SXin Li
125*67e74705SXin Li } // end anonymous namespace
126*67e74705SXin Li
FrontendAction()127*67e74705SXin Li FrontendAction::FrontendAction() : Instance(nullptr) {}
128*67e74705SXin Li
~FrontendAction()129*67e74705SXin Li FrontendAction::~FrontendAction() {}
130*67e74705SXin Li
setCurrentInput(const FrontendInputFile & CurrentInput,std::unique_ptr<ASTUnit> AST)131*67e74705SXin Li void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput,
132*67e74705SXin Li std::unique_ptr<ASTUnit> AST) {
133*67e74705SXin Li this->CurrentInput = CurrentInput;
134*67e74705SXin Li CurrentASTUnit = std::move(AST);
135*67e74705SXin Li }
136*67e74705SXin Li
137*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateWrappedASTConsumer(CompilerInstance & CI,StringRef InFile)138*67e74705SXin Li FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
139*67e74705SXin Li StringRef InFile) {
140*67e74705SXin Li std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
141*67e74705SXin Li if (!Consumer)
142*67e74705SXin Li return nullptr;
143*67e74705SXin Li
144*67e74705SXin Li // If there are no registered plugins we don't need to wrap the consumer
145*67e74705SXin Li if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
146*67e74705SXin Li return Consumer;
147*67e74705SXin Li
148*67e74705SXin Li // Collect the list of plugins that go before the main action (in Consumers)
149*67e74705SXin Li // or after it (in AfterConsumers)
150*67e74705SXin Li std::vector<std::unique_ptr<ASTConsumer>> Consumers;
151*67e74705SXin Li std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
152*67e74705SXin Li for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(),
153*67e74705SXin Li ie = FrontendPluginRegistry::end();
154*67e74705SXin Li it != ie; ++it) {
155*67e74705SXin Li std::unique_ptr<PluginASTAction> P = it->instantiate();
156*67e74705SXin Li PluginASTAction::ActionType ActionType = P->getActionType();
157*67e74705SXin Li if (ActionType == PluginASTAction::Cmdline) {
158*67e74705SXin Li // This is O(|plugins| * |add_plugins|), but since both numbers are
159*67e74705SXin Li // way below 50 in practice, that's ok.
160*67e74705SXin Li for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size();
161*67e74705SXin Li i != e; ++i) {
162*67e74705SXin Li if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) {
163*67e74705SXin Li ActionType = PluginASTAction::AddAfterMainAction;
164*67e74705SXin Li break;
165*67e74705SXin Li }
166*67e74705SXin Li }
167*67e74705SXin Li }
168*67e74705SXin Li if ((ActionType == PluginASTAction::AddBeforeMainAction ||
169*67e74705SXin Li ActionType == PluginASTAction::AddAfterMainAction) &&
170*67e74705SXin Li P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) {
171*67e74705SXin Li std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
172*67e74705SXin Li if (ActionType == PluginASTAction::AddBeforeMainAction) {
173*67e74705SXin Li Consumers.push_back(std::move(PluginConsumer));
174*67e74705SXin Li } else {
175*67e74705SXin Li AfterConsumers.push_back(std::move(PluginConsumer));
176*67e74705SXin Li }
177*67e74705SXin Li }
178*67e74705SXin Li }
179*67e74705SXin Li
180*67e74705SXin Li // Add to Consumers the main consumer, then all the plugins that go after it
181*67e74705SXin Li Consumers.push_back(std::move(Consumer));
182*67e74705SXin Li for (auto &C : AfterConsumers) {
183*67e74705SXin Li Consumers.push_back(std::move(C));
184*67e74705SXin Li }
185*67e74705SXin Li
186*67e74705SXin Li return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
187*67e74705SXin Li }
188*67e74705SXin Li
BeginSourceFile(CompilerInstance & CI,const FrontendInputFile & Input)189*67e74705SXin Li bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
190*67e74705SXin Li const FrontendInputFile &Input) {
191*67e74705SXin Li assert(!Instance && "Already processing a source file!");
192*67e74705SXin Li assert(!Input.isEmpty() && "Unexpected empty filename!");
193*67e74705SXin Li setCurrentInput(Input);
194*67e74705SXin Li setCompilerInstance(&CI);
195*67e74705SXin Li
196*67e74705SXin Li StringRef InputFile = Input.getFile();
197*67e74705SXin Li bool HasBegunSourceFile = false;
198*67e74705SXin Li if (!BeginInvocation(CI))
199*67e74705SXin Li goto failure;
200*67e74705SXin Li
201*67e74705SXin Li // AST files follow a very different path, since they share objects via the
202*67e74705SXin Li // AST unit.
203*67e74705SXin Li if (Input.getKind() == IK_AST) {
204*67e74705SXin Li assert(!usesPreprocessorOnly() &&
205*67e74705SXin Li "Attempt to pass AST file to preprocessor only action!");
206*67e74705SXin Li assert(hasASTFileSupport() &&
207*67e74705SXin Li "This action does not have AST file support!");
208*67e74705SXin Li
209*67e74705SXin Li IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
210*67e74705SXin Li
211*67e74705SXin Li std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
212*67e74705SXin Li InputFile, CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts(),
213*67e74705SXin Li CI.getCodeGenOpts().DebugTypeExtRefs);
214*67e74705SXin Li
215*67e74705SXin Li if (!AST)
216*67e74705SXin Li goto failure;
217*67e74705SXin Li
218*67e74705SXin Li // Inform the diagnostic client we are processing a source file.
219*67e74705SXin Li CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
220*67e74705SXin Li HasBegunSourceFile = true;
221*67e74705SXin Li
222*67e74705SXin Li // Set the shared objects, these are reset when we finish processing the
223*67e74705SXin Li // file, otherwise the CompilerInstance will happily destroy them.
224*67e74705SXin Li CI.setFileManager(&AST->getFileManager());
225*67e74705SXin Li CI.setSourceManager(&AST->getSourceManager());
226*67e74705SXin Li CI.setPreprocessor(&AST->getPreprocessor());
227*67e74705SXin Li CI.setASTContext(&AST->getASTContext());
228*67e74705SXin Li
229*67e74705SXin Li setCurrentInput(Input, std::move(AST));
230*67e74705SXin Li
231*67e74705SXin Li // Initialize the action.
232*67e74705SXin Li if (!BeginSourceFileAction(CI, InputFile))
233*67e74705SXin Li goto failure;
234*67e74705SXin Li
235*67e74705SXin Li // Create the AST consumer.
236*67e74705SXin Li CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
237*67e74705SXin Li if (!CI.hasASTConsumer())
238*67e74705SXin Li goto failure;
239*67e74705SXin Li
240*67e74705SXin Li return true;
241*67e74705SXin Li }
242*67e74705SXin Li
243*67e74705SXin Li if (!CI.hasVirtualFileSystem()) {
244*67e74705SXin Li if (IntrusiveRefCntPtr<vfs::FileSystem> VFS =
245*67e74705SXin Li createVFSFromCompilerInvocation(CI.getInvocation(),
246*67e74705SXin Li CI.getDiagnostics()))
247*67e74705SXin Li CI.setVirtualFileSystem(VFS);
248*67e74705SXin Li else
249*67e74705SXin Li goto failure;
250*67e74705SXin Li }
251*67e74705SXin Li
252*67e74705SXin Li // Set up the file and source managers, if needed.
253*67e74705SXin Li if (!CI.hasFileManager())
254*67e74705SXin Li CI.createFileManager();
255*67e74705SXin Li if (!CI.hasSourceManager())
256*67e74705SXin Li CI.createSourceManager(CI.getFileManager());
257*67e74705SXin Li
258*67e74705SXin Li // IR files bypass the rest of initialization.
259*67e74705SXin Li if (Input.getKind() == IK_LLVM_IR) {
260*67e74705SXin Li assert(hasIRSupport() &&
261*67e74705SXin Li "This action does not have IR file support!");
262*67e74705SXin Li
263*67e74705SXin Li // Inform the diagnostic client we are processing a source file.
264*67e74705SXin Li CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
265*67e74705SXin Li HasBegunSourceFile = true;
266*67e74705SXin Li
267*67e74705SXin Li // Initialize the action.
268*67e74705SXin Li if (!BeginSourceFileAction(CI, InputFile))
269*67e74705SXin Li goto failure;
270*67e74705SXin Li
271*67e74705SXin Li // Initialize the main file entry.
272*67e74705SXin Li if (!CI.InitializeSourceManager(CurrentInput))
273*67e74705SXin Li goto failure;
274*67e74705SXin Li
275*67e74705SXin Li return true;
276*67e74705SXin Li }
277*67e74705SXin Li
278*67e74705SXin Li // If the implicit PCH include is actually a directory, rather than
279*67e74705SXin Li // a single file, search for a suitable PCH file in that directory.
280*67e74705SXin Li if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
281*67e74705SXin Li FileManager &FileMgr = CI.getFileManager();
282*67e74705SXin Li PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
283*67e74705SXin Li StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
284*67e74705SXin Li std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
285*67e74705SXin Li if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) {
286*67e74705SXin Li std::error_code EC;
287*67e74705SXin Li SmallString<128> DirNative;
288*67e74705SXin Li llvm::sys::path::native(PCHDir->getName(), DirNative);
289*67e74705SXin Li bool Found = false;
290*67e74705SXin Li for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd;
291*67e74705SXin Li Dir != DirEnd && !EC; Dir.increment(EC)) {
292*67e74705SXin Li // Check whether this is an acceptable AST file.
293*67e74705SXin Li if (ASTReader::isAcceptableASTFile(
294*67e74705SXin Li Dir->path(), FileMgr, CI.getPCHContainerReader(),
295*67e74705SXin Li CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(),
296*67e74705SXin Li SpecificModuleCachePath)) {
297*67e74705SXin Li PPOpts.ImplicitPCHInclude = Dir->path();
298*67e74705SXin Li Found = true;
299*67e74705SXin Li break;
300*67e74705SXin Li }
301*67e74705SXin Li }
302*67e74705SXin Li
303*67e74705SXin Li if (!Found) {
304*67e74705SXin Li CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
305*67e74705SXin Li goto failure;
306*67e74705SXin Li }
307*67e74705SXin Li }
308*67e74705SXin Li }
309*67e74705SXin Li
310*67e74705SXin Li // Set up the preprocessor if needed. When parsing model files the
311*67e74705SXin Li // preprocessor of the original source is reused.
312*67e74705SXin Li if (!isModelParsingAction())
313*67e74705SXin Li CI.createPreprocessor(getTranslationUnitKind());
314*67e74705SXin Li
315*67e74705SXin Li // Inform the diagnostic client we are processing a source file.
316*67e74705SXin Li CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
317*67e74705SXin Li &CI.getPreprocessor());
318*67e74705SXin Li HasBegunSourceFile = true;
319*67e74705SXin Li
320*67e74705SXin Li // Initialize the action.
321*67e74705SXin Li if (!BeginSourceFileAction(CI, InputFile))
322*67e74705SXin Li goto failure;
323*67e74705SXin Li
324*67e74705SXin Li // Initialize the main file entry. It is important that this occurs after
325*67e74705SXin Li // BeginSourceFileAction, which may change CurrentInput during module builds.
326*67e74705SXin Li if (!CI.InitializeSourceManager(CurrentInput))
327*67e74705SXin Li goto failure;
328*67e74705SXin Li
329*67e74705SXin Li // Create the AST context and consumer unless this is a preprocessor only
330*67e74705SXin Li // action.
331*67e74705SXin Li if (!usesPreprocessorOnly()) {
332*67e74705SXin Li // Parsing a model file should reuse the existing ASTContext.
333*67e74705SXin Li if (!isModelParsingAction())
334*67e74705SXin Li CI.createASTContext();
335*67e74705SXin Li
336*67e74705SXin Li std::unique_ptr<ASTConsumer> Consumer =
337*67e74705SXin Li CreateWrappedASTConsumer(CI, InputFile);
338*67e74705SXin Li if (!Consumer)
339*67e74705SXin Li goto failure;
340*67e74705SXin Li
341*67e74705SXin Li // FIXME: should not overwrite ASTMutationListener when parsing model files?
342*67e74705SXin Li if (!isModelParsingAction())
343*67e74705SXin Li CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
344*67e74705SXin Li
345*67e74705SXin Li if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
346*67e74705SXin Li // Convert headers to PCH and chain them.
347*67e74705SXin Li IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
348*67e74705SXin Li source = createChainedIncludesSource(CI, FinalReader);
349*67e74705SXin Li if (!source)
350*67e74705SXin Li goto failure;
351*67e74705SXin Li CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get()));
352*67e74705SXin Li CI.getASTContext().setExternalSource(source);
353*67e74705SXin Li } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
354*67e74705SXin Li // Use PCH.
355*67e74705SXin Li assert(hasPCHSupport() && "This action does not have PCH support!");
356*67e74705SXin Li ASTDeserializationListener *DeserialListener =
357*67e74705SXin Li Consumer->GetASTDeserializationListener();
358*67e74705SXin Li bool DeleteDeserialListener = false;
359*67e74705SXin Li if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
360*67e74705SXin Li DeserialListener = new DeserializedDeclsDumper(DeserialListener,
361*67e74705SXin Li DeleteDeserialListener);
362*67e74705SXin Li DeleteDeserialListener = true;
363*67e74705SXin Li }
364*67e74705SXin Li if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
365*67e74705SXin Li DeserialListener = new DeserializedDeclsChecker(
366*67e74705SXin Li CI.getASTContext(),
367*67e74705SXin Li CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
368*67e74705SXin Li DeserialListener, DeleteDeserialListener);
369*67e74705SXin Li DeleteDeserialListener = true;
370*67e74705SXin Li }
371*67e74705SXin Li CI.createPCHExternalASTSource(
372*67e74705SXin Li CI.getPreprocessorOpts().ImplicitPCHInclude,
373*67e74705SXin Li CI.getPreprocessorOpts().DisablePCHValidation,
374*67e74705SXin Li CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener,
375*67e74705SXin Li DeleteDeserialListener);
376*67e74705SXin Li if (!CI.getASTContext().getExternalSource())
377*67e74705SXin Li goto failure;
378*67e74705SXin Li }
379*67e74705SXin Li
380*67e74705SXin Li CI.setASTConsumer(std::move(Consumer));
381*67e74705SXin Li if (!CI.hasASTConsumer())
382*67e74705SXin Li goto failure;
383*67e74705SXin Li }
384*67e74705SXin Li
385*67e74705SXin Li // Initialize built-in info as long as we aren't using an external AST
386*67e74705SXin Li // source.
387*67e74705SXin Li if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
388*67e74705SXin Li Preprocessor &PP = CI.getPreprocessor();
389*67e74705SXin Li
390*67e74705SXin Li // If modules are enabled, create the module manager before creating
391*67e74705SXin Li // any builtins, so that all declarations know that they might be
392*67e74705SXin Li // extended by an external source.
393*67e74705SXin Li if (CI.getLangOpts().Modules)
394*67e74705SXin Li CI.createModuleManager();
395*67e74705SXin Li
396*67e74705SXin Li PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
397*67e74705SXin Li PP.getLangOpts());
398*67e74705SXin Li } else {
399*67e74705SXin Li // FIXME: If this is a problem, recover from it by creating a multiplex
400*67e74705SXin Li // source.
401*67e74705SXin Li assert((!CI.getLangOpts().Modules || CI.getModuleManager()) &&
402*67e74705SXin Li "modules enabled but created an external source that "
403*67e74705SXin Li "doesn't support modules");
404*67e74705SXin Li }
405*67e74705SXin Li
406*67e74705SXin Li // If we were asked to load any module map files, do so now.
407*67e74705SXin Li for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
408*67e74705SXin Li if (auto *File = CI.getFileManager().getFile(Filename))
409*67e74705SXin Li CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
410*67e74705SXin Li File, /*IsSystem*/false);
411*67e74705SXin Li else
412*67e74705SXin Li CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
413*67e74705SXin Li }
414*67e74705SXin Li
415*67e74705SXin Li // If we were asked to load any module files, do so now.
416*67e74705SXin Li for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
417*67e74705SXin Li if (!CI.loadModuleFile(ModuleFile))
418*67e74705SXin Li goto failure;
419*67e74705SXin Li
420*67e74705SXin Li // If there is a layout overrides file, attach an external AST source that
421*67e74705SXin Li // provides the layouts from that file.
422*67e74705SXin Li if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
423*67e74705SXin Li CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
424*67e74705SXin Li IntrusiveRefCntPtr<ExternalASTSource>
425*67e74705SXin Li Override(new LayoutOverrideSource(
426*67e74705SXin Li CI.getFrontendOpts().OverrideRecordLayoutsFile));
427*67e74705SXin Li CI.getASTContext().setExternalSource(Override);
428*67e74705SXin Li }
429*67e74705SXin Li
430*67e74705SXin Li return true;
431*67e74705SXin Li
432*67e74705SXin Li // If we failed, reset state since the client will not end up calling the
433*67e74705SXin Li // matching EndSourceFile().
434*67e74705SXin Li failure:
435*67e74705SXin Li if (isCurrentFileAST()) {
436*67e74705SXin Li CI.setASTContext(nullptr);
437*67e74705SXin Li CI.setPreprocessor(nullptr);
438*67e74705SXin Li CI.setSourceManager(nullptr);
439*67e74705SXin Li CI.setFileManager(nullptr);
440*67e74705SXin Li }
441*67e74705SXin Li
442*67e74705SXin Li if (HasBegunSourceFile)
443*67e74705SXin Li CI.getDiagnosticClient().EndSourceFile();
444*67e74705SXin Li CI.clearOutputFiles(/*EraseFiles=*/true);
445*67e74705SXin Li setCurrentInput(FrontendInputFile());
446*67e74705SXin Li setCompilerInstance(nullptr);
447*67e74705SXin Li return false;
448*67e74705SXin Li }
449*67e74705SXin Li
Execute()450*67e74705SXin Li bool FrontendAction::Execute() {
451*67e74705SXin Li CompilerInstance &CI = getCompilerInstance();
452*67e74705SXin Li
453*67e74705SXin Li if (CI.hasFrontendTimer()) {
454*67e74705SXin Li llvm::TimeRegion Timer(CI.getFrontendTimer());
455*67e74705SXin Li ExecuteAction();
456*67e74705SXin Li }
457*67e74705SXin Li else ExecuteAction();
458*67e74705SXin Li
459*67e74705SXin Li // If we are supposed to rebuild the global module index, do so now unless
460*67e74705SXin Li // there were any module-build failures.
461*67e74705SXin Li if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
462*67e74705SXin Li CI.hasPreprocessor()) {
463*67e74705SXin Li StringRef Cache =
464*67e74705SXin Li CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
465*67e74705SXin Li if (!Cache.empty())
466*67e74705SXin Li GlobalModuleIndex::writeIndex(CI.getFileManager(),
467*67e74705SXin Li CI.getPCHContainerReader(), Cache);
468*67e74705SXin Li }
469*67e74705SXin Li
470*67e74705SXin Li return true;
471*67e74705SXin Li }
472*67e74705SXin Li
EndSourceFile()473*67e74705SXin Li void FrontendAction::EndSourceFile() {
474*67e74705SXin Li CompilerInstance &CI = getCompilerInstance();
475*67e74705SXin Li
476*67e74705SXin Li // Inform the diagnostic client we are done with this source file.
477*67e74705SXin Li CI.getDiagnosticClient().EndSourceFile();
478*67e74705SXin Li
479*67e74705SXin Li // Inform the preprocessor we are done.
480*67e74705SXin Li if (CI.hasPreprocessor())
481*67e74705SXin Li CI.getPreprocessor().EndSourceFile();
482*67e74705SXin Li
483*67e74705SXin Li // Finalize the action.
484*67e74705SXin Li EndSourceFileAction();
485*67e74705SXin Li
486*67e74705SXin Li // Sema references the ast consumer, so reset sema first.
487*67e74705SXin Li //
488*67e74705SXin Li // FIXME: There is more per-file stuff we could just drop here?
489*67e74705SXin Li bool DisableFree = CI.getFrontendOpts().DisableFree;
490*67e74705SXin Li if (DisableFree) {
491*67e74705SXin Li CI.resetAndLeakSema();
492*67e74705SXin Li CI.resetAndLeakASTContext();
493*67e74705SXin Li BuryPointer(CI.takeASTConsumer().get());
494*67e74705SXin Li } else {
495*67e74705SXin Li CI.setSema(nullptr);
496*67e74705SXin Li CI.setASTContext(nullptr);
497*67e74705SXin Li CI.setASTConsumer(nullptr);
498*67e74705SXin Li }
499*67e74705SXin Li
500*67e74705SXin Li if (CI.getFrontendOpts().ShowStats) {
501*67e74705SXin Li llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n";
502*67e74705SXin Li CI.getPreprocessor().PrintStats();
503*67e74705SXin Li CI.getPreprocessor().getIdentifierTable().PrintStats();
504*67e74705SXin Li CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
505*67e74705SXin Li CI.getSourceManager().PrintStats();
506*67e74705SXin Li llvm::errs() << "\n";
507*67e74705SXin Li }
508*67e74705SXin Li
509*67e74705SXin Li // Cleanup the output streams, and erase the output files if instructed by the
510*67e74705SXin Li // FrontendAction.
511*67e74705SXin Li CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
512*67e74705SXin Li
513*67e74705SXin Li if (isCurrentFileAST()) {
514*67e74705SXin Li if (DisableFree) {
515*67e74705SXin Li CI.resetAndLeakPreprocessor();
516*67e74705SXin Li CI.resetAndLeakSourceManager();
517*67e74705SXin Li CI.resetAndLeakFileManager();
518*67e74705SXin Li } else {
519*67e74705SXin Li CI.setPreprocessor(nullptr);
520*67e74705SXin Li CI.setSourceManager(nullptr);
521*67e74705SXin Li CI.setFileManager(nullptr);
522*67e74705SXin Li }
523*67e74705SXin Li }
524*67e74705SXin Li
525*67e74705SXin Li setCompilerInstance(nullptr);
526*67e74705SXin Li setCurrentInput(FrontendInputFile());
527*67e74705SXin Li }
528*67e74705SXin Li
shouldEraseOutputFiles()529*67e74705SXin Li bool FrontendAction::shouldEraseOutputFiles() {
530*67e74705SXin Li return getCompilerInstance().getDiagnostics().hasErrorOccurred();
531*67e74705SXin Li }
532*67e74705SXin Li
533*67e74705SXin Li //===----------------------------------------------------------------------===//
534*67e74705SXin Li // Utility Actions
535*67e74705SXin Li //===----------------------------------------------------------------------===//
536*67e74705SXin Li
ExecuteAction()537*67e74705SXin Li void ASTFrontendAction::ExecuteAction() {
538*67e74705SXin Li CompilerInstance &CI = getCompilerInstance();
539*67e74705SXin Li if (!CI.hasPreprocessor())
540*67e74705SXin Li return;
541*67e74705SXin Li
542*67e74705SXin Li // FIXME: Move the truncation aspect of this into Sema, we delayed this till
543*67e74705SXin Li // here so the source manager would be initialized.
544*67e74705SXin Li if (hasCodeCompletionSupport() &&
545*67e74705SXin Li !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
546*67e74705SXin Li CI.createCodeCompletionConsumer();
547*67e74705SXin Li
548*67e74705SXin Li // Use a code completion consumer?
549*67e74705SXin Li CodeCompleteConsumer *CompletionConsumer = nullptr;
550*67e74705SXin Li if (CI.hasCodeCompletionConsumer())
551*67e74705SXin Li CompletionConsumer = &CI.getCodeCompletionConsumer();
552*67e74705SXin Li
553*67e74705SXin Li if (!CI.hasSema())
554*67e74705SXin Li CI.createSema(getTranslationUnitKind(), CompletionConsumer);
555*67e74705SXin Li
556*67e74705SXin Li ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats,
557*67e74705SXin Li CI.getFrontendOpts().SkipFunctionBodies);
558*67e74705SXin Li }
559*67e74705SXin Li
anchor()560*67e74705SXin Li void PluginASTAction::anchor() { }
561*67e74705SXin Li
562*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)563*67e74705SXin Li PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
564*67e74705SXin Li StringRef InFile) {
565*67e74705SXin Li llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
566*67e74705SXin Li }
567*67e74705SXin Li
568*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)569*67e74705SXin Li WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
570*67e74705SXin Li StringRef InFile) {
571*67e74705SXin Li return WrappedAction->CreateASTConsumer(CI, InFile);
572*67e74705SXin Li }
BeginInvocation(CompilerInstance & CI)573*67e74705SXin Li bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) {
574*67e74705SXin Li return WrappedAction->BeginInvocation(CI);
575*67e74705SXin Li }
BeginSourceFileAction(CompilerInstance & CI,StringRef Filename)576*67e74705SXin Li bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI,
577*67e74705SXin Li StringRef Filename) {
578*67e74705SXin Li WrappedAction->setCurrentInput(getCurrentInput());
579*67e74705SXin Li WrappedAction->setCompilerInstance(&CI);
580*67e74705SXin Li auto Ret = WrappedAction->BeginSourceFileAction(CI, Filename);
581*67e74705SXin Li // BeginSourceFileAction may change CurrentInput, e.g. during module builds.
582*67e74705SXin Li setCurrentInput(WrappedAction->getCurrentInput());
583*67e74705SXin Li return Ret;
584*67e74705SXin Li }
ExecuteAction()585*67e74705SXin Li void WrapperFrontendAction::ExecuteAction() {
586*67e74705SXin Li WrappedAction->ExecuteAction();
587*67e74705SXin Li }
EndSourceFileAction()588*67e74705SXin Li void WrapperFrontendAction::EndSourceFileAction() {
589*67e74705SXin Li WrappedAction->EndSourceFileAction();
590*67e74705SXin Li }
591*67e74705SXin Li
usesPreprocessorOnly() const592*67e74705SXin Li bool WrapperFrontendAction::usesPreprocessorOnly() const {
593*67e74705SXin Li return WrappedAction->usesPreprocessorOnly();
594*67e74705SXin Li }
getTranslationUnitKind()595*67e74705SXin Li TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() {
596*67e74705SXin Li return WrappedAction->getTranslationUnitKind();
597*67e74705SXin Li }
hasPCHSupport() const598*67e74705SXin Li bool WrapperFrontendAction::hasPCHSupport() const {
599*67e74705SXin Li return WrappedAction->hasPCHSupport();
600*67e74705SXin Li }
hasASTFileSupport() const601*67e74705SXin Li bool WrapperFrontendAction::hasASTFileSupport() const {
602*67e74705SXin Li return WrappedAction->hasASTFileSupport();
603*67e74705SXin Li }
hasIRSupport() const604*67e74705SXin Li bool WrapperFrontendAction::hasIRSupport() const {
605*67e74705SXin Li return WrappedAction->hasIRSupport();
606*67e74705SXin Li }
hasCodeCompletionSupport() const607*67e74705SXin Li bool WrapperFrontendAction::hasCodeCompletionSupport() const {
608*67e74705SXin Li return WrappedAction->hasCodeCompletionSupport();
609*67e74705SXin Li }
610*67e74705SXin Li
WrapperFrontendAction(std::unique_ptr<FrontendAction> WrappedAction)611*67e74705SXin Li WrapperFrontendAction::WrapperFrontendAction(
612*67e74705SXin Li std::unique_ptr<FrontendAction> WrappedAction)
613*67e74705SXin Li : WrappedAction(std::move(WrappedAction)) {}
614*67e74705SXin Li
615