summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test')
-rw-r--r--lldb/packages/Python/lldbsuite/test/decorators.py13
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py75
-rw-r--r--lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/main.cpp35
4 files changed, 128 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py
index 72c2ed71c70..228a8bd390e 100644
--- a/lldb/packages/Python/lldbsuite/test/decorators.py
+++ b/lldb/packages/Python/lldbsuite/test/decorators.py
@@ -652,6 +652,19 @@ def skipIfTargetAndroid(api_levels=None, archs=None):
api_levels,
archs))
+def skipUnlessSupportedTypeAttribute(attr):
+ """Decorate the item to skip test unless Clang supports type __attribute__(attr)."""
+ def compiler_doesnt_support_struct_attribute(self):
+ compiler_path = self.getCompiler()
+ compiler = os.path.basename(compiler_path)
+ f = tempfile.NamedTemporaryFile()
+ cmd = "echo 'struct __attribute__((%s)) Test {};' | %s -x c++ -c -o %s - ; exit" % (attr, compiler_path, f.name)
+ p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
+ test_result = p.stderr.read()
+ if attr in test_result:
+ return "Compiler does not support attribute %s"%(attr)
+ return None
+ return skipTestIfFn(compiler_doesnt_support_struct_attribute)
def skipUnlessThreadSanitizer(func):
"""Decorate the item to skip test unless Clang -fsanitize=thread is supported."""
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/Makefile b/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/Makefile
new file mode 100644
index 00000000000..314f1cb2f07
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py b/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py
new file mode 100644
index 00000000000..34ab00e1dc8
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py
@@ -0,0 +1,75 @@
+"""
+Test that we work properly with classes with the trivial_abi attribute
+"""
+
+from __future__ import print_function
+
+
+import os
+import time
+import re
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import decorators
+
+class TestTrivialABI(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ @decorators.skipUnlessSupportedTypeAttribute("trivial_abi")
+ def test_call_trivial(self):
+ """Test that we can print a variable & call a function with a trivial ABI class."""
+ self.build()
+ self.main_source_file = lldb.SBFileSpec("main.cpp")
+ self.expr_test(True)
+
+ @decorators.skipUnlessSupportedTypeAttribute("trivial_abi")
+ @decorators.expectedFailureAll(bugnumber="llvm.org/pr36870")
+ def test_call_nontrivial(self):
+ """Test that we can print a variable & call a function on the same class w/o the trivial ABI marker."""
+ self.build()
+ self.main_source_file = lldb.SBFileSpec("main.cpp")
+ self.expr_test(False)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def check_value(self, test_var, ivar_value):
+ self.assertTrue(test_var.GetError().Success(), "Invalid valobj: %s"%(test_var.GetError().GetCString()))
+ ivar = test_var.GetChildMemberWithName("ivar")
+ self.assertTrue(test_var.GetError().Success(), "Failed to fetch ivar")
+ self.assertEqual(ivar_value, ivar.GetValueAsSigned(), "Got the right value for ivar")
+
+ def check_frame(self, thread):
+ frame = thread.frames[0]
+ inVal_var = frame.FindVariable("inVal")
+ self.check_value(inVal_var, 10)
+
+ options = lldb.SBExpressionOptions()
+ inVal_expr = frame.EvaluateExpression("inVal", options)
+ self.check_value(inVal_expr, 10)
+
+ thread.StepOut()
+ outVal_ret = thread.GetStopReturnValue()
+ self.check_value(outVal_ret, 30)
+
+ def expr_test(self, trivial):
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
+ "Set a breakpoint here", self.main_source_file)
+
+ # Stop in a function that takes a trivial value, and try both frame var & expr to get its value:
+ if trivial:
+ self.check_frame(thread)
+ return
+
+ # Now continue to the same thing without the trivial_abi and see if we get that right:
+ threads = lldbutil.continue_to_breakpoint(process, bkpt)
+ self.assertEqual(len(threads), 1, "Hit my breakpoint the second time.")
+
+ self.check_frame(threads[0])
+
+
diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/main.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/main.cpp
new file mode 100644
index 00000000000..cdf593e8b40
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/main.cpp
@@ -0,0 +1,35 @@
+struct __attribute__((trivial_abi)) S_Trivial {
+ ~S_Trivial() {}
+ int ivar = 10;
+};
+
+S_Trivial takeTrivial(S_Trivial inVal)
+{
+ S_Trivial ret_val = inVal;
+ ret_val.ivar = 30;
+ return ret_val; // Set a breakpoint here
+}
+
+struct S_NotTrivial {
+ ~S_NotTrivial() {}
+ int ivar = 10;
+};
+
+S_NotTrivial takeNotTrivial(S_NotTrivial inVal)
+{
+ S_NotTrivial ret_val = inVal;
+ ret_val.ivar = 30;
+ return ret_val; // Set a breakpoint here
+}
+
+int
+main()
+{
+ S_Trivial inVal, outVal;
+ outVal = takeTrivial(inVal);
+
+ S_NotTrivial inNotVal, outNotVal;
+ outNotVal = takeNotTrivial(outNotVal);
+
+ return 0; // Set another for return value
+}
OpenPOWER on IntegriCloud