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