1f4a2713aSLionel Sambuc //===--- ExecuteCompilerInvocation.cpp ------------------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file holds ExecuteCompilerInvocation(). It is split into its own file to
11f4a2713aSLionel Sambuc // minimize the impact of pulling in essentially everything else in Clang.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc
15f4a2713aSLionel Sambuc #include "clang/FrontendTool/Utils.h"
16f4a2713aSLionel Sambuc #include "clang/ARCMigrate/ARCMTActions.h"
17f4a2713aSLionel Sambuc #include "clang/CodeGen/CodeGenAction.h"
18f4a2713aSLionel Sambuc #include "clang/Driver/Options.h"
19f4a2713aSLionel Sambuc #include "clang/Frontend/CompilerInstance.h"
20f4a2713aSLionel Sambuc #include "clang/Frontend/CompilerInvocation.h"
21f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendActions.h"
22f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendDiagnostic.h"
23f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendPluginRegistry.h"
24*0a6a1f1dSLionel Sambuc #include "clang/Frontend/Utils.h"
25f4a2713aSLionel Sambuc #include "clang/Rewrite/Frontend/FrontendActions.h"
26f4a2713aSLionel Sambuc #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
27f4a2713aSLionel Sambuc #include "llvm/Option/OptTable.h"
28f4a2713aSLionel Sambuc #include "llvm/Option/Option.h"
29f4a2713aSLionel Sambuc #include "llvm/Support/DynamicLibrary.h"
30f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
31f4a2713aSLionel Sambuc using namespace clang;
32f4a2713aSLionel Sambuc using namespace llvm::opt;
33f4a2713aSLionel Sambuc
CreateFrontendBaseAction(CompilerInstance & CI)34f4a2713aSLionel Sambuc static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
35f4a2713aSLionel Sambuc using namespace clang::frontend;
36f4a2713aSLionel Sambuc StringRef Action("unknown");
37*0a6a1f1dSLionel Sambuc (void)Action;
38f4a2713aSLionel Sambuc
39f4a2713aSLionel Sambuc switch (CI.getFrontendOpts().ProgramAction) {
40f4a2713aSLionel Sambuc case ASTDeclList: return new ASTDeclListAction();
41f4a2713aSLionel Sambuc case ASTDump: return new ASTDumpAction();
42f4a2713aSLionel Sambuc case ASTPrint: return new ASTPrintAction();
43f4a2713aSLionel Sambuc case ASTView: return new ASTViewAction();
44f4a2713aSLionel Sambuc case DumpRawTokens: return new DumpRawTokensAction();
45f4a2713aSLionel Sambuc case DumpTokens: return new DumpTokensAction();
46f4a2713aSLionel Sambuc case EmitAssembly: return new EmitAssemblyAction();
47f4a2713aSLionel Sambuc case EmitBC: return new EmitBCAction();
48f4a2713aSLionel Sambuc case EmitHTML: return new HTMLPrintAction();
49f4a2713aSLionel Sambuc case EmitLLVM: return new EmitLLVMAction();
50f4a2713aSLionel Sambuc case EmitLLVMOnly: return new EmitLLVMOnlyAction();
51f4a2713aSLionel Sambuc case EmitCodeGenOnly: return new EmitCodeGenOnlyAction();
52f4a2713aSLionel Sambuc case EmitObj: return new EmitObjAction();
53f4a2713aSLionel Sambuc case FixIt: return new FixItAction();
54f4a2713aSLionel Sambuc case GenerateModule: return new GenerateModuleAction;
55f4a2713aSLionel Sambuc case GeneratePCH: return new GeneratePCHAction;
56f4a2713aSLionel Sambuc case GeneratePTH: return new GeneratePTHAction();
57f4a2713aSLionel Sambuc case InitOnly: return new InitOnlyAction();
58f4a2713aSLionel Sambuc case ParseSyntaxOnly: return new SyntaxOnlyAction();
59f4a2713aSLionel Sambuc case ModuleFileInfo: return new DumpModuleInfoAction();
60*0a6a1f1dSLionel Sambuc case VerifyPCH: return new VerifyPCHAction();
61f4a2713aSLionel Sambuc
62f4a2713aSLionel Sambuc case PluginAction: {
63f4a2713aSLionel Sambuc for (FrontendPluginRegistry::iterator it =
64f4a2713aSLionel Sambuc FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
65f4a2713aSLionel Sambuc it != ie; ++it) {
66f4a2713aSLionel Sambuc if (it->getName() == CI.getFrontendOpts().ActionName) {
67*0a6a1f1dSLionel Sambuc std::unique_ptr<PluginASTAction> P(it->instantiate());
68f4a2713aSLionel Sambuc if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs))
69*0a6a1f1dSLionel Sambuc return nullptr;
70*0a6a1f1dSLionel Sambuc return P.release();
71f4a2713aSLionel Sambuc }
72f4a2713aSLionel Sambuc }
73f4a2713aSLionel Sambuc
74f4a2713aSLionel Sambuc CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
75f4a2713aSLionel Sambuc << CI.getFrontendOpts().ActionName;
76*0a6a1f1dSLionel Sambuc return nullptr;
77f4a2713aSLionel Sambuc }
78f4a2713aSLionel Sambuc
79f4a2713aSLionel Sambuc case PrintDeclContext: return new DeclContextPrintAction();
80f4a2713aSLionel Sambuc case PrintPreamble: return new PrintPreambleAction();
81f4a2713aSLionel Sambuc case PrintPreprocessedInput: {
82*0a6a1f1dSLionel Sambuc if (CI.getPreprocessorOutputOpts().RewriteIncludes)
83f4a2713aSLionel Sambuc return new RewriteIncludesAction();
84f4a2713aSLionel Sambuc return new PrintPreprocessedAction();
85f4a2713aSLionel Sambuc }
86f4a2713aSLionel Sambuc
87f4a2713aSLionel Sambuc case RewriteMacros: return new RewriteMacrosAction();
88f4a2713aSLionel Sambuc case RewriteTest: return new RewriteTestAction();
89*0a6a1f1dSLionel Sambuc #ifdef CLANG_ENABLE_OBJC_REWRITER
90*0a6a1f1dSLionel Sambuc case RewriteObjC: return new RewriteObjCAction();
91f4a2713aSLionel Sambuc #else
92f4a2713aSLionel Sambuc case RewriteObjC: Action = "RewriteObjC"; break;
93f4a2713aSLionel Sambuc #endif
94f4a2713aSLionel Sambuc #ifdef CLANG_ENABLE_ARCMT
95f4a2713aSLionel Sambuc case MigrateSource: return new arcmt::MigrateSourceAction();
96f4a2713aSLionel Sambuc #else
97f4a2713aSLionel Sambuc case MigrateSource: Action = "MigrateSource"; break;
98f4a2713aSLionel Sambuc #endif
99f4a2713aSLionel Sambuc #ifdef CLANG_ENABLE_STATIC_ANALYZER
100f4a2713aSLionel Sambuc case RunAnalysis: return new ento::AnalysisAction();
101f4a2713aSLionel Sambuc #else
102f4a2713aSLionel Sambuc case RunAnalysis: Action = "RunAnalysis"; break;
103f4a2713aSLionel Sambuc #endif
104f4a2713aSLionel Sambuc case RunPreprocessorOnly: return new PreprocessOnlyAction();
105f4a2713aSLionel Sambuc }
106f4a2713aSLionel Sambuc
107f4a2713aSLionel Sambuc #if !defined(CLANG_ENABLE_ARCMT) || !defined(CLANG_ENABLE_STATIC_ANALYZER) \
108*0a6a1f1dSLionel Sambuc || !defined(CLANG_ENABLE_OBJC_REWRITER)
109f4a2713aSLionel Sambuc CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;
110f4a2713aSLionel Sambuc return 0;
111f4a2713aSLionel Sambuc #else
112f4a2713aSLionel Sambuc llvm_unreachable("Invalid program action!");
113f4a2713aSLionel Sambuc #endif
114f4a2713aSLionel Sambuc }
115f4a2713aSLionel Sambuc
CreateFrontendAction(CompilerInstance & CI)116f4a2713aSLionel Sambuc static FrontendAction *CreateFrontendAction(CompilerInstance &CI) {
117f4a2713aSLionel Sambuc // Create the underlying action.
118f4a2713aSLionel Sambuc FrontendAction *Act = CreateFrontendBaseAction(CI);
119f4a2713aSLionel Sambuc if (!Act)
120*0a6a1f1dSLionel Sambuc return nullptr;
121f4a2713aSLionel Sambuc
122f4a2713aSLionel Sambuc const FrontendOptions &FEOpts = CI.getFrontendOpts();
123f4a2713aSLionel Sambuc
124f4a2713aSLionel Sambuc if (FEOpts.FixAndRecompile) {
125f4a2713aSLionel Sambuc Act = new FixItRecompile(Act);
126f4a2713aSLionel Sambuc }
127f4a2713aSLionel Sambuc
128f4a2713aSLionel Sambuc #ifdef CLANG_ENABLE_ARCMT
129*0a6a1f1dSLionel Sambuc if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource &&
130*0a6a1f1dSLionel Sambuc CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) {
131f4a2713aSLionel Sambuc // Potentially wrap the base FE action in an ARC Migrate Tool action.
132f4a2713aSLionel Sambuc switch (FEOpts.ARCMTAction) {
133f4a2713aSLionel Sambuc case FrontendOptions::ARCMT_None:
134f4a2713aSLionel Sambuc break;
135f4a2713aSLionel Sambuc case FrontendOptions::ARCMT_Check:
136f4a2713aSLionel Sambuc Act = new arcmt::CheckAction(Act);
137f4a2713aSLionel Sambuc break;
138f4a2713aSLionel Sambuc case FrontendOptions::ARCMT_Modify:
139f4a2713aSLionel Sambuc Act = new arcmt::ModifyAction(Act);
140f4a2713aSLionel Sambuc break;
141f4a2713aSLionel Sambuc case FrontendOptions::ARCMT_Migrate:
142f4a2713aSLionel Sambuc Act = new arcmt::MigrateAction(Act,
143f4a2713aSLionel Sambuc FEOpts.MTMigrateDir,
144f4a2713aSLionel Sambuc FEOpts.ARCMTMigrateReportOut,
145f4a2713aSLionel Sambuc FEOpts.ARCMTMigrateEmitARCErrors);
146f4a2713aSLionel Sambuc break;
147f4a2713aSLionel Sambuc }
148f4a2713aSLionel Sambuc
149f4a2713aSLionel Sambuc if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
150f4a2713aSLionel Sambuc Act = new arcmt::ObjCMigrateAction(Act, FEOpts.MTMigrateDir,
151f4a2713aSLionel Sambuc FEOpts.ObjCMTAction);
152f4a2713aSLionel Sambuc }
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc #endif
155f4a2713aSLionel Sambuc
156f4a2713aSLionel Sambuc // If there are any AST files to merge, create a frontend action
157f4a2713aSLionel Sambuc // adaptor to perform the merge.
158f4a2713aSLionel Sambuc if (!FEOpts.ASTMergeFiles.empty())
159f4a2713aSLionel Sambuc Act = new ASTMergeAction(Act, FEOpts.ASTMergeFiles);
160f4a2713aSLionel Sambuc
161f4a2713aSLionel Sambuc return Act;
162f4a2713aSLionel Sambuc }
163f4a2713aSLionel Sambuc
ExecuteCompilerInvocation(CompilerInstance * Clang)164f4a2713aSLionel Sambuc bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
165f4a2713aSLionel Sambuc // Honor -help.
166f4a2713aSLionel Sambuc if (Clang->getFrontendOpts().ShowHelp) {
167*0a6a1f1dSLionel Sambuc std::unique_ptr<OptTable> Opts(driver::createDriverOptTable());
168f4a2713aSLionel Sambuc Opts->PrintHelp(llvm::outs(), "clang -cc1",
169f4a2713aSLionel Sambuc "LLVM 'Clang' Compiler: http://clang.llvm.org",
170f4a2713aSLionel Sambuc /*Include=*/ driver::options::CC1Option, /*Exclude=*/ 0);
171f4a2713aSLionel Sambuc return true;
172f4a2713aSLionel Sambuc }
173f4a2713aSLionel Sambuc
174f4a2713aSLionel Sambuc // Honor -version.
175f4a2713aSLionel Sambuc //
176f4a2713aSLionel Sambuc // FIXME: Use a better -version message?
177f4a2713aSLionel Sambuc if (Clang->getFrontendOpts().ShowVersion) {
178f4a2713aSLionel Sambuc llvm::cl::PrintVersionMessage();
179f4a2713aSLionel Sambuc return true;
180f4a2713aSLionel Sambuc }
181f4a2713aSLionel Sambuc
182f4a2713aSLionel Sambuc // Load any requested plugins.
183f4a2713aSLionel Sambuc for (unsigned i = 0,
184f4a2713aSLionel Sambuc e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) {
185f4a2713aSLionel Sambuc const std::string &Path = Clang->getFrontendOpts().Plugins[i];
186f4a2713aSLionel Sambuc std::string Error;
187f4a2713aSLionel Sambuc if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
188f4a2713aSLionel Sambuc Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
189f4a2713aSLionel Sambuc << Path << Error;
190f4a2713aSLionel Sambuc }
191f4a2713aSLionel Sambuc
192f4a2713aSLionel Sambuc // Honor -mllvm.
193f4a2713aSLionel Sambuc //
194f4a2713aSLionel Sambuc // FIXME: Remove this, one day.
195f4a2713aSLionel Sambuc // This should happen AFTER plugins have been loaded!
196f4a2713aSLionel Sambuc if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
197f4a2713aSLionel Sambuc unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
198*0a6a1f1dSLionel Sambuc auto Args = llvm::make_unique<const char*[]>(NumArgs + 2);
199f4a2713aSLionel Sambuc Args[0] = "clang (LLVM option parsing)";
200f4a2713aSLionel Sambuc for (unsigned i = 0; i != NumArgs; ++i)
201f4a2713aSLionel Sambuc Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
202*0a6a1f1dSLionel Sambuc Args[NumArgs + 1] = nullptr;
203*0a6a1f1dSLionel Sambuc llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
204f4a2713aSLionel Sambuc }
205f4a2713aSLionel Sambuc
206f4a2713aSLionel Sambuc #ifdef CLANG_ENABLE_STATIC_ANALYZER
207f4a2713aSLionel Sambuc // Honor -analyzer-checker-help.
208f4a2713aSLionel Sambuc // This should happen AFTER plugins have been loaded!
209f4a2713aSLionel Sambuc if (Clang->getAnalyzerOpts()->ShowCheckerHelp) {
210f4a2713aSLionel Sambuc ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins);
211f4a2713aSLionel Sambuc return true;
212f4a2713aSLionel Sambuc }
213f4a2713aSLionel Sambuc #endif
214f4a2713aSLionel Sambuc
215f4a2713aSLionel Sambuc // If there were errors in processing arguments, don't do anything else.
216f4a2713aSLionel Sambuc if (Clang->getDiagnostics().hasErrorOccurred())
217f4a2713aSLionel Sambuc return false;
218f4a2713aSLionel Sambuc // Create and execute the frontend action.
219*0a6a1f1dSLionel Sambuc std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
220f4a2713aSLionel Sambuc if (!Act)
221f4a2713aSLionel Sambuc return false;
222f4a2713aSLionel Sambuc bool Success = Clang->ExecuteAction(*Act);
223f4a2713aSLionel Sambuc if (Clang->getFrontendOpts().DisableFree)
224*0a6a1f1dSLionel Sambuc BuryPointer(std::move(Act));
225f4a2713aSLionel Sambuc return Success;
226f4a2713aSLionel Sambuc }
227