summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp12
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp54
-rw-r--r--clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp16
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.
OpenPOWER on IntegriCloud