185dd0bd1SPeter Collingbourne //===--- ExecuteCompilerInvocation.cpp ------------------------------------===// 285dd0bd1SPeter Collingbourne // 385dd0bd1SPeter Collingbourne // The LLVM Compiler Infrastructure 485dd0bd1SPeter Collingbourne // 585dd0bd1SPeter Collingbourne // This file is distributed under the University of Illinois Open Source 685dd0bd1SPeter Collingbourne // License. See LICENSE.TXT for details. 785dd0bd1SPeter Collingbourne // 885dd0bd1SPeter Collingbourne //===----------------------------------------------------------------------===// 985dd0bd1SPeter Collingbourne // 1085dd0bd1SPeter Collingbourne // This file holds ExecuteCompilerInvocation(). It is split into its own file to 1185dd0bd1SPeter Collingbourne // minimize the impact of pulling in essentially everything else in Clang. 1285dd0bd1SPeter Collingbourne // 1385dd0bd1SPeter Collingbourne //===----------------------------------------------------------------------===// 1485dd0bd1SPeter Collingbourne 1585dd0bd1SPeter Collingbourne #include "clang/FrontendTool/Utils.h" 16b5703510SChandler Carruth #include "clang/ARCMigrate/ARCMTActions.h" 1785dd0bd1SPeter Collingbourne #include "clang/CodeGen/CodeGenAction.h" 18a3c85b86SJames Molloy #include "clang/Driver/Options.h" 1985dd0bd1SPeter Collingbourne #include "clang/Frontend/CompilerInstance.h" 203a02247dSChandler Carruth #include "clang/Frontend/CompilerInvocation.h" 2185dd0bd1SPeter Collingbourne #include "clang/Frontend/FrontendActions.h" 2285dd0bd1SPeter Collingbourne #include "clang/Frontend/FrontendDiagnostic.h" 2385dd0bd1SPeter Collingbourne #include "clang/Frontend/FrontendPluginRegistry.h" 24ce2c726eSKostya Serebryany #include "clang/Frontend/Utils.h" 25cdf81490STed Kremenek #include "clang/Rewrite/Frontend/FrontendActions.h" 263a02247dSChandler Carruth #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" 27898229abSReid Kleckner #include "llvm/Option/OptTable.h" 28898229abSReid Kleckner #include "llvm/Option/Option.h" 298aaf4995SMichael J. Spencer #include "llvm/Support/DynamicLibrary.h" 303a02247dSChandler Carruth #include "llvm/Support/ErrorHandling.h" 3185dd0bd1SPeter Collingbourne using namespace clang; 32898229abSReid Kleckner using namespace llvm::opt; 3385dd0bd1SPeter Collingbourne 3485dd0bd1SPeter Collingbourne static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { 3585dd0bd1SPeter Collingbourne using namespace clang::frontend; 36ba294d73SAlp Toker StringRef Action("unknown"); 37ba294d73SAlp Toker (void)Action; 3885dd0bd1SPeter Collingbourne 3985dd0bd1SPeter Collingbourne switch (CI.getFrontendOpts().ProgramAction) { 404de03594SAlexander Kornienko case ASTDeclList: return new ASTDeclListAction(); 4185dd0bd1SPeter Collingbourne case ASTDump: return new ASTDumpAction(); 4285dd0bd1SPeter Collingbourne case ASTPrint: return new ASTPrintAction(); 4385dd0bd1SPeter Collingbourne case ASTView: return new ASTViewAction(); 4485dd0bd1SPeter Collingbourne case DumpRawTokens: return new DumpRawTokensAction(); 4585dd0bd1SPeter Collingbourne case DumpTokens: return new DumpTokensAction(); 4685dd0bd1SPeter Collingbourne case EmitAssembly: return new EmitAssemblyAction(); 4785dd0bd1SPeter Collingbourne case EmitBC: return new EmitBCAction(); 48d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_REWRITER 4985dd0bd1SPeter Collingbourne case EmitHTML: return new HTMLPrintAction(); 50d93c8c00SRoman Divacky #else 51d93c8c00SRoman Divacky case EmitHTML: Action = "EmitHTML"; break; 52d93c8c00SRoman Divacky #endif 5385dd0bd1SPeter Collingbourne case EmitLLVM: return new EmitLLVMAction(); 5485dd0bd1SPeter Collingbourne case EmitLLVMOnly: return new EmitLLVMOnlyAction(); 5585dd0bd1SPeter Collingbourne case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); 5685dd0bd1SPeter Collingbourne case EmitObj: return new EmitObjAction(); 57d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_REWRITER 5885dd0bd1SPeter Collingbourne case FixIt: return new FixItAction(); 59d93c8c00SRoman Divacky #else 60d93c8c00SRoman Divacky case FixIt: Action = "FixIt"; break; 61d93c8c00SRoman Divacky #endif 6270db54f1SDouglas Gregor case GenerateModule: return new GenerateModuleAction; 6370db54f1SDouglas Gregor case GeneratePCH: return new GeneratePCHAction; 6485dd0bd1SPeter Collingbourne case GeneratePTH: return new GeneratePTHAction(); 6585dd0bd1SPeter Collingbourne case InitOnly: return new InitOnlyAction(); 6685dd0bd1SPeter Collingbourne case ParseSyntaxOnly: return new SyntaxOnlyAction(); 67bf7fc9c5SDouglas Gregor case ModuleFileInfo: return new DumpModuleInfoAction(); 68*2cb4a78fSBen Langmuir case VerifyPCH: return new VerifyPCHAction(); 6985dd0bd1SPeter Collingbourne 7085dd0bd1SPeter Collingbourne case PluginAction: { 7185dd0bd1SPeter Collingbourne for (FrontendPluginRegistry::iterator it = 7285dd0bd1SPeter Collingbourne FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); 7385dd0bd1SPeter Collingbourne it != ie; ++it) { 7485dd0bd1SPeter Collingbourne if (it->getName() == CI.getFrontendOpts().ActionName) { 75e2778999SDylan Noblesmith OwningPtr<PluginASTAction> P(it->instantiate()); 7685dd0bd1SPeter Collingbourne if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) 7785dd0bd1SPeter Collingbourne return 0; 7885dd0bd1SPeter Collingbourne return P.take(); 7985dd0bd1SPeter Collingbourne } 8085dd0bd1SPeter Collingbourne } 8185dd0bd1SPeter Collingbourne 8285dd0bd1SPeter Collingbourne CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) 8385dd0bd1SPeter Collingbourne << CI.getFrontendOpts().ActionName; 8485dd0bd1SPeter Collingbourne return 0; 8585dd0bd1SPeter Collingbourne } 8685dd0bd1SPeter Collingbourne 8785dd0bd1SPeter Collingbourne case PrintDeclContext: return new DeclContextPrintAction(); 8885dd0bd1SPeter Collingbourne case PrintPreamble: return new PrintPreambleAction(); 89e993e4cdSDavid Blaikie case PrintPreprocessedInput: { 90d93c8c00SRoman Divacky if (CI.getPreprocessorOutputOpts().RewriteIncludes) { 91d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_REWRITER 92e993e4cdSDavid Blaikie return new RewriteIncludesAction(); 93d93c8c00SRoman Divacky #else 94d93c8c00SRoman Divacky Action = "RewriteIncludesAction"; 95d93c8c00SRoman Divacky break; 96d93c8c00SRoman Divacky #endif 97d93c8c00SRoman Divacky } 98e993e4cdSDavid Blaikie return new PrintPreprocessedAction(); 99e993e4cdSDavid Blaikie } 100e993e4cdSDavid Blaikie 101d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_REWRITER 10285dd0bd1SPeter Collingbourne case RewriteMacros: return new RewriteMacrosAction(); 10385dd0bd1SPeter Collingbourne case RewriteObjC: return new RewriteObjCAction(); 10485dd0bd1SPeter Collingbourne case RewriteTest: return new RewriteTestAction(); 105d93c8c00SRoman Divacky #else 106d93c8c00SRoman Divacky case RewriteMacros: Action = "RewriteMacros"; break; 107d93c8c00SRoman Divacky case RewriteObjC: Action = "RewriteObjC"; break; 108d93c8c00SRoman Divacky case RewriteTest: Action = "RewriteTest"; break; 109d93c8c00SRoman Divacky #endif 110d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_ARCMT 111f7639e1bSTed Kremenek case MigrateSource: return new arcmt::MigrateSourceAction(); 112d93c8c00SRoman Divacky #else 113d93c8c00SRoman Divacky case MigrateSource: Action = "MigrateSource"; break; 114d93c8c00SRoman Divacky #endif 115d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_STATIC_ANALYZER 116d93c8c00SRoman Divacky case RunAnalysis: return new ento::AnalysisAction(); 117d93c8c00SRoman Divacky #else 118d93c8c00SRoman Divacky case RunAnalysis: Action = "RunAnalysis"; break; 119d93c8c00SRoman Divacky #endif 12085dd0bd1SPeter Collingbourne case RunPreprocessorOnly: return new PreprocessOnlyAction(); 12185dd0bd1SPeter Collingbourne } 122d93c8c00SRoman Divacky 123d93c8c00SRoman Divacky #if !defined(CLANG_ENABLE_ARCMT) || !defined(CLANG_ENABLE_STATIC_ANALYZER) \ 124d93c8c00SRoman Divacky || !defined(CLANG_ENABLE_REWRITER) 125d93c8c00SRoman Divacky CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action; 126d93c8c00SRoman Divacky return 0; 127d93c8c00SRoman Divacky #else 128f47fa304SDavid Blaikie llvm_unreachable("Invalid program action!"); 129d93c8c00SRoman Divacky #endif 13085dd0bd1SPeter Collingbourne } 13185dd0bd1SPeter Collingbourne 13285dd0bd1SPeter Collingbourne static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { 13385dd0bd1SPeter Collingbourne // Create the underlying action. 13485dd0bd1SPeter Collingbourne FrontendAction *Act = CreateFrontendBaseAction(CI); 13585dd0bd1SPeter Collingbourne if (!Act) 13685dd0bd1SPeter Collingbourne return 0; 13785dd0bd1SPeter Collingbourne 1383d97a9beSArgyrios Kyrtzidis const FrontendOptions &FEOpts = CI.getFrontendOpts(); 1393d97a9beSArgyrios Kyrtzidis 140d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_REWRITER 1413d97a9beSArgyrios Kyrtzidis if (FEOpts.FixAndRecompile) { 14224e9afffSArgyrios Kyrtzidis Act = new FixItRecompile(Act); 14324e9afffSArgyrios Kyrtzidis } 144d93c8c00SRoman Divacky #endif 14524e9afffSArgyrios Kyrtzidis 146d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_ARCMT 1477a2645f9SArgyrios Kyrtzidis if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource) { 148b5703510SChandler Carruth // Potentially wrap the base FE action in an ARC Migrate Tool action. 1493d97a9beSArgyrios Kyrtzidis switch (FEOpts.ARCMTAction) { 150b5703510SChandler Carruth case FrontendOptions::ARCMT_None: 151b5703510SChandler Carruth break; 152b5703510SChandler Carruth case FrontendOptions::ARCMT_Check: 153b5703510SChandler Carruth Act = new arcmt::CheckAction(Act); 154b5703510SChandler Carruth break; 155b5703510SChandler Carruth case FrontendOptions::ARCMT_Modify: 1567fbd97f6SArgyrios Kyrtzidis Act = new arcmt::ModifyAction(Act); 1577fbd97f6SArgyrios Kyrtzidis break; 1587fbd97f6SArgyrios Kyrtzidis case FrontendOptions::ARCMT_Migrate: 159d571363eSArgyrios Kyrtzidis Act = new arcmt::MigrateAction(Act, 160f7639e1bSTed Kremenek FEOpts.MTMigrateDir, 1613d97a9beSArgyrios Kyrtzidis FEOpts.ARCMTMigrateReportOut, 1623d97a9beSArgyrios Kyrtzidis FEOpts.ARCMTMigrateEmitARCErrors); 163b5703510SChandler Carruth break; 164b5703510SChandler Carruth } 165b5703510SChandler Carruth 166f7639e1bSTed Kremenek if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) { 167f7639e1bSTed Kremenek Act = new arcmt::ObjCMigrateAction(Act, FEOpts.MTMigrateDir, 168182486c9SFariborz Jahanian FEOpts.ObjCMTAction); 169f7639e1bSTed Kremenek } 1707a2645f9SArgyrios Kyrtzidis } 171d93c8c00SRoman Divacky #endif 172f7639e1bSTed Kremenek 17385dd0bd1SPeter Collingbourne // If there are any AST files to merge, create a frontend action 17485dd0bd1SPeter Collingbourne // adaptor to perform the merge. 1753d97a9beSArgyrios Kyrtzidis if (!FEOpts.ASTMergeFiles.empty()) 176bd6a7d4cSArgyrios Kyrtzidis Act = new ASTMergeAction(Act, FEOpts.ASTMergeFiles); 17785dd0bd1SPeter Collingbourne 17885dd0bd1SPeter Collingbourne return Act; 17985dd0bd1SPeter Collingbourne } 18085dd0bd1SPeter Collingbourne 18185dd0bd1SPeter Collingbourne bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) { 18285dd0bd1SPeter Collingbourne // Honor -help. 18385dd0bd1SPeter Collingbourne if (Clang->getFrontendOpts().ShowHelp) { 184898229abSReid Kleckner OwningPtr<OptTable> Opts(driver::createDriverOptTable()); 18585dd0bd1SPeter Collingbourne Opts->PrintHelp(llvm::outs(), "clang -cc1", 186e70ed869SRichard Smith "LLVM 'Clang' Compiler: http://clang.llvm.org", 187898229abSReid Kleckner /*Include=*/ driver::options::CC1Option, /*Exclude=*/ 0); 188958297daSRafael Espindola return true; 18985dd0bd1SPeter Collingbourne } 19085dd0bd1SPeter Collingbourne 19185dd0bd1SPeter Collingbourne // Honor -version. 19285dd0bd1SPeter Collingbourne // 19385dd0bd1SPeter Collingbourne // FIXME: Use a better -version message? 19485dd0bd1SPeter Collingbourne if (Clang->getFrontendOpts().ShowVersion) { 19585dd0bd1SPeter Collingbourne llvm::cl::PrintVersionMessage(); 196958297daSRafael Espindola return true; 19785dd0bd1SPeter Collingbourne } 19885dd0bd1SPeter Collingbourne 19985dd0bd1SPeter Collingbourne // Load any requested plugins. 20085dd0bd1SPeter Collingbourne for (unsigned i = 0, 20185dd0bd1SPeter Collingbourne e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { 20285dd0bd1SPeter Collingbourne const std::string &Path = Clang->getFrontendOpts().Plugins[i]; 20385dd0bd1SPeter Collingbourne std::string Error; 20485dd0bd1SPeter Collingbourne if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) 20585dd0bd1SPeter Collingbourne Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) 20685dd0bd1SPeter Collingbourne << Path << Error; 20785dd0bd1SPeter Collingbourne } 20885dd0bd1SPeter Collingbourne 20911ce9224STobias Grosser // Honor -mllvm. 21011ce9224STobias Grosser // 21111ce9224STobias Grosser // FIXME: Remove this, one day. 21211ce9224STobias Grosser // This should happen AFTER plugins have been loaded! 21311ce9224STobias Grosser if (!Clang->getFrontendOpts().LLVMArgs.empty()) { 21411ce9224STobias Grosser unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size(); 21511ce9224STobias Grosser const char **Args = new const char*[NumArgs + 2]; 21611ce9224STobias Grosser Args[0] = "clang (LLVM option parsing)"; 21711ce9224STobias Grosser for (unsigned i = 0; i != NumArgs; ++i) 21811ce9224STobias Grosser Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str(); 21911ce9224STobias Grosser Args[NumArgs + 1] = 0; 22009d20eefSDavid Blaikie llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args); 22111ce9224STobias Grosser } 22211ce9224STobias Grosser 223d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_STATIC_ANALYZER 22459cce71aSJordy Rose // Honor -analyzer-checker-help. 22559cce71aSJordy Rose // This should happen AFTER plugins have been loaded! 22640ea0eaaSTed Kremenek if (Clang->getAnalyzerOpts()->ShowCheckerHelp) { 22759cce71aSJordy Rose ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins); 228958297daSRafael Espindola return true; 22959cce71aSJordy Rose } 230d93c8c00SRoman Divacky #endif 23159cce71aSJordy Rose 23285dd0bd1SPeter Collingbourne // If there were errors in processing arguments, don't do anything else. 233aa73d020SSean Silva if (Clang->getDiagnostics().hasErrorOccurred()) 234aa73d020SSean Silva return false; 23585dd0bd1SPeter Collingbourne // Create and execute the frontend action. 236e2778999SDylan Noblesmith OwningPtr<FrontendAction> Act(CreateFrontendAction(*Clang)); 237aa73d020SSean Silva if (!Act) 238aa73d020SSean Silva return false; 239aa73d020SSean Silva bool Success = Clang->ExecuteAction(*Act); 2404f76f4aeSTed Kremenek if (Clang->getFrontendOpts().DisableFree) 241ce2c726eSKostya Serebryany BuryPointer(Act.take()); 24285dd0bd1SPeter Collingbourne return Success; 24385dd0bd1SPeter Collingbourne } 244