1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "clang/ARCMigrate/ARCMTActions.h" |
15 | #include "clang/CodeGen/CodeGenAction.h" |
16 | #include "clang/Config/config.h" |
17 | #include "clang/Driver/Options.h" |
18 | #include "clang/Frontend/CompilerInstance.h" |
19 | #include "clang/Frontend/CompilerInvocation.h" |
20 | #include "clang/Frontend/FrontendActions.h" |
21 | #include "clang/Frontend/FrontendDiagnostic.h" |
22 | #include "clang/Frontend/FrontendPluginRegistry.h" |
23 | #include "clang/Frontend/Utils.h" |
24 | #include "clang/FrontendTool/Utils.h" |
25 | #include "clang/Rewrite/Frontend/FrontendActions.h" |
26 | #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" |
27 | #include "llvm/Option/OptTable.h" |
28 | #include "llvm/Option/Option.h" |
29 | #include "llvm/Support/BuryPointer.h" |
30 | #include "llvm/Support/DynamicLibrary.h" |
31 | #include "llvm/Support/ErrorHandling.h" |
32 | using namespace clang; |
33 | using namespace llvm::opt; |
34 | |
35 | namespace clang { |
36 | |
37 | static std::unique_ptr<FrontendAction> |
38 | CreateFrontendBaseAction(CompilerInstance &CI) { |
39 | using namespace clang::frontend; |
40 | StringRef Action("unknown"); |
41 | (void)Action; |
42 | |
43 | switch (CI.getFrontendOpts().ProgramAction) { |
44 | case ASTDeclList: return llvm::make_unique<ASTDeclListAction>(); |
45 | case ASTDump: return llvm::make_unique<ASTDumpAction>(); |
46 | case ASTPrint: return llvm::make_unique<ASTPrintAction>(); |
47 | case ASTView: return llvm::make_unique<ASTViewAction>(); |
48 | case DumpCompilerOptions: |
49 | return llvm::make_unique<DumpCompilerOptionsAction>(); |
50 | case DumpRawTokens: return llvm::make_unique<DumpRawTokensAction>(); |
51 | case DumpTokens: return llvm::make_unique<DumpTokensAction>(); |
52 | case EmitAssembly: return llvm::make_unique<EmitAssemblyAction>(); |
53 | case EmitBC: return llvm::make_unique<EmitBCAction>(); |
54 | case EmitHTML: return llvm::make_unique<HTMLPrintAction>(); |
55 | case EmitLLVM: return llvm::make_unique<EmitLLVMAction>(); |
56 | case EmitLLVMOnly: return llvm::make_unique<EmitLLVMOnlyAction>(); |
57 | case EmitCodeGenOnly: return llvm::make_unique<EmitCodeGenOnlyAction>(); |
58 | case EmitObj: return llvm::make_unique<EmitObjAction>(); |
59 | case FixIt: return llvm::make_unique<FixItAction>(); |
60 | case GenerateModule: |
61 | return llvm::make_unique<GenerateModuleFromModuleMapAction>(); |
62 | case GenerateModuleInterface: |
63 | return llvm::make_unique<GenerateModuleInterfaceAction>(); |
64 | case GenerateHeaderModule: |
65 | return llvm::make_unique<GenerateHeaderModuleAction>(); |
66 | case GeneratePCH: return llvm::make_unique<GeneratePCHAction>(); |
67 | case InitOnly: return llvm::make_unique<InitOnlyAction>(); |
68 | case ParseSyntaxOnly: return llvm::make_unique<SyntaxOnlyAction>(); |
69 | case ModuleFileInfo: return llvm::make_unique<DumpModuleInfoAction>(); |
70 | case VerifyPCH: return llvm::make_unique<VerifyPCHAction>(); |
71 | case TemplightDump: return llvm::make_unique<TemplightDumpAction>(); |
72 | |
73 | case PluginAction: { |
74 | for (FrontendPluginRegistry::iterator it = |
75 | FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); |
76 | it != ie; ++it) { |
77 | if (it->getName() == CI.getFrontendOpts().ActionName) { |
78 | std::unique_ptr<PluginASTAction> P(it->instantiate()); |
79 | if ((P->getActionType() != PluginASTAction::ReplaceAction && |
80 | P->getActionType() != PluginASTAction::Cmdline) || |
81 | !P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) |
82 | return nullptr; |
83 | return std::move(P); |
84 | } |
85 | } |
86 | |
87 | CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) |
88 | << CI.getFrontendOpts().ActionName; |
89 | return nullptr; |
90 | } |
91 | |
92 | case PrintPreamble: return llvm::make_unique<PrintPreambleAction>(); |
93 | case PrintPreprocessedInput: { |
94 | if (CI.getPreprocessorOutputOpts().RewriteIncludes || |
95 | CI.getPreprocessorOutputOpts().RewriteImports) |
96 | return llvm::make_unique<RewriteIncludesAction>(); |
97 | return llvm::make_unique<PrintPreprocessedAction>(); |
98 | } |
99 | |
100 | case RewriteMacros: return llvm::make_unique<RewriteMacrosAction>(); |
101 | case RewriteTest: return llvm::make_unique<RewriteTestAction>(); |
102 | #if CLANG_ENABLE_OBJC_REWRITER |
103 | case RewriteObjC: return llvm::make_unique<RewriteObjCAction>(); |
104 | #else |
105 | case RewriteObjC: Action = "RewriteObjC"; break; |
106 | #endif |
107 | #if CLANG_ENABLE_ARCMT |
108 | case MigrateSource: |
109 | return llvm::make_unique<arcmt::MigrateSourceAction>(); |
110 | #else |
111 | case MigrateSource: Action = "MigrateSource"; break; |
112 | #endif |
113 | #if CLANG_ENABLE_STATIC_ANALYZER |
114 | case RunAnalysis: return llvm::make_unique<ento::AnalysisAction>(); |
115 | #else |
116 | case RunAnalysis: Action = "RunAnalysis"; break; |
117 | #endif |
118 | case RunPreprocessorOnly: return llvm::make_unique<PreprocessOnlyAction>(); |
119 | } |
120 | |
121 | #if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \ |
122 | || !CLANG_ENABLE_OBJC_REWRITER |
123 | CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action; |
124 | return 0; |
125 | #else |
126 | llvm_unreachable("Invalid program action!"); |
127 | #endif |
128 | } |
129 | |
130 | std::unique_ptr<FrontendAction> |
131 | CreateFrontendAction(CompilerInstance &CI) { |
132 | |
133 | std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI); |
134 | if (!Act) |
135 | return nullptr; |
136 | |
137 | const FrontendOptions &FEOpts = CI.getFrontendOpts(); |
138 | |
139 | if (FEOpts.FixAndRecompile) { |
140 | Act = llvm::make_unique<FixItRecompile>(std::move(Act)); |
141 | } |
142 | |
143 | #if CLANG_ENABLE_ARCMT |
144 | if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource && |
145 | CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) { |
146 | |
147 | switch (FEOpts.ARCMTAction) { |
148 | case FrontendOptions::ARCMT_None: |
149 | break; |
150 | case FrontendOptions::ARCMT_Check: |
151 | Act = llvm::make_unique<arcmt::CheckAction>(std::move(Act)); |
152 | break; |
153 | case FrontendOptions::ARCMT_Modify: |
154 | Act = llvm::make_unique<arcmt::ModifyAction>(std::move(Act)); |
155 | break; |
156 | case FrontendOptions::ARCMT_Migrate: |
157 | Act = llvm::make_unique<arcmt::MigrateAction>(std::move(Act), |
158 | FEOpts.MTMigrateDir, |
159 | FEOpts.ARCMTMigrateReportOut, |
160 | FEOpts.ARCMTMigrateEmitARCErrors); |
161 | break; |
162 | } |
163 | |
164 | if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) { |
165 | Act = llvm::make_unique<arcmt::ObjCMigrateAction>(std::move(Act), |
166 | FEOpts.MTMigrateDir, |
167 | FEOpts.ObjCMTAction); |
168 | } |
169 | } |
170 | #endif |
171 | |
172 | |
173 | |
174 | if (!FEOpts.ASTMergeFiles.empty()) |
175 | Act = llvm::make_unique<ASTMergeAction>(std::move(Act), |
176 | FEOpts.ASTMergeFiles); |
177 | |
178 | return Act; |
179 | } |
180 | |
181 | bool ExecuteCompilerInvocation(CompilerInstance *Clang) { |
182 | |
183 | if (Clang->getFrontendOpts().ShowHelp) { |
184 | std::unique_ptr<OptTable> Opts = driver::createDriverOptTable(); |
185 | Opts->PrintHelp(llvm::outs(), "clang -cc1 [options] file...", |
186 | "LLVM 'Clang' Compiler: http://clang.llvm.org", |
187 | driver::options::CC1Option, |
188 | , ); |
189 | return true; |
190 | } |
191 | |
192 | |
193 | |
194 | |
195 | if (Clang->getFrontendOpts().ShowVersion) { |
196 | llvm::cl::PrintVersionMessage(); |
197 | return true; |
198 | } |
199 | |
200 | |
201 | for (unsigned i = 0, |
202 | e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { |
203 | const std::string &Path = Clang->getFrontendOpts().Plugins[i]; |
204 | std::string Error; |
205 | if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) |
206 | Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) |
207 | << Path << Error; |
208 | } |
209 | |
210 | |
211 | for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), |
212 | ie = FrontendPluginRegistry::end(); |
213 | it != ie; ++it) { |
214 | std::unique_ptr<PluginASTAction> P(it->instantiate()); |
215 | if (P->getActionType() == PluginASTAction::ReplaceAction) { |
216 | Clang->getFrontendOpts().ProgramAction = clang::frontend::PluginAction; |
217 | Clang->getFrontendOpts().ActionName = it->getName(); |
218 | break; |
219 | } |
220 | } |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | if (!Clang->getFrontendOpts().LLVMArgs.empty()) { |
227 | unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size(); |
228 | auto Args = llvm::make_unique<const char*[]>(NumArgs + 2); |
229 | Args[0] = "clang (LLVM option parsing)"; |
230 | for (unsigned i = 0; i != NumArgs; ++i) |
231 | Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str(); |
232 | Args[NumArgs + 1] = nullptr; |
233 | llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); |
234 | } |
235 | |
236 | #if CLANG_ENABLE_STATIC_ANALYZER |
237 | |
238 | |
239 | if (Clang->getAnalyzerOpts()->ShowCheckerHelp) { |
240 | ento::printCheckerHelp(llvm::outs(), |
241 | Clang->getFrontendOpts().Plugins, |
242 | *Clang->getAnalyzerOpts(), |
243 | Clang->getDiagnostics(), |
244 | Clang->getLangOpts()); |
245 | return true; |
246 | } |
247 | |
248 | |
249 | if (Clang->getAnalyzerOpts()->ShowEnabledCheckerList) { |
250 | ento::printEnabledCheckerList(llvm::outs(), |
251 | Clang->getFrontendOpts().Plugins, |
252 | *Clang->getAnalyzerOpts(), |
253 | Clang->getDiagnostics(), |
254 | Clang->getLangOpts()); |
255 | } |
256 | |
257 | |
258 | if (Clang->getAnalyzerOpts()->ShowConfigOptionsList) { |
259 | ento::printAnalyzerConfigList(llvm::outs()); |
260 | return true; |
261 | } |
262 | #endif |
263 | |
264 | |
265 | if (Clang->getDiagnostics().hasErrorOccurred()) |
266 | return false; |
267 | |
268 | std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang)); |
269 | if (!Act) |
270 | return false; |
271 | bool Success = Clang->ExecuteAction(*Act); |
272 | if (Clang->getFrontendOpts().DisableFree) |
273 | llvm::BuryPointer(std::move(Act)); |
274 | return Success; |
275 | } |
276 | |
277 | } |
278 | |