[clang] Don't clear AST if we have consumers running after the main action
authorArthur Eubanks <aeubanks@google.com>
Wed, 20 Oct 2021 22:43:10 +0000 (15:43 -0700)
committerArthur Eubanks <aeubanks@google.com>
Thu, 21 Oct 2021 16:03:57 +0000 (09:03 -0700)
Downstream users may have Clang plugins. By default these plugins run
after the main action if they are specified on the command line.

Since these plugins are ASTConsumers, presumably they inspect the AST.
So we shouldn't clear it if any plugins run after the main action.

Reviewed By: dblaikie, hans

Differential Revision: https://reviews.llvm.org/D112190

clang/lib/Frontend/FrontendAction.cpp
clang/test/Misc/clear-ast-before-backend-plugins.c [new file with mode: 0644]

index b56db78..089f40b 100644 (file)
@@ -217,8 +217,13 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
 
   // 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));
+  if (!AfterConsumers.empty()) {
+    // If we have plugins after the main consumer, which may be the codegen
+    // action, they likely will need the ASTContext, so don't clear it in the
+    // codegen action.
+    CI.getCodeGenOpts().ClearASTBeforeBackend = false;
+    for (auto &C : AfterConsumers)
+      Consumers.push_back(std::move(C));
   }
 
   return std::make_unique<MultiplexConsumer>(std::move(Consumers));
diff --git a/clang/test/Misc/clear-ast-before-backend-plugins.c b/clang/test/Misc/clear-ast-before-backend-plugins.c
new file mode 100644 (file)
index 0000000..c00bee4
--- /dev/null
@@ -0,0 +1,9 @@
+// REQUIRES: plugins, examples, asserts
+
+// RUN: %clang_cc1 -mllvm -debug-only=codegenaction -clear-ast-before-backend -emit-obj -o /dev/null -load %llvmshlibdir/PrintFunctionNames%pluginext %s 2>&1 | FileCheck %s --check-prefix=YES
+// YES: Clearing AST
+
+// RUN: %clang_cc1 -mllvm -debug-only=codegenaction -clear-ast-before-backend -emit-obj -o /dev/null -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-fns -plugin-arg-print-fns help %s 2>&1 | FileCheck %s --check-prefix=NO
+// NO-NOT: Clearing AST
+
+void f() {}