diff --git a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h index 0192193281119..6cc00680eab79 100644 --- a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h +++ b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H #include "clang/Analysis/FlowSensitive/DataflowLattice.h" +#include "llvm/ADT/Any.h" #include namespace clang { @@ -38,4 +39,13 @@ inline std::ostream &operator<<(std::ostream &OS, const NoopLattice &) { } // namespace dataflow } // namespace clang +namespace llvm { +// This needs to be exported for ClangAnalysisFlowSensitiveTests so any_cast +// uses the correct address of Any::TypeId from the clang shared library instead +// of creating one in the test executable. when building with +// CLANG_LINK_CLANG_DYLIB +extern template struct CLANG_TEMPLATE_ABI + Any::TypeId; +}; // namespace llvm + #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 8afd18b315d28..32b3886439495 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -30,6 +30,7 @@ #include "clang/Analysis/FlowSensitive/Transfer.h" #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" #include "clang/Analysis/FlowSensitive/Value.h" +#include "clang/Support/Compiler.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" @@ -37,6 +38,20 @@ #define DEBUG_TYPE "clang-dataflow" +namespace clang { +namespace dataflow { +class NoopLattice; +} +} // namespace clang + +namespace llvm { +// This needs to be exported for ClangAnalysisFlowSensitiveTests so any_cast +// uses the correct address of Any::TypeId from the clang shared library instead +// of creating one in the test executable. when building with +// CLANG_LINK_CLANG_DYLIB +template struct CLANG_EXPORT_TEMPLATE Any::TypeId; +} // namespace llvm + namespace clang { namespace dataflow { diff --git a/llvm/include/llvm/Analysis/LazyCallGraph.h b/llvm/include/llvm/Analysis/LazyCallGraph.h index e7fd18967d9be..289e9c3990bcc 100644 --- a/llvm/include/llvm/Analysis/LazyCallGraph.h +++ b/llvm/include/llvm/Analysis/LazyCallGraph.h @@ -34,6 +34,7 @@ #ifndef LLVM_ANALYSIS_LAZYCALLGRAPH_H #define LLVM_ANALYSIS_LAZYCALLGRAPH_H +#include "llvm/ADT/Any.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" @@ -1308,6 +1309,8 @@ class LazyCallGraphDOTPrinterPass static bool isRequired() { return true; } }; +extern template struct LLVM_TEMPLATE_ABI + Any::TypeId; } // end namespace llvm #endif // LLVM_ANALYSIS_LAZYCALLGRAPH_H diff --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h index 9fcc2d5957a30..45ee372e7959d 100644 --- a/llvm/include/llvm/IR/PassInstrumentation.h +++ b/llvm/include/llvm/IR/PassInstrumentation.h @@ -50,10 +50,11 @@ #define LLVM_IR_PASSINSTRUMENTATION_H #include "llvm/ADT/Any.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/IR/PassManager.h" +#include "llvm/Support/Compiler.h" #include #include @@ -61,6 +62,13 @@ namespace llvm { class PreservedAnalyses; class StringRef; +class Module; +class Loop; +class Function; + +extern template struct LLVM_TEMPLATE_ABI Any::TypeId; +extern template struct LLVM_TEMPLATE_ABI Any::TypeId; +extern template struct LLVM_TEMPLATE_ABI Any::TypeId; /// This class manages callbacks registration, as well as provides a way for /// PassInstrumentation to pass control to the registered callbacks. diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp index e6bf8c9cbb289..5aa36bfc36d46 100644 --- a/llvm/lib/Analysis/LazyCallGraph.cpp +++ b/llvm/lib/Analysis/LazyCallGraph.cpp @@ -37,6 +37,8 @@ using namespace llvm; #define DEBUG_TYPE "lcg" +template struct LLVM_EXPORT_TEMPLATE Any::TypeId; + void LazyCallGraph::EdgeSequence::insertEdgeInternal(Node &TargetN, Edge::Kind EK) { EdgeIndexMap.try_emplace(&TargetN, Edges.size()); diff --git a/llvm/lib/IR/PassInstrumentation.cpp b/llvm/lib/IR/PassInstrumentation.cpp index 0c4e7698d9fa8..94ad124a6c770 100644 --- a/llvm/lib/IR/PassInstrumentation.cpp +++ b/llvm/lib/IR/PassInstrumentation.cpp @@ -17,6 +17,10 @@ namespace llvm { +template struct LLVM_EXPORT_TEMPLATE Any::TypeId; +template struct LLVM_EXPORT_TEMPLATE Any::TypeId; +template struct LLVM_EXPORT_TEMPLATE Any::TypeId; + void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName, StringRef PassName) { ClassToPassName.try_emplace(ClassName, PassName.str()); diff --git a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp index 5ef25c21162fe..d3bcfb8cc6404 100644 --- a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp +++ b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp @@ -269,12 +269,9 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F, PI.pushBeforeNonSkippedPassCallback([&LAR, &LI](StringRef PassID, Any IR) { if (isSpecialPass(PassID, {"PassManager"})) return; - assert(llvm::any_cast(&IR) || - llvm::any_cast(&IR)); + assert(llvm::any_cast(&IR)); const Loop **LPtr = llvm::any_cast(&IR); const Loop *L = LPtr ? *LPtr : nullptr; - if (!L) - L = &llvm::any_cast(IR)->getOutermostLoop(); assert(L && "Loop should be valid for printing"); // Verify the loop structure and LCSSA form before visiting the loop. diff --git a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp index 6230aed7b7119..9aad6e3ca9125 100644 --- a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp +++ b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp @@ -298,8 +298,6 @@ template <> std::string getName(const Any &WrappedIR) { return (*F)->getName().str(); if (const auto *const *L = llvm::any_cast(&WrappedIR)) return (*L)->getName().str(); - if (const auto *const *L = llvm::any_cast(&WrappedIR)) - return (*L)->getName().str(); if (const auto *const *C = llvm::any_cast(&WrappedIR)) return (*C)->getName();