diff options
author | John Brawn <john.brawn@arm.com> | 2016-03-15 12:51:40 +0000 |
---|---|---|
committer | John Brawn <john.brawn@arm.com> | 2016-03-15 12:51:40 +0000 |
commit | 6c78974b298d619ec11e243fb6fdea0b16f87a66 (patch) | |
tree | a3821d2f102bdc6db560013edefad6cd3f4e983c /clang/lib | |
parent | 27fc7a7b47bc9656b5af858432518e81b9d36482 (diff) | |
download | bcm5719-llvm-6c78974b298d619ec11e243fb6fdea0b16f87a66.tar.gz bcm5719-llvm-6c78974b298d619ec11e243fb6fdea0b16f87a66.zip |
Make it possible for AST plugins to enable themselves by default
Currently when an AST plugin is loaded it must then be enabled by passing
-plugin pluginname or -add-plugin pluginname to the -cc1 command line. This
patch adds a method to PluginASTAction which allows it to declare that the
action happens before, instead of, or after the main AST action, plus the
relevant changes to make the plugin action happen at that time automatically.
Differential Revision: http://reviews.llvm.org/D17959
llvm-svn: 263546
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 54 | ||||
-rw-r--r-- | clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp | 16 |
3 files changed, 53 insertions, 29 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index d2643614670..858ecc72c4d 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1051,18 +1051,10 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.Plugins.emplace_back(A->getValue(0)); Opts.ProgramAction = frontend::PluginAction; Opts.ActionName = A->getValue(); - - for (const Arg *AA : Args.filtered(OPT_plugin_arg)) - if (AA->getValue(0) == Opts.ActionName) - Opts.PluginArgs.emplace_back(AA->getValue(1)); } - Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin); - Opts.AddPluginArgs.resize(Opts.AddPluginActions.size()); - for (int i = 0, e = Opts.AddPluginActions.size(); i != e; ++i) - for (const Arg *A : Args.filtered(OPT_plugin_arg)) - if (A->getValue(0) == Opts.AddPluginActions[i]) - Opts.AddPluginArgs[i].emplace_back(A->getValue(1)); + for (const Arg *AA : Args.filtered(OPT_plugin_arg)) + Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1)); for (const std::string &Arg : Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) { diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index cdaa18a7a31..d514d406d8b 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -141,28 +141,46 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI, if (!Consumer) return nullptr; - if (CI.getFrontendOpts().AddPluginActions.size() == 0) + // If there are no registered plugins we don't need to wrap the consumer + if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end()) return Consumer; - // Make sure the non-plugin consumer is first, so that plugins can't - // modifiy the AST. + // 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; - 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)); + 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)); diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 116590e5375..509c326d159 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -66,7 +66,9 @@ CreateFrontendBaseAction(CompilerInstance &CI) { it != ie; ++it) { if (it->getName() == CI.getFrontendOpts().ActionName) { std::unique_ptr<PluginASTAction> P(it->instantiate()); - if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs)) + if ((P->getActionType() != PluginASTAction::ReplaceAction && + P->getActionType() != PluginASTAction::Cmdline) || + !P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs[it->getName()])) return nullptr; return std::move(P); } @@ -194,6 +196,18 @@ bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) { << 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. |