Timer LLVMIRGeneration;
unsigned LLVMIRGenerationRefCount;
+ /// True if we've finished generating IR. This prevents us from generating
+ /// additional LLVM IR after emitting output in HandleTranslationUnit. This
+ /// can happen when Clang plugins trigger additional AST deserialization.
+ bool IRGenFinished = false;
+
std::unique_ptr<CodeGenerator> Gen;
SmallVector<std::pair<unsigned, std::unique_ptr<llvm::Module>>, 4>
LLVMIRGeneration.stopTimer();
}
+ void HandleInterestingDecl(DeclGroupRef D) {
+ // Ignore interesting decls from the AST reader after IRGen is finished.
+ if (!IRGenFinished)
+ HandleTopLevelDecl(D);
+ }
+
void HandleTranslationUnit(ASTContext &C) override {
{
PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
if (LLVMIRGenerationRefCount == 0)
LLVMIRGeneration.stopTimer();
}
+
+ IRGenFinished = true;
}
// Silently ignore if we weren't initialized for some reason.
--- /dev/null
+// This test uses PrintFunctionNames with -fdelayed-template-parsing because it
+// happens to use a RecursiveASTVisitor that forces deserialization of AST
+// files.
+//
+// RUN: %clang_cc1 -fdelayed-template-parsing -std=c++14 -emit-pch -o %t.pch %s
+// RUN: %clang_cc1 -load %llvmshlibdir/PrintFunctionNames%pluginext \
+// RUN: -add-plugin print-fns -std=c++14 -include-pch %t.pch %s -emit-llvm \
+// RUN: -fdelayed-template-parsing -debug-info-kind=limited \
+// RUN: -o %t.ll 2>&1 | FileCheck --check-prefix=DECLS %s
+// RUN: FileCheck --check-prefix=IR %s < %t.ll
+//
+// REQUIRES: plugins, examples
+
+// DECLS: top-level-decl: "func"
+
+// IR: define {{.*}}void @_Z4funcv()
+
+#ifndef HEADER
+#define HEADER
+
+struct nullopt_t {
+ constexpr explicit nullopt_t(int) {}
+};
+constexpr nullopt_t nullopt(0);
+
+#else
+
+void func() { }
+
+#endif