aprantl updated this revision to Diff 197871.
aprantl added a comment.

Thanks you! There was indeed a bug that prevented us from recognizing the 
correct runtime for the C++ `this` pointer.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61451/new/

https://reviews.llvm.org/D61451

Files:
  lldb/include/lldb/Target/CPPLanguageRuntime.h
  lldb/include/lldb/Target/LanguageRuntime.h
  lldb/include/lldb/Target/ObjCLanguageRuntime.h
  lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py
  lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/Makefile
  
lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/TestObjCXXHideRuntimeValues.py
  lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/main.mm
  lldb/source/Symbol/ClangASTContext.cpp
  lldb/source/Target/CPPLanguageRuntime.cpp
  lldb/source/Target/ObjCLanguageRuntime.cpp

Index: lldb/source/Target/ObjCLanguageRuntime.cpp
===================================================================
--- lldb/source/Target/ObjCLanguageRuntime.cpp
+++ lldb/source/Target/ObjCLanguageRuntime.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Symbol/TypeList.h"
+#include "lldb/Symbol/Variable.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/Log.h"
@@ -37,6 +38,25 @@
       m_isa_to_descriptor_stop_id(UINT32_MAX), m_complete_class_cache(),
       m_negative_complete_class_cache() {}
 
+bool ObjCLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) {
+  static ConstString g_self = ConstString("self");
+  static ConstString g_cmd = ConstString("_cmd");
+  return name == g_self || name == g_cmd;
+}
+
+bool ObjCLanguageRuntime::IsRuntimeSupportValue(ValueObject &valobj) {
+  // All runtime support values have to be marked as artificial by the
+  // compiler. But not all artificial variables should be hidden from
+  // the user.
+  if (!valobj.GetVariable())
+    return false;
+  if (!valobj.GetVariable()->IsArtificial())
+    return false;
+
+  // Whitelist "self" and "_cmd".
+  return !IsWhitelistedRuntimeValue(valobj.GetName());
+}
+
 bool ObjCLanguageRuntime::AddClass(ObjCISA isa,
                                    const ClassDescriptorSP &descriptor_sp,
                                    const char *class_name) {
Index: lldb/source/Target/CPPLanguageRuntime.cpp
===================================================================
--- lldb/source/Target/CPPLanguageRuntime.cpp
+++ lldb/source/Target/CPPLanguageRuntime.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Target/CPPLanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
 
 #include <string.h>
 
@@ -15,6 +16,7 @@
 #include "llvm/ADT/StringRef.h"
 
 #include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/Variable.h"
 #include "lldb/Symbol/VariableList.h"
 
 #include "lldb/Core/PluginManager.h"
@@ -31,12 +33,30 @@
 using namespace lldb;
 using namespace lldb_private;
 
+static ConstString g_this = ConstString("this");
+
 // Destructor
 CPPLanguageRuntime::~CPPLanguageRuntime() {}
 
 CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
     : LanguageRuntime(process) {}
 
+bool CPPLanguageRuntime::IsRuntimeSupportValue(ValueObject &valobj) {
+  // All runtime support values have to be marked as artificial by the
+  // compiler. But not all artificial variables should be hidden from
+  // the user.
+  if (!valobj.GetVariable())
+    return false;
+  if (!valobj.GetVariable()->IsArtificial())
+    return false;
+
+  // Whitelist "this" and since there is no ObjC++ runtime, any ObjC names.
+  ConstString name = valobj.GetName();
+  if (name == g_this)
+    return false;
+  return !ObjCLanguageRuntime::IsWhitelistedRuntimeValue(name);
+}
+
 bool CPPLanguageRuntime::GetObjectDescription(Stream &str,
                                               ValueObject &object) {
   // C++ has no generic way to do this.
@@ -317,7 +337,7 @@
   StackFrameSP frame = thread.GetStackFrameAtIndex(0);
 
   if (frame) {
-    ValueObjectSP value_sp = frame->FindVariable(ConstString("this"));
+    ValueObjectSP value_sp = frame->FindVariable(g_this);
 
     CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info =
         FindLibCppStdFunctionCallableInfo(value_sp);
Index: lldb/source/Symbol/ClangASTContext.cpp
===================================================================
--- lldb/source/Symbol/ClangASTContext.cpp
+++ lldb/source/Symbol/ClangASTContext.cpp
@@ -4257,9 +4257,11 @@
   if (qual_type->isAnyPointerType()) {
     if (qual_type->isObjCObjectPointerType())
       return lldb::eLanguageTypeObjC;
+    if (qual_type->getPointeeCXXRecordDecl())
+      return lldb::eLanguageTypeC_plus_plus;
 
     clang::QualType pointee_type(qual_type->getPointeeType());
-    if (pointee_type->getPointeeCXXRecordDecl() != nullptr)
+    if (pointee_type->getPointeeCXXRecordDecl())
       return lldb::eLanguageTypeC_plus_plus;
     if (pointee_type->isObjCObjectOrInterfaceType())
       return lldb::eLanguageTypeObjC;
Index: lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/main.mm
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/main.mm
@@ -0,0 +1,28 @@
+#import <Foundation/Foundation.h>
+
+void baz() {}
+
+struct MyClass {
+  void bar() {
+    baz(); // break here
+  }
+};
+
+@interface MyObject : NSObject {}
+- (void)foo;
+@end
+
+@implementation MyObject
+- (void)foo {
+  MyClass c;
+  c.bar(); // break here
+}
+@end
+
+int main (int argc, char const *argv[]) {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    id obj = [MyObject new];
+    [obj foo];
+    [pool release];
+    return 0;
+}
Index: lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/TestObjCXXHideRuntimeValues.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/TestObjCXXHideRuntimeValues.py
@@ -0,0 +1,47 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import os
+import unittest2
+
+
+class TestObjCXXHideRuntimeSupportValues(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def setUp(self):
+        TestBase.setUp(self)
+
+    def test_hide_runtime_support_values(self):
+        self.build()
+        _, process, _, _ = lldbutil.run_to_source_breakpoint(
+            self, 'break here', lldb.SBFileSpec('main.mm'))
+
+        var_opts = lldb.SBVariablesOptions()
+        var_opts.SetIncludeArguments(True)
+        var_opts.SetIncludeLocals(True)
+        var_opts.SetInScopeOnly(True)
+        var_opts.SetIncludeStatics(False)
+        var_opts.SetIncludeRuntimeSupportValues(False)
+        var_opts.SetUseDynamic(lldb.eDynamicCanRunTarget)
+        values = self.frame().GetVariables(var_opts)
+
+        def shows_var(name):
+            for value in values:
+                if value.name == name:
+                    return True
+            return False
+        # ObjC method.
+        values = self.frame().GetVariables(var_opts)
+        self.assertFalse(shows_var("this"))
+        self.assertTrue(shows_var("self"))
+        self.assertTrue(shows_var("_cmd"))
+        self.assertTrue(shows_var("c"))
+
+        process.Continue()
+        # C++ method.
+        values = self.frame().GetVariables(var_opts)
+        self.assertTrue(shows_var("this"))
+        self.assertFalse(shows_var("self"))
+        self.assertFalse(shows_var("_cmd"))
Index: lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/Makefile
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+OBJCXX_SOURCES := main.mm
+LDFLAGS = $(CFLAGS) -lobjc -framework Foundation
+
+include $(LEVEL)/Makefile.rules
Index: lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py
+++ lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py
@@ -14,12 +14,23 @@
         _, process, _, _ = lldbutil.run_to_source_breakpoint(
             self, "break here", lldb.SBFileSpec('main.c'))
 
+        # Make sure no helper expressions show up in frame variable.
+        var_opts = lldb.SBVariablesOptions()
+        var_opts.SetIncludeArguments(False)
+        var_opts.SetIncludeLocals(True)
+        var_opts.SetInScopeOnly(True)
+        var_opts.SetIncludeStatics(False)
+        var_opts.SetIncludeRuntimeSupportValues(False)
+        var_opts.SetUseDynamic(lldb.eDynamicCanRunTarget)
+        all_locals = self.frame().GetVariables(var_opts)
+        self.assertEqual(len(all_locals), 1)
+
         def test(a, array):
             for i in range(a):
                 self.expect("fr v vla[%d]"%i, substrs=["int", "%d"%(a-i)])
                 self.expect("expr vla[%d]"%i, substrs=["int", "%d"%(a-i)])
-            self.expect("frame var vla", substrs=array)
-            self.expect("expr      vla", error=True, substrs=["incomplete"])
+            self.expect("fr v vla", substrs=array)
+            self.expect("expr vla", error=True, substrs=["incomplete"])
 
         test(2, ["int []", "[0] = 2, [1] = 1"])
         process.Continue()
Index: lldb/include/lldb/Target/ObjCLanguageRuntime.h
===================================================================
--- lldb/include/lldb/Target/ObjCLanguageRuntime.h
+++ lldb/include/lldb/Target/ObjCLanguageRuntime.h
@@ -292,6 +292,11 @@
   bool GetTypeBitSize(const CompilerType &compiler_type,
                       uint64_t &size) override;
 
+  /// Check whether the name is "self" or "_cmd" and should show up in
+  /// "frame variable".
+  static bool IsWhitelistedRuntimeValue(ConstString name);
+  bool IsRuntimeSupportValue(ValueObject &valobj) override;
+
 protected:
   // Classes that inherit from ObjCLanguageRuntime can see and modify these
   ObjCLanguageRuntime(Process *process);
Index: lldb/include/lldb/Target/LanguageRuntime.h
===================================================================
--- lldb/include/lldb/Target/LanguageRuntime.h
+++ lldb/include/lldb/Target/LanguageRuntime.h
@@ -143,6 +143,8 @@
     return false;
   }
 
+  /// Identify whether a value is a language implementation detaul
+  /// that should be hidden from the user interface by default.
   virtual bool IsRuntimeSupportValue(ValueObject &valobj) { return false; }
 
   virtual void ModulesDidLoad(const ModuleList &module_list) {}
Index: lldb/include/lldb/Target/CPPLanguageRuntime.h
===================================================================
--- lldb/include/lldb/Target/CPPLanguageRuntime.h
+++ lldb/include/lldb/Target/CPPLanguageRuntime.h
@@ -63,6 +63,7 @@
   lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
                                                   bool stop_others);
 
+  bool IsRuntimeSupportValue(ValueObject &valobj) override;
 protected:
   // Classes that inherit from CPPLanguageRuntime can see and modify these
   CPPLanguageRuntime(Process *process);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to