diff options
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test')
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 +} |