ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, StringRef InFile) { ASTConsumer* Consumer = CreateASTConsumer(CI, InFile); if (!Consumer) return 0; if (CI.getFrontendOpts().AddPluginActions.size() == 0) return Consumer; // Make sure the non-plugin consumer is first, so that plugins can't // modifiy the AST. std::vector<ASTConsumer*> Consumers(1, Consumer); for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); i != e; ++i) { // This is O(|plugins| * |add_plugins|), but since both numbers are // way below 50 in practice, that's ok. for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { OwningPtr<PluginASTAction> P(it->instantiate()); FrontendAction* c = P.get(); if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) Consumers.push_back(c->CreateASTConsumer(CI, InFile)); } } } return new MultiplexConsumer(Consumers); }
static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { using namespace clang::frontend; switch (CI.getFrontendOpts().ProgramAction) { default: llvm_unreachable("Invalid program action!"); case ASTDump: return new ASTDumpAction(); case ASTPrint: return new ASTPrintAction(); case ASTPrintXML: return new ASTPrintXMLAction(); case ASTView: return new ASTViewAction(); case DumpRawTokens: return new DumpRawTokensAction(); case DumpRecordLayouts: return new DumpRecordAction(); case DumpTokens: return new DumpTokensAction(); case EmitAssembly: return new EmitAssemblyAction(); case EmitBC: return new EmitBCAction(); case EmitHTML: return new HTMLPrintAction(); case EmitLLVM: return new EmitLLVMAction(); case EmitLLVMOnly: return new EmitLLVMOnlyAction(); case EmitObj: return new EmitObjAction(); case FixIt: return new FixItAction(); case GeneratePCH: return new GeneratePCHAction(); case GeneratePTH: return new GeneratePTHAction(); case InheritanceView: return new InheritanceViewAction(); case ParseNoop: return new ParseOnlyAction(); case ParsePrintCallbacks: return new PrintParseAction(); case ParseSyntaxOnly: return new SyntaxOnlyAction(); case PluginAction: { if (CI.getFrontendOpts().ActionName == "help") { llvm::errs() << "clang -cc1 plugins:\n"; for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) llvm::errs() << " " << it->getName() << " - " << it->getDesc() << "\n"; return 0; } for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { if (it->getName() == CI.getFrontendOpts().ActionName) return it->instantiate(); } CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << CI.getFrontendOpts().ActionName; return 0; } case PrintDeclContext: return new DeclContextPrintAction(); case PrintPreprocessedInput: return new PrintPreprocessedAction(); case RewriteMacros: return new RewriteMacrosAction(); case RewriteObjC: return new RewriteObjCAction(); case RewriteTest: return new RewriteTestAction(); case RunAnalysis: return new AnalysisAction(); case RunPreprocessorOnly: return new PreprocessOnlyAction(); } }
std::unique_ptr<ASTConsumer> FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, StringRef InFile) { std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile); if (!Consumer) return nullptr; if (CI.getFrontendOpts().AddPluginActions.size() == 0) return Consumer; // Make sure the non-plugin consumer is first, so that plugins can't // modifiy the AST. std::vector<std::unique_ptr<ASTConsumer>> Consumers; Consumers.push_back(std::move(Consumer)); for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); i != e; ++i) { // This is O(|plugins| * |add_plugins|), but since both numbers are // way below 50 in practice, that's ok. for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { if (it->getName() != CI.getFrontendOpts().AddPluginActions[i]) continue; std::unique_ptr<PluginASTAction> P = it->instantiate(); if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i])) Consumers.push_back(P->CreateASTConsumer(CI, InFile)); } } return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); }
static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { using namespace clang::frontend; switch (CI.getFrontendOpts().ProgramAction) { default: llvm_unreachable("Invalid program action!"); case ASTDump: return new ASTDumpAction(); case ASTPrint: return new ASTPrintAction(); case ASTPrintXML: return new ASTPrintXMLAction(); case ASTView: return new ASTViewAction(); case BoostCon: return new BoostConAction(); case DumpRawTokens: return new DumpRawTokensAction(); case DumpTokens: return new DumpTokensAction(); case EmitAssembly: return new EmitAssemblyAction(); case EmitBC: return new EmitBCAction(); case EmitHTML: return new HTMLPrintAction(); case EmitLLVM: return new EmitLLVMAction(); case EmitLLVMOnly: return new EmitLLVMOnlyAction(); case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); case EmitObj: return new EmitObjAction(); case FixIt: return new FixItAction(); case GeneratePCH: return new GeneratePCHAction(); case GeneratePTH: return new GeneratePTHAction(); case InheritanceView: return new InheritanceViewAction(); case InitOnly: return new InitOnlyAction(); case ParseSyntaxOnly: return new SyntaxOnlyAction(); case PluginAction: { for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { if (it->getName() == CI.getFrontendOpts().ActionName) { llvm::OwningPtr<PluginASTAction> P(it->instantiate()); if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) return 0; return P.take(); } } CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << CI.getFrontendOpts().ActionName; return 0; } case PrintDeclContext: return new DeclContextPrintAction(); case PrintPreamble: return new PrintPreambleAction(); case PrintPreprocessedInput: return new PrintPreprocessedAction(); case RewriteMacros: return new RewriteMacrosAction(); case RewriteObjC: return new RewriteObjCAction(); case RewriteTest: return new RewriteTestAction(); //case RunAnalysis: return new AnalysisAction(); case RunPreprocessorOnly: return new PreprocessOnlyAction(); } }
std::unique_ptr<ASTConsumer> FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, StringRef InFile) { std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile); if (!Consumer) return nullptr; // If there are no registered plugins we don't need to wrap the consumer if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end()) return Consumer; // If this is a code completion run, avoid invoking the plugin consumers if (CI.hasCodeCompletionConsumer()) return Consumer; // Collect the list of plugins that go before the main action (in Consumers) // or after it (in AfterConsumers) std::vector<std::unique_ptr<ASTConsumer>> Consumers; std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers; for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { std::unique_ptr<PluginASTAction> P = it->instantiate(); PluginASTAction::ActionType ActionType = P->getActionType(); if (ActionType == PluginASTAction::Cmdline) { // This is O(|plugins| * |add_plugins|), but since both numbers are // way below 50 in practice, that's ok. for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size(); i != e; ++i) { if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) { ActionType = PluginASTAction::AddAfterMainAction; break; } } } if ((ActionType == PluginASTAction::AddBeforeMainAction || ActionType == PluginASTAction::AddAfterMainAction) && P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) { std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile); if (ActionType == PluginASTAction::AddBeforeMainAction) { Consumers.push_back(std::move(PluginConsumer)); } else { AfterConsumers.push_back(std::move(PluginConsumer)); } } } // Add to Consumers the main consumer, then all the plugins that go after it Consumers.push_back(std::move(Consumer)); for (auto &C : AfterConsumers) { Consumers.push_back(std::move(C)); } return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); }
static std::unique_ptr<FrontendAction> CreateFrontendBaseAction(CompilerInstance &CI) { using namespace clang::frontend; StringRef Action("unknown"); (void)Action; switch (CI.getFrontendOpts().ProgramAction) { case ASTDeclList: return llvm::make_unique<ASTDeclListAction>(); case ASTDump: return llvm::make_unique<ASTDumpAction>(); case ASTPrint: return llvm::make_unique<ASTPrintAction>(); case ASTView: return llvm::make_unique<ASTViewAction>(); case DumpRawTokens: return llvm::make_unique<DumpRawTokensAction>(); case DumpTokens: return llvm::make_unique<DumpTokensAction>(); case EmitAssembly: return llvm::make_unique<EmitAssemblyAction>(); case EmitBC: return llvm::make_unique<EmitBCAction>(); case EmitHTML: return llvm::make_unique<HTMLPrintAction>(); case EmitLLVM: return llvm::make_unique<EmitLLVMAction>(); case EmitLLVMOnly: return llvm::make_unique<EmitLLVMOnlyAction>(); case EmitCodeGenOnly: return llvm::make_unique<EmitCodeGenOnlyAction>(); case EmitObj: return llvm::make_unique<EmitObjAction>(); case FixIt: return llvm::make_unique<FixItAction>(); case GenerateModule: return llvm::make_unique<GenerateModuleFromModuleMapAction>(); case GenerateModuleInterface: return llvm::make_unique<GenerateModuleInterfaceAction>(); case GeneratePCH: return llvm::make_unique<GeneratePCHAction>(); case GeneratePTH: return llvm::make_unique<GeneratePTHAction>(); case InitOnly: return llvm::make_unique<InitOnlyAction>(); case ParseSyntaxOnly: return llvm::make_unique<SyntaxOnlyAction>(); case ModuleFileInfo: return llvm::make_unique<DumpModuleInfoAction>(); case VerifyPCH: return llvm::make_unique<VerifyPCHAction>(); case PluginAction: { for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { if (it->getName() == CI.getFrontendOpts().ActionName) { std::unique_ptr<PluginASTAction> P(it->instantiate()); if ((P->getActionType() != PluginASTAction::ReplaceAction && P->getActionType() != PluginASTAction::Cmdline) || !P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) return nullptr; return std::move(P); } } CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << CI.getFrontendOpts().ActionName; return nullptr; } case PrintDeclContext: return llvm::make_unique<DeclContextPrintAction>(); case PrintPreamble: return llvm::make_unique<PrintPreambleAction>(); case PrintPreprocessedInput: { if (CI.getPreprocessorOutputOpts().RewriteIncludes) return llvm::make_unique<RewriteIncludesAction>(); return llvm::make_unique<PrintPreprocessedAction>(); } case RewriteMacros: return llvm::make_unique<RewriteMacrosAction>(); case RewriteTest: return llvm::make_unique<RewriteTestAction>(); #ifdef CLANG_ENABLE_OBJC_REWRITER case RewriteObjC: return llvm::make_unique<RewriteObjCAction>(); #else case RewriteObjC: Action = "RewriteObjC"; break; #endif #ifdef CLANG_ENABLE_ARCMT case MigrateSource: return llvm::make_unique<arcmt::MigrateSourceAction>(); #else case MigrateSource: Action = "MigrateSource"; break; #endif #ifdef CLANG_ENABLE_STATIC_ANALYZER case RunAnalysis: return llvm::make_unique<ento::AnalysisAction>(); #else case RunAnalysis: Action = "RunAnalysis"; break; #endif case RunPreprocessorOnly: return llvm::make_unique<PreprocessOnlyAction>(); } #if !defined(CLANG_ENABLE_ARCMT) || !defined(CLANG_ENABLE_STATIC_ANALYZER) \ || !defined(CLANG_ENABLE_OBJC_REWRITER) CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action; return 0; #else llvm_unreachable("Invalid program action!"); #endif }
bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) { // Honor -help. if (Clang->getFrontendOpts().ShowHelp) { std::unique_ptr<OptTable> Opts = driver::createDriverOptTable(); Opts->PrintHelp(llvm::outs(), "clang -cc1", "LLVM 'Clang' Compiler: http://clang.llvm.org", /*Include=*/ driver::options::CC1Option, /*Exclude=*/ 0); return true; } // Honor -version. // // FIXME: Use a better -version message? if (Clang->getFrontendOpts().ShowVersion) { llvm::cl::PrintVersionMessage(); return true; } // Load any requested plugins. for (unsigned i = 0, e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) { const std::string &Path = Clang->getFrontendOpts().Plugins[i]; std::string Error; if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) << Path << Error; } // Check if any of the loaded plugins replaces the main AST action for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { std::unique_ptr<PluginASTAction> P(it->instantiate()); if (P->getActionType() == PluginASTAction::ReplaceAction) { Clang->getFrontendOpts().ProgramAction = clang::frontend::PluginAction; Clang->getFrontendOpts().ActionName = it->getName(); break; } } // Honor -mllvm. // // FIXME: Remove this, one day. // This should happen AFTER plugins have been loaded! if (!Clang->getFrontendOpts().LLVMArgs.empty()) { unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size(); auto Args = llvm::make_unique<const char*[]>(NumArgs + 2); Args[0] = "clang (LLVM option parsing)"; for (unsigned i = 0; i != NumArgs; ++i) Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str(); Args[NumArgs + 1] = nullptr; llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); } #ifdef CLANG_ENABLE_STATIC_ANALYZER // Honor -analyzer-checker-help. // This should happen AFTER plugins have been loaded! if (Clang->getAnalyzerOpts()->ShowCheckerHelp) { ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins); return true; } if (Clang->getAnalyzerOpts()->ShowEnabledCheckerList) { ento::printEnabledCheckerList(llvm::outs(), Clang->getFrontendOpts().Plugins, *Clang->getAnalyzerOpts()); } #endif // If there were errors in processing arguments, don't do anything else. if (Clang->getDiagnostics().hasErrorOccurred()) return false; // Create and execute the frontend action. std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang)); if (!Act) return false; bool Success = Clang->ExecuteAction(*Act); if (Clang->getFrontendOpts().DisableFree) BuryPointer(std::move(Act)); return Success; }
static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { using namespace clang::frontend; StringRef Action("unknown"); switch (CI.getFrontendOpts().ProgramAction) { case ASTDeclList: return new ASTDeclListAction(); case ASTDump: return new ASTDumpAction(); case ASTDumpXML: return new ASTDumpXMLAction(); case ASTPrint: return new ASTPrintAction(); case ASTView: return new ASTViewAction(); case DumpRawTokens: return new DumpRawTokensAction(); case DumpTokens: return new DumpTokensAction(); case EmitAssembly: return new EmitAssemblyAction(); case EmitBC: return new EmitBCAction(); #ifdef CLANG_ENABLE_REWRITER case EmitHTML: return new HTMLPrintAction(); #else case EmitHTML: Action = "EmitHTML"; break; #endif case EmitLLVM: return new EmitLLVMAction(); case EmitLLVMOnly: return new EmitLLVMOnlyAction(); case EmitCodeGenOnly: return new EmitCodeGenOnlyAction(); case EmitObj: return new EmitObjAction(); #ifdef CLANG_ENABLE_REWRITER case FixIt: return new FixItAction(); #else case FixIt: Action = "FixIt"; break; #endif case GenerateModule: return new GenerateModuleAction; case GeneratePCH: return new GeneratePCHAction; case GeneratePTH: return new GeneratePTHAction(); case InitOnly: return new InitOnlyAction(); case ParseSyntaxOnly: return new SyntaxOnlyAction(); case PluginAction: { for (FrontendPluginRegistry::iterator it = FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end(); it != ie; ++it) { if (it->getName() == CI.getFrontendOpts().ActionName) { OwningPtr<PluginASTAction> P(it->instantiate()); if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) return 0; return P.take(); } } CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << CI.getFrontendOpts().ActionName; return 0; } case PrintDeclContext: return new DeclContextPrintAction(); case PrintPreamble: return new PrintPreambleAction(); case PrintPreprocessedInput: { if (CI.getPreprocessorOutputOpts().RewriteIncludes) { #ifdef CLANG_ENABLE_REWRITER return new RewriteIncludesAction(); #else Action = "RewriteIncludesAction"; break; #endif } return new PrintPreprocessedAction(); } #ifdef CLANG_ENABLE_REWRITER case RewriteMacros: return new RewriteMacrosAction(); case RewriteObjC: return new RewriteObjCAction(); case RewriteTest: return new RewriteTestAction(); #else case RewriteMacros: Action = "RewriteMacros"; break; case RewriteObjC: Action = "RewriteObjC"; break; case RewriteTest: Action = "RewriteTest"; break; #endif #ifdef CLANG_ENABLE_ARCMT case MigrateSource: return new arcmt::MigrateSourceAction(); #else case MigrateSource: Action = "MigrateSource"; break; #endif #ifdef CLANG_ENABLE_STATIC_ANALYZER case RunAnalysis: return new ento::AnalysisAction(); #else case RunAnalysis: Action = "RunAnalysis"; break; #endif case RunPreprocessorOnly: return new PreprocessOnlyAction(); } #if !defined(CLANG_ENABLE_ARCMT) || !defined(CLANG_ENABLE_STATIC_ANALYZER) \ || !defined(CLANG_ENABLE_REWRITER) CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action; return 0; #else llvm_unreachable("Invalid program action!"); #endif }