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(); 4885dd0bd1SPeter Collingbourne case EmitHTML: return new HTMLPrintAction(); 4985dd0bd1SPeter Collingbourne case EmitLLVM: return new EmitLLVMAction(); 5085dd0bd1SPeter Collingbourne case EmitLLVMOnly: return new EmitLLVMOnlyAction(); 5185dd0bd1SPeter Collingbourne case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); 5285dd0bd1SPeter Collingbourne case EmitObj: return new EmitObjAction(); 5385dd0bd1SPeter Collingbourne case FixIt: return new FixItAction(); 5470db54f1SDouglas Gregor case GenerateModule: return new GenerateModuleAction; 5570db54f1SDouglas Gregor case GeneratePCH: return new GeneratePCHAction; 5685dd0bd1SPeter Collingbourne case GeneratePTH: return new GeneratePTHAction(); 5785dd0bd1SPeter Collingbourne case InitOnly: return new InitOnlyAction(); 5885dd0bd1SPeter Collingbourne case ParseSyntaxOnly: return new SyntaxOnlyAction(); 59bf7fc9c5SDouglas Gregor case ModuleFileInfo: return new DumpModuleInfoAction(); 602cb4a78fSBen Langmuir case VerifyPCH: return new VerifyPCHAction(); 6185dd0bd1SPeter Collingbourne 6285dd0bd1SPeter Collingbourne case PluginAction: { 6385dd0bd1SPeter Collingbourne for (FrontendPluginRegistry::iterator it = 6485dd0bd1SPeter Collingbourne FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); 6585dd0bd1SPeter Collingbourne it != ie; ++it) { 6685dd0bd1SPeter Collingbourne if (it->getName() == CI.getFrontendOpts().ActionName) { 67b8984329SAhmed Charles std::unique_ptr<PluginASTAction> P(it->instantiate()); 6885dd0bd1SPeter Collingbourne if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) 69236bde3dSCraig Topper return nullptr; 709a16beb8SAhmed Charles return P.release(); 7185dd0bd1SPeter Collingbourne } 7285dd0bd1SPeter Collingbourne } 7385dd0bd1SPeter Collingbourne 7485dd0bd1SPeter Collingbourne CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) 7585dd0bd1SPeter Collingbourne << CI.getFrontendOpts().ActionName; 76236bde3dSCraig Topper return nullptr; 7785dd0bd1SPeter Collingbourne } 7885dd0bd1SPeter Collingbourne 7985dd0bd1SPeter Collingbourne case PrintDeclContext: return new DeclContextPrintAction(); 8085dd0bd1SPeter Collingbourne case PrintPreamble: return new PrintPreambleAction(); 81e993e4cdSDavid Blaikie case PrintPreprocessedInput: { 82*0621cb2eSAlp Toker if (CI.getPreprocessorOutputOpts().RewriteIncludes) 83e993e4cdSDavid Blaikie return new RewriteIncludesAction(); 84e993e4cdSDavid Blaikie return new PrintPreprocessedAction(); 85e993e4cdSDavid Blaikie } 86e993e4cdSDavid Blaikie 8785dd0bd1SPeter Collingbourne case RewriteMacros: return new RewriteMacrosAction(); 8885dd0bd1SPeter Collingbourne case RewriteTest: return new RewriteTestAction(); 89*0621cb2eSAlp Toker #ifdef CLANG_ENABLE_OBJC_REWRITER 90*0621cb2eSAlp Toker case RewriteObjC: return new RewriteObjCAction(); 91d93c8c00SRoman Divacky #else 92d93c8c00SRoman Divacky case RewriteObjC: Action = "RewriteObjC"; break; 93d93c8c00SRoman Divacky #endif 94d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_ARCMT 95f7639e1bSTed Kremenek case MigrateSource: return new arcmt::MigrateSourceAction(); 96d93c8c00SRoman Divacky #else 97d93c8c00SRoman Divacky case MigrateSource: Action = "MigrateSource"; break; 98d93c8c00SRoman Divacky #endif 99d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_STATIC_ANALYZER 100d93c8c00SRoman Divacky case RunAnalysis: return new ento::AnalysisAction(); 101d93c8c00SRoman Divacky #else 102d93c8c00SRoman Divacky case RunAnalysis: Action = "RunAnalysis"; break; 103d93c8c00SRoman Divacky #endif 10485dd0bd1SPeter Collingbourne case RunPreprocessorOnly: return new PreprocessOnlyAction(); 10585dd0bd1SPeter Collingbourne } 106d93c8c00SRoman Divacky 107d93c8c00SRoman Divacky #if !defined(CLANG_ENABLE_ARCMT) || !defined(CLANG_ENABLE_STATIC_ANALYZER) \ 108*0621cb2eSAlp Toker || !defined(CLANG_ENABLE_OBJC_REWRITER) 109d93c8c00SRoman Divacky CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action; 110d93c8c00SRoman Divacky return 0; 111d93c8c00SRoman Divacky #else 112f47fa304SDavid Blaikie llvm_unreachable("Invalid program action!"); 113d93c8c00SRoman Divacky #endif 11485dd0bd1SPeter Collingbourne } 11585dd0bd1SPeter Collingbourne 11685dd0bd1SPeter Collingbourne static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { 11785dd0bd1SPeter Collingbourne // Create the underlying action. 11885dd0bd1SPeter Collingbourne FrontendAction *Act = CreateFrontendBaseAction(CI); 11985dd0bd1SPeter Collingbourne if (!Act) 120236bde3dSCraig Topper return nullptr; 12185dd0bd1SPeter Collingbourne 1223d97a9beSArgyrios Kyrtzidis const FrontendOptions &FEOpts = CI.getFrontendOpts(); 1233d97a9beSArgyrios Kyrtzidis 1243d97a9beSArgyrios Kyrtzidis if (FEOpts.FixAndRecompile) { 12524e9afffSArgyrios Kyrtzidis Act = new FixItRecompile(Act); 12624e9afffSArgyrios Kyrtzidis } 12724e9afffSArgyrios Kyrtzidis 128d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_ARCMT 129d4d55340SArgyrios Kyrtzidis if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource && 130d4d55340SArgyrios Kyrtzidis CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) { 131b5703510SChandler Carruth // Potentially wrap the base FE action in an ARC Migrate Tool action. 1323d97a9beSArgyrios Kyrtzidis switch (FEOpts.ARCMTAction) { 133b5703510SChandler Carruth case FrontendOptions::ARCMT_None: 134b5703510SChandler Carruth break; 135b5703510SChandler Carruth case FrontendOptions::ARCMT_Check: 136b5703510SChandler Carruth Act = new arcmt::CheckAction(Act); 137b5703510SChandler Carruth break; 138b5703510SChandler Carruth case FrontendOptions::ARCMT_Modify: 1397fbd97f6SArgyrios Kyrtzidis Act = new arcmt::ModifyAction(Act); 1407fbd97f6SArgyrios Kyrtzidis break; 1417fbd97f6SArgyrios Kyrtzidis case FrontendOptions::ARCMT_Migrate: 142d571363eSArgyrios Kyrtzidis Act = new arcmt::MigrateAction(Act, 143f7639e1bSTed Kremenek FEOpts.MTMigrateDir, 1443d97a9beSArgyrios Kyrtzidis FEOpts.ARCMTMigrateReportOut, 1453d97a9beSArgyrios Kyrtzidis FEOpts.ARCMTMigrateEmitARCErrors); 146b5703510SChandler Carruth break; 147b5703510SChandler Carruth } 148b5703510SChandler Carruth 149f7639e1bSTed Kremenek if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) { 150f7639e1bSTed Kremenek Act = new arcmt::ObjCMigrateAction(Act, FEOpts.MTMigrateDir, 151182486c9SFariborz Jahanian FEOpts.ObjCMTAction); 152f7639e1bSTed Kremenek } 1537a2645f9SArgyrios Kyrtzidis } 154d93c8c00SRoman Divacky #endif 155f7639e1bSTed Kremenek 15685dd0bd1SPeter Collingbourne // If there are any AST files to merge, create a frontend action 15785dd0bd1SPeter Collingbourne // adaptor to perform the merge. 1583d97a9beSArgyrios Kyrtzidis if (!FEOpts.ASTMergeFiles.empty()) 159bd6a7d4cSArgyrios Kyrtzidis Act = new ASTMergeAction(Act, FEOpts.ASTMergeFiles); 16085dd0bd1SPeter Collingbourne 16185dd0bd1SPeter Collingbourne return Act; 16285dd0bd1SPeter Collingbourne } 16385dd0bd1SPeter Collingbourne 16485dd0bd1SPeter Collingbourne bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) { 16585dd0bd1SPeter Collingbourne // Honor -help. 16685dd0bd1SPeter Collingbourne if (Clang->getFrontendOpts().ShowHelp) { 167b8984329SAhmed Charles std::unique_ptr<OptTable> Opts(driver::createDriverOptTable()); 16885dd0bd1SPeter Collingbourne Opts->PrintHelp(llvm::outs(), "clang -cc1", 169e70ed869SRichard Smith "LLVM 'Clang' Compiler: http://clang.llvm.org", 170898229abSReid Kleckner /*Include=*/ driver::options::CC1Option, /*Exclude=*/ 0); 171958297daSRafael Espindola return true; 17285dd0bd1SPeter Collingbourne } 17385dd0bd1SPeter Collingbourne 17485dd0bd1SPeter Collingbourne // Honor -version. 17585dd0bd1SPeter Collingbourne // 17685dd0bd1SPeter Collingbourne // FIXME: Use a better -version message? 17785dd0bd1SPeter Collingbourne if (Clang->getFrontendOpts().ShowVersion) { 17885dd0bd1SPeter Collingbourne llvm::cl::PrintVersionMessage(); 179958297daSRafael Espindola return true; 18085dd0bd1SPeter Collingbourne } 18185dd0bd1SPeter Collingbourne 18285dd0bd1SPeter Collingbourne // Load any requested plugins. 18385dd0bd1SPeter Collingbourne for (unsigned i = 0, 18485dd0bd1SPeter Collingbourne e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { 18585dd0bd1SPeter Collingbourne const std::string &Path = Clang->getFrontendOpts().Plugins[i]; 18685dd0bd1SPeter Collingbourne std::string Error; 18785dd0bd1SPeter Collingbourne if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) 18885dd0bd1SPeter Collingbourne Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) 18985dd0bd1SPeter Collingbourne << Path << Error; 19085dd0bd1SPeter Collingbourne } 19185dd0bd1SPeter Collingbourne 19211ce9224STobias Grosser // Honor -mllvm. 19311ce9224STobias Grosser // 19411ce9224STobias Grosser // FIXME: Remove this, one day. 19511ce9224STobias Grosser // This should happen AFTER plugins have been loaded! 19611ce9224STobias Grosser if (!Clang->getFrontendOpts().LLVMArgs.empty()) { 19711ce9224STobias Grosser unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size(); 19881f9e02eSChandler Carruth auto Args = llvm::make_unique<const char*[]>(NumArgs + 2); 19911ce9224STobias Grosser Args[0] = "clang (LLVM option parsing)"; 20011ce9224STobias Grosser for (unsigned i = 0; i != NumArgs; ++i) 20111ce9224STobias Grosser Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str(); 202236bde3dSCraig Topper Args[NumArgs + 1] = nullptr; 20381f9e02eSChandler Carruth llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); 20411ce9224STobias Grosser } 20511ce9224STobias Grosser 206d93c8c00SRoman Divacky #ifdef CLANG_ENABLE_STATIC_ANALYZER 20759cce71aSJordy Rose // Honor -analyzer-checker-help. 20859cce71aSJordy Rose // This should happen AFTER plugins have been loaded! 20940ea0eaaSTed Kremenek if (Clang->getAnalyzerOpts()->ShowCheckerHelp) { 21059cce71aSJordy Rose ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins); 211958297daSRafael Espindola return true; 21259cce71aSJordy Rose } 213d93c8c00SRoman Divacky #endif 21459cce71aSJordy Rose 21585dd0bd1SPeter Collingbourne // If there were errors in processing arguments, don't do anything else. 216aa73d020SSean Silva if (Clang->getDiagnostics().hasErrorOccurred()) 217aa73d020SSean Silva return false; 21885dd0bd1SPeter Collingbourne // Create and execute the frontend action. 219b8984329SAhmed Charles std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang)); 220aa73d020SSean Silva if (!Act) 221aa73d020SSean Silva return false; 222aa73d020SSean Silva bool Success = Clang->ExecuteAction(*Act); 2234f76f4aeSTed Kremenek if (Clang->getFrontendOpts().DisableFree) 2249a16beb8SAhmed Charles BuryPointer(Act.release()); 22585dd0bd1SPeter Collingbourne return Success; 22685dd0bd1SPeter Collingbourne } 227