teemperor created this revision. teemperor added a reviewer: davide. Herald added subscribers: lldb-commits, abidh. Herald added a project: LLDB.
Our IR rewriting infrastructure currently treats type info pointers ('@_ZTI...') as variables it needs to rewrite. This isn't necessary as we don't need to have the type info (and often shouldn't) in the same module as our expression. This patch filters out these errors when resolving variables by checking if they are for type information. Note that we only do the demangling and checking work in cases where we threw an error before, so this doesn't have any performance impact on other expressions. This patch should fix dynamic_cast and also adds a bunch of test coverage to that language feature. Fixes rdar://10813639 Repository: rLLDB LLDB https://reviews.llvm.org/D65932 Files: lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.cpp lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/ExtBase.h lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/Makefile lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/TestDynamicCast.py lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic_cast/main.cpp lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
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()); 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<Derived *>(b)->foo(); + + ExtDerived ext_d; + ExtBase *ext_b = &ext_d; + ExtBase *ext_real_base = new ExtBase(); + c = dynamic_cast<ExtDerived *>(ext_b)->bar(); + + + return 0; //% self.expect("expression dynamic_cast<class Derived *>(b) == (Derived*)b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class Base *>(b) == (Base*)b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class Derived *>(real_base) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class NonOverrideDerived *>(&d) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class ExtDerived *>(real_base) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class Derived *>(&d2) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class NonOverrideDerived *>(&d2) == (NonOverrideDerived *)&d2", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class Derived *>(&ext_d) == nullptr", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class ExtDerived *>(ext_b) == (class ExtDerived*)ext_b", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class ExtBase *>(ext_real_base) == (class ExtBase*)ext_real_base", substrs = ["bool", " = true"]) + //% self.expect("expression dynamic_cast<class ExtDerived *>(ext_real_base) == nullptr", substrs = ["bool", " = true"]) +} 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/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/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'; +}
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits