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