Index: lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.h =================================================================== --- /dev/null +++ lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.h @@ -0,0 +1,3 @@ +class ExtBase { + virtual char bar(); +}; Index: lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.cpp =================================================================== --- /dev/null +++ lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.cpp @@ -0,0 +1,5 @@ +#include "ExtBase.h" + +char ExtBase::bar() { + return 'x'; +} Index: lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/Makefile =================================================================== --- /dev/null +++ lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/Makefile @@ -0,0 +1,3 @@ +LEVEL = ../../../make +CXX_SOURCES := main.cpp ExtBase.cpp +include $(LEVEL)/Makefile.rules Index: lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/TestDynamicCast.py =================================================================== --- /dev/null +++ lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/TestDynamicCast.py @@ -0,0 +1,3 @@ +from lldbsuite.test import lldbinline + +lldbinline.MakeInlineTest(__file__, globals(), []) Index: lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/main.cpp =================================================================== --- /dev/null +++ lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/main.cpp @@ -0,0 +1,51 @@ +class Base { +public: + virtual char foo() { + return 'b'; + } +}; + +class Derived : public Base { +public: + char foo() override { + return 'd'; + } +}; + +class NonOverrideDerived : public Base { +}; + +#include "ExtBase.h" + +class ExtDerived : public ExtBase { +public: + char bar() override { + return 'y'; + } +}; + +int main() { + Derived d; + NonOverrideDerived d2; + Base *b = &d; + Base *real_base = new Base(); + char c = dynamic_cast(b)->foo(); + + ExtDerived ext_d; + ExtBase *ext_b = &ext_d; + ExtBase *ext_real_base = new ExtBase(); + c = dynamic_cast(ext_b)->bar(); + + + return 0; //% self.expect("expression dynamic_cast(b) == (Derived*)b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(b) == (Base*)b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(real_base) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(&d) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(real_base) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(&d2) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(&d2) == (NonOverrideDerived *)&d2", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(&ext_d) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(ext_b) == (class ExtDerived*)ext_b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(ext_real_base) == (class ExtBase*)ext_real_base", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast(ext_real_base) == nullptr", substrs = ["bool", " = true"]) +} Index: lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -10,6 +10,7 @@ #include "ClangExpressionDeclMap.h" +#include "llvm/Demangle/Demangle.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InstrTypes.h" @@ -1335,6 +1336,11 @@ if (!global_variable->hasExternalLinkage()) return true; + // Typeinfo can be external. + std::string demangled = llvm::demangle(global_variable->getName()); + if (llvm::StringRef(demangled).startswith("typeinfo for ")) + return true; + if (log) LLDB_LOGF(log, "Found global variable \"%s\" without metadata", global_variable->getName().str().c_str());