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" 16556c45e9SArgyrios Kyrtzidis #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" 17b5703510SChandler Carruth #include "clang/ARCMigrate/ARCMTActions.h" 1885dd0bd1SPeter Collingbourne #include "clang/CodeGen/CodeGenAction.h" 1985dd0bd1SPeter Collingbourne #include "clang/Driver/CC1Options.h" 2085dd0bd1SPeter Collingbourne #include "clang/Driver/OptTable.h" 2185dd0bd1SPeter Collingbourne #include "clang/Frontend/CompilerInvocation.h" 2285dd0bd1SPeter Collingbourne #include "clang/Frontend/CompilerInstance.h" 2385dd0bd1SPeter Collingbourne #include "clang/Frontend/FrontendActions.h" 2485dd0bd1SPeter Collingbourne #include "clang/Frontend/FrontendDiagnostic.h" 2585dd0bd1SPeter Collingbourne #include "clang/Frontend/FrontendPluginRegistry.h" 2685dd0bd1SPeter Collingbourne #include "clang/Rewrite/FrontendActions.h" 2785dd0bd1SPeter Collingbourne #include "llvm/Support/ErrorHandling.h" 288aaf4995SMichael J. Spencer #include "llvm/Support/DynamicLibrary.h" 2985dd0bd1SPeter Collingbourne using namespace clang; 3085dd0bd1SPeter Collingbourne 3185dd0bd1SPeter Collingbourne static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { 3285dd0bd1SPeter Collingbourne using namespace clang::frontend; 3385dd0bd1SPeter Collingbourne 3485dd0bd1SPeter Collingbourne switch (CI.getFrontendOpts().ProgramAction) { 3585dd0bd1SPeter Collingbourne case ASTDump: return new ASTDumpAction(); 369b66c4bbSJohn McCall case ASTDumpXML: return new ASTDumpXMLAction(); 3785dd0bd1SPeter Collingbourne case ASTPrint: return new ASTPrintAction(); 3885dd0bd1SPeter Collingbourne case ASTView: return new ASTViewAction(); 3985dd0bd1SPeter Collingbourne case DumpRawTokens: return new DumpRawTokensAction(); 4085dd0bd1SPeter Collingbourne case DumpTokens: return new DumpTokensAction(); 4185dd0bd1SPeter Collingbourne case EmitAssembly: return new EmitAssemblyAction(); 4285dd0bd1SPeter Collingbourne case EmitBC: return new EmitBCAction(); 4385dd0bd1SPeter Collingbourne case EmitHTML: return new HTMLPrintAction(); 4485dd0bd1SPeter Collingbourne case EmitLLVM: return new EmitLLVMAction(); 4585dd0bd1SPeter Collingbourne case EmitLLVMOnly: return new EmitLLVMOnlyAction(); 4685dd0bd1SPeter Collingbourne case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); 4785dd0bd1SPeter Collingbourne case EmitObj: return new EmitObjAction(); 4885dd0bd1SPeter Collingbourne case FixIt: return new FixItAction(); 4970db54f1SDouglas Gregor case GenerateModule: return new GenerateModuleAction; 5070db54f1SDouglas Gregor case GeneratePCH: return new GeneratePCHAction; 5185dd0bd1SPeter Collingbourne case GeneratePTH: return new GeneratePTHAction(); 5285dd0bd1SPeter Collingbourne case InitOnly: return new InitOnlyAction(); 5385dd0bd1SPeter Collingbourne case ParseSyntaxOnly: return new SyntaxOnlyAction(); 5485dd0bd1SPeter Collingbourne 5585dd0bd1SPeter Collingbourne case PluginAction: { 5685dd0bd1SPeter Collingbourne for (FrontendPluginRegistry::iterator it = 5785dd0bd1SPeter Collingbourne FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); 5885dd0bd1SPeter Collingbourne it != ie; ++it) { 5985dd0bd1SPeter Collingbourne if (it->getName() == CI.getFrontendOpts().ActionName) { 60e2778999SDylan Noblesmith OwningPtr<PluginASTAction> P(it->instantiate()); 6185dd0bd1SPeter Collingbourne if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) 6285dd0bd1SPeter Collingbourne return 0; 6385dd0bd1SPeter Collingbourne return P.take(); 6485dd0bd1SPeter Collingbourne } 6585dd0bd1SPeter Collingbourne } 6685dd0bd1SPeter Collingbourne 6785dd0bd1SPeter Collingbourne CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) 6885dd0bd1SPeter Collingbourne << CI.getFrontendOpts().ActionName; 6985dd0bd1SPeter Collingbourne return 0; 7085dd0bd1SPeter Collingbourne } 7185dd0bd1SPeter Collingbourne 7285dd0bd1SPeter Collingbourne case PrintDeclContext: return new DeclContextPrintAction(); 7385dd0bd1SPeter Collingbourne case PrintPreamble: return new PrintPreambleAction(); 7485dd0bd1SPeter Collingbourne case PrintPreprocessedInput: return new PrintPreprocessedAction(); 7585dd0bd1SPeter Collingbourne case RewriteMacros: return new RewriteMacrosAction(); 7685dd0bd1SPeter Collingbourne case RewriteObjC: return new RewriteObjCAction(); 7785dd0bd1SPeter Collingbourne case RewriteTest: return new RewriteTestAction(); 7898857c98STed Kremenek case RunAnalysis: return new ento::AnalysisAction(); 7985dd0bd1SPeter Collingbourne case RunPreprocessorOnly: return new PreprocessOnlyAction(); 8085dd0bd1SPeter Collingbourne } 81f47fa304SDavid Blaikie llvm_unreachable("Invalid program action!"); 8285dd0bd1SPeter Collingbourne } 8385dd0bd1SPeter Collingbourne 8485dd0bd1SPeter Collingbourne static FrontendAction *CreateFrontendAction(CompilerInstance &CI) { 8585dd0bd1SPeter Collingbourne // Create the underlying action. 8685dd0bd1SPeter Collingbourne FrontendAction *Act = CreateFrontendBaseAction(CI); 8785dd0bd1SPeter Collingbourne if (!Act) 8885dd0bd1SPeter Collingbourne return 0; 8985dd0bd1SPeter Collingbourne 903d97a9beSArgyrios Kyrtzidis const FrontendOptions &FEOpts = CI.getFrontendOpts(); 913d97a9beSArgyrios Kyrtzidis 923d97a9beSArgyrios Kyrtzidis if (FEOpts.FixAndRecompile) { 9324e9afffSArgyrios Kyrtzidis Act = new FixItRecompile(Act); 9424e9afffSArgyrios Kyrtzidis } 9524e9afffSArgyrios Kyrtzidis 96b5703510SChandler Carruth // Potentially wrap the base FE action in an ARC Migrate Tool action. 973d97a9beSArgyrios Kyrtzidis switch (FEOpts.ARCMTAction) { 98b5703510SChandler Carruth case FrontendOptions::ARCMT_None: 99b5703510SChandler Carruth break; 100b5703510SChandler Carruth case FrontendOptions::ARCMT_Check: 101b5703510SChandler Carruth Act = new arcmt::CheckAction(Act); 102b5703510SChandler Carruth break; 103b5703510SChandler Carruth case FrontendOptions::ARCMT_Modify: 1047fbd97f6SArgyrios Kyrtzidis Act = new arcmt::ModifyAction(Act); 1057fbd97f6SArgyrios Kyrtzidis break; 1067fbd97f6SArgyrios Kyrtzidis case FrontendOptions::ARCMT_Migrate: 107d571363eSArgyrios Kyrtzidis Act = new arcmt::MigrateAction(Act, 1083d97a9beSArgyrios Kyrtzidis FEOpts.ARCMTMigrateDir, 1093d97a9beSArgyrios Kyrtzidis FEOpts.ARCMTMigrateReportOut, 1103d97a9beSArgyrios Kyrtzidis FEOpts.ARCMTMigrateEmitARCErrors); 111b5703510SChandler Carruth break; 112b5703510SChandler Carruth } 113b5703510SChandler Carruth 11485dd0bd1SPeter Collingbourne // If there are any AST files to merge, create a frontend action 11585dd0bd1SPeter Collingbourne // adaptor to perform the merge. 1163d97a9beSArgyrios Kyrtzidis if (!FEOpts.ASTMergeFiles.empty()) 117bd6a7d4cSArgyrios Kyrtzidis Act = new ASTMergeAction(Act, FEOpts.ASTMergeFiles); 11885dd0bd1SPeter Collingbourne 11985dd0bd1SPeter Collingbourne return Act; 12085dd0bd1SPeter Collingbourne } 12185dd0bd1SPeter Collingbourne 12285dd0bd1SPeter Collingbourne bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) { 12385dd0bd1SPeter Collingbourne // Honor -help. 12485dd0bd1SPeter Collingbourne if (Clang->getFrontendOpts().ShowHelp) { 125e2778999SDylan Noblesmith OwningPtr<driver::OptTable> Opts(driver::createCC1OptTable()); 12685dd0bd1SPeter Collingbourne Opts->PrintHelp(llvm::outs(), "clang -cc1", 12785dd0bd1SPeter Collingbourne "LLVM 'Clang' Compiler: http://clang.llvm.org"); 12885dd0bd1SPeter Collingbourne return 0; 12985dd0bd1SPeter Collingbourne } 13085dd0bd1SPeter Collingbourne 13185dd0bd1SPeter Collingbourne // Honor -version. 13285dd0bd1SPeter Collingbourne // 13385dd0bd1SPeter Collingbourne // FIXME: Use a better -version message? 13485dd0bd1SPeter Collingbourne if (Clang->getFrontendOpts().ShowVersion) { 13585dd0bd1SPeter Collingbourne llvm::cl::PrintVersionMessage(); 13685dd0bd1SPeter Collingbourne return 0; 13785dd0bd1SPeter Collingbourne } 13885dd0bd1SPeter Collingbourne 13985dd0bd1SPeter Collingbourne // Load any requested plugins. 14085dd0bd1SPeter Collingbourne for (unsigned i = 0, 14185dd0bd1SPeter Collingbourne e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { 14285dd0bd1SPeter Collingbourne const std::string &Path = Clang->getFrontendOpts().Plugins[i]; 14385dd0bd1SPeter Collingbourne std::string Error; 14485dd0bd1SPeter Collingbourne if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) 14585dd0bd1SPeter Collingbourne Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) 14685dd0bd1SPeter Collingbourne << Path << Error; 14785dd0bd1SPeter Collingbourne } 14885dd0bd1SPeter Collingbourne 14911ce9224STobias Grosser // Honor -mllvm. 15011ce9224STobias Grosser // 15111ce9224STobias Grosser // FIXME: Remove this, one day. 15211ce9224STobias Grosser // This should happen AFTER plugins have been loaded! 15311ce9224STobias Grosser if (!Clang->getFrontendOpts().LLVMArgs.empty()) { 15411ce9224STobias Grosser unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size(); 15511ce9224STobias Grosser const char **Args = new const char*[NumArgs + 2]; 15611ce9224STobias Grosser Args[0] = "clang (LLVM option parsing)"; 15711ce9224STobias Grosser for (unsigned i = 0; i != NumArgs; ++i) 15811ce9224STobias Grosser Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str(); 15911ce9224STobias Grosser Args[NumArgs + 1] = 0; 160*09d20eefSDavid Blaikie llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args); 16111ce9224STobias Grosser } 16211ce9224STobias Grosser 16359cce71aSJordy Rose // Honor -analyzer-checker-help. 16459cce71aSJordy Rose // This should happen AFTER plugins have been loaded! 16559cce71aSJordy Rose if (Clang->getAnalyzerOpts().ShowCheckerHelp) { 16659cce71aSJordy Rose ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins); 16759cce71aSJordy Rose return 0; 16859cce71aSJordy Rose } 16959cce71aSJordy Rose 17085dd0bd1SPeter Collingbourne // If there were errors in processing arguments, don't do anything else. 17185dd0bd1SPeter Collingbourne bool Success = false; 1725c26cda2SArgyrios Kyrtzidis if (!Clang->getDiagnostics().hasErrorOccurred()) { 17385dd0bd1SPeter Collingbourne // Create and execute the frontend action. 174e2778999SDylan Noblesmith OwningPtr<FrontendAction> Act(CreateFrontendAction(*Clang)); 1754f76f4aeSTed Kremenek if (Act) { 17685dd0bd1SPeter Collingbourne Success = Clang->ExecuteAction(*Act); 1774f76f4aeSTed Kremenek if (Clang->getFrontendOpts().DisableFree) 1784f76f4aeSTed Kremenek Act.take(); 1794f76f4aeSTed Kremenek } 18085dd0bd1SPeter Collingbourne } 18185dd0bd1SPeter Collingbourne 18285dd0bd1SPeter Collingbourne return Success; 18385dd0bd1SPeter Collingbourne } 184