diff options
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. |