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

Reply via email to