shafik updated this revision to Diff 197426.
shafik marked 9 inline comments as done.
shafik added a comment.

Changed to reflect comments.

- Added comments to test to explain what it is doing.
- Formatting and other minor fixes.


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

https://reviews.llvm.org/D61146

Files:
  
packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/Makefile
  
packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/TestArgumentPassingRestrictions.py
  
packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/main.cpp
  packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -959,6 +959,14 @@
           }
         }
 
+        if (calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
+          clang::CXXRecordDecl *record_decl =
+              m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+          if (record_decl)
+            record_decl->setArgPassingRestrictions(
+                clang::RecordDecl::APK_CannotPassInRegs);
+        }
+
       } break;
 
       case DW_TAG_enumeration_type: {
Index: packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py
===================================================================
--- packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py
+++ /dev/null
@@ -1,125 +0,0 @@
-"""Show global variables and check that they do indeed have global scopes."""
-
-from __future__ import print_function
-
-
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class GlobalVariablesTestCase(TestBase):
-
-    mydir = TestBase.compute_mydir(__file__)
-
-    def setUp(self):
-        # Call super's setUp().
-        TestBase.setUp(self)
-        # Find the line number to break inside main().
-        self.source = 'main.c'
-        self.line = line_number(
-            self.source, '// Set break point at this line.')
-        self.shlib_names = ["a"]
-
-    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
-    @expectedFailureAll(oslist=["linux"], archs=["aarch64"], bugnumber="llvm.org/pr37301")
-    def test_without_process(self):
-        """Test that static initialized variables can be inspected without
-        process."""
-        self.build()
-
-        # Create a target by the debugger.
-        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
-
-        self.assertTrue(target, VALID_TARGET)
-        self.expect("target variable g_ptr", VARIABLES_DISPLAYED_CORRECTLY,
-                    substrs=['(int *)'])
-        self.expect("target variable *g_ptr", VARIABLES_DISPLAYED_CORRECTLY,
-                    substrs=['42'])
-
-    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764")
-    @expectedFailureNetBSD
-    def test_c_global_variables(self):
-        """Test 'frame variable --scope --no-args' which omits args and shows scopes."""
-        self.build()
-
-        # Create a target by the debugger.
-        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
-        self.assertTrue(target, VALID_TARGET)
-
-        # Break inside the main.
-        lldbutil.run_break_set_by_file_and_line(
-            self, self.source, self.line, num_expected_locations=1, loc_exact=True)
-
-        # Register our shared libraries for remote targets so they get
-        # automatically uploaded
-        environment = self.registerSharedLibrariesWithTarget(
-            target, self.shlib_names)
-
-        # Now launch the process, and do not stop at entry point.
-        process = target.LaunchSimple(
-            None, environment, self.get_process_working_directory())
-        self.assertTrue(process, PROCESS_IS_VALID)
-
-        # The stop reason of the thread should be breakpoint.
-        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
-                    substrs=['stopped',
-                             'stop reason = breakpoint'])
-
-        # The breakpoint should have a hit count of 1.
-        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
-                    substrs=[' resolved, hit count = 1'])
-
-        # Test that the statically initialized variable can also be
-        # inspected *with* a process.
-        self.expect("target variable g_ptr", VARIABLES_DISPLAYED_CORRECTLY,
-                    substrs=['(int *)'])
-        self.expect("target variable *g_ptr", VARIABLES_DISPLAYED_CORRECTLY,
-                    substrs=['42'])
-
-        # Check that GLOBAL scopes are indicated for the variables.
-        self.expect(
-            "frame variable --show-types --scope --show-globals --no-args",
-            VARIABLES_DISPLAYED_CORRECTLY,
-            substrs=[
-                'STATIC: (const int) g_file_static_int = 2',
-                'STATIC: (const char *) g_func_static_cstr',
-                'GLOBAL: (const char *) g_file_global_cstr',
-                '"g_file_global_cstr"',
-                'GLOBAL: (int) g_file_global_int = 42',
-                'GLOBAL: (int) g_common_1 = 21',
-                'GLOBAL: (int *) g_ptr',
-                'STATIC: (const char *) g_file_static_cstr',
-                '"g_file_static_cstr"'
-            ])
-
-        # 'frame variable' should support address-of operator.
-        self.runCmd("frame variable &g_file_global_int")
-
-        # Exercise the 'target variable' command to display globals in a.c
-        # file.
-        self.expect("target variable g_a", VARIABLES_DISPLAYED_CORRECTLY,
-                    substrs=['g_a', '123'])
-        self.expect(
-            "target variable g_marked_spot.x",
-            VARIABLES_DISPLAYED_CORRECTLY,
-            substrs=[
-                'g_marked_spot.x',
-                '20'])
-
-        # rdar://problem/9747668
-        # runCmd: target variable g_marked_spot.y
-        # output: (int) g_marked_spot.y = <a.o[0x214] can't be resolved,  in not currently loaded.
-        #         >
-        self.expect(
-            "target variable g_marked_spot.y",
-            VARIABLES_DISPLAYED_CORRECTLY,
-            substrs=[
-                'g_marked_spot.y',
-                '21'])
-        self.expect(
-            "target variable g_marked_spot.y",
-            VARIABLES_DISPLAYED_CORRECTLY,
-            matching=False,
-            substrs=["can't be resolved"])
-
Index: packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/main.cpp
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/main.cpp
@@ -0,0 +1,54 @@
+// Bounds should be pass by reference since the copy constructor is user-defined
+// which means it can not be passed in registers.
+// Full logic in canPassInRegisters(...) in SemaDeclCXX.cpp
+struct Bounds {
+  Bounds() = default;
+  Bounds(const Bounds &b);
+
+  int x;
+};
+
+Bounds::Bounds(const Bounds &b) : x(b.x) {}
+
+class Shape {
+  // Original reproducer was using 0x1 as a value for the pointer
+  // and casting it to Shape*. This invokes undefined behavior
+  // so went with a static instance.
+  static Shape *sp;
+
+public:
+  static Shape *empty_shape() { return sp; }
+
+  // Because this reproducer involes a mixing up of the register
+  // containing the this pointer. We need an expression that will
+  // be always true in the good case but always false for any other
+  // pointer.
+  bool check() const { return this == sp; }
+
+  void get_bounds(Bounds &bounds) const {
+    // If while parsing dwarf for Bounds we don't set APK_CannotPassInRegs
+    // the register containing the this pointer will be mixed up and the
+    // call to check() will return false which leaves x and y
+    // unintialized.
+    if (check()) {
+      bounds.x = 11223344;
+    }
+  }
+
+  Bounds bounds() const {
+    Bounds b;
+    // How b is passed is effected by whether we set APK_CannotPassInRegs
+    // correctly for Bounds.
+    get_bounds(b);
+    return b;
+  }
+};
+
+Shape shape;
+Shape *Shape::sp = &shape;
+
+int main() {
+  Shape s;
+
+  return Shape::empty_shape()->bounds().x; // break here
+}
Index: packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/TestArgumentPassingRestrictions.py
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/TestArgumentPassingRestrictions.py
@@ -0,0 +1,29 @@
+"""
+This is a test to ensure that both lldb is reconstructing the right
+calling convention for a CXXRecordDecl as represented by:
+
+   DW_CC_pass_by_reference
+   DW_CC_pass_by_value
+
+and to also make sure that the ASTImporter is copying over this
+setting when importing the CXXRecordDecl via setArgPassingRestrictions.
+"""
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestArgumentPassingRestrictions(TestBase):
+
+  mydir = TestBase.compute_mydir(__file__)
+
+  def test_argument_passing_restrictions(self):
+    self.build()
+
+    lldbutil.run_to_source_breakpoint(self, '// break here',
+            lldb.SBFileSpec("main.cpp"))
+
+    self.expect("expr Shape::empty_shape()->bounds()",
+            substrs=['(Bounds)', 'x = 11223344'])
Index: packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/Makefile
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/expression_command/argument_passing_restrictions/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to