diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/lang/cpp/template')
3 files changed, 166 insertions, 0 deletions
| diff --git a/packages/Python/lldbsuite/test/lang/cpp/template/Makefile b/packages/Python/lldbsuite/test/lang/cpp/template/Makefile new file mode 100644 index 000000000000..194af7b32398 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/template/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../make + +CXX_SOURCES := main.cpp + +CFLAGS_EXTRAS += $(NO_LIMIT_DEBUG_INFO_FLAGS) + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py b/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py new file mode 100644 index 000000000000..e08d3a10786c --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py @@ -0,0 +1,87 @@ +""" +Test that C++ template classes that have integer parameters work correctly. + +We must reconstruct the types correctly so the template types are correct  +and display correctly, and also make sure the expression parser works and +is able the find all needed functions when evaluating expressions +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TemplateArgsTestCase(TestBase): +     +    mydir = TestBase.compute_mydir(__file__) +     +    def prepareProcess(self): +        self.build() + +        # Create a target by the debugger. +        exe = os.path.join(os.getcwd(), "a.out") +        target = self.dbg.CreateTarget(exe) +        self.assertTrue(target, VALID_TARGET) + +        # Set breakpoints inside and outside methods that take pointers to the containing struct. +        line = line_number('main.cpp', '// Breakpoint 1') +        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", line, num_expected_locations=1, loc_exact=True) + +        arguments = None +        environment = None  + +        # Now launch the process, and do not stop at entry point. +        process = target.LaunchSimple (arguments, environment, self.get_process_working_directory()) +        self.assertTrue(process, PROCESS_IS_VALID) +  +        # Get the thread of the process +        self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED) +        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) + +        # Get frame for current thread +        return thread.GetSelectedFrame() + +    def test_integer_args(self): +        frame = self.prepareProcess() +         +        testpos = frame.FindVariable('testpos')  +        self.assertTrue(testpos.IsValid(), 'make sure we find a local variabble named "testpos"') +        self.assertTrue(testpos.GetType().GetName() == 'TestObj<1>') +         +        expr_result = frame.EvaluateExpression("testpos.getArg()") +        self.assertTrue(expr_result.IsValid(), 'got a valid expression result from expression "testpos.getArg()"'); +        self.assertTrue(expr_result.GetValue() == "1", "testpos.getArg() == 1") +        self.assertTrue(expr_result.GetType().GetName() == "int", 'expr_result.GetType().GetName() == "int"')      +         +        testneg = frame.FindVariable('testneg')  +        self.assertTrue(testneg.IsValid(), 'make sure we find a local variabble named "testneg"') +        self.assertTrue(testneg.GetType().GetName() == 'TestObj<-1>')         +         +        expr_result = frame.EvaluateExpression("testneg.getArg()") +        self.assertTrue(expr_result.IsValid(), 'got a valid expression result from expression "testneg.getArg()"'); +        self.assertTrue(expr_result.GetValue() == "-1", "testneg.getArg() == -1") +        self.assertTrue(expr_result.GetType().GetName() == "int", 'expr_result.GetType().GetName() == "int"') + +    # Gcc does not generate the necessary DWARF attribute for enum template parameters. +    @expectedFailureAll(bugnumber="llvm.org/pr28354", compiler="gcc") +    def test_enum_args(self): +        frame = self.prepareProcess() + +        # Make sure "member" can be displayed and also used in an expression correctly +        member = frame.FindVariable('member')  +        self.assertTrue(member.IsValid(), 'make sure we find a local variabble named "member"') +        self.assertTrue(member.GetType().GetName() == 'EnumTemplate<EnumType::Member>') +         +        expr_result = frame.EvaluateExpression("member.getMember()") +        self.assertTrue(expr_result.IsValid(), 'got a valid expression result from expression "member.getMember()"'); +        self.assertTrue(expr_result.GetValue() == "123", "member.getMember() == 123") +        self.assertTrue(expr_result.GetType().GetName() == "int", 'expr_result.GetType().GetName() == "int"')      + +        # Make sure "subclass" can be displayed and also used in an expression correctly +        subclass = frame.FindVariable('subclass')  +        self.assertTrue(subclass.IsValid(), 'make sure we find a local variabble named "subclass"') +        self.assertTrue(subclass.GetType().GetName() == 'EnumTemplate<EnumType::Subclass>') +         +        expr_result = frame.EvaluateExpression("subclass.getMember()") +        self.assertTrue(expr_result.IsValid(), 'got a valid expression result from expression "subclass.getMember()"'); +        self.assertTrue(expr_result.GetValue() == "246", "subclass.getMember() == 246") +        self.assertTrue(expr_result.GetType().GetName() == "int", 'expr_result.GetType().GetName() == "int"')      diff --git a/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp new file mode 100644 index 000000000000..9c33a6420912 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp @@ -0,0 +1,72 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +template <int Arg> +class TestObj +{ +public: +  int getArg() +  { +    return Arg; +  } +}; + +//---------------------------------------------------------------------- +// Define a template class that we can specialize with an enumeration +//---------------------------------------------------------------------- +enum class EnumType +{ +    Member, +    Subclass +}; + +template <EnumType Arg> class EnumTemplate; +                                           +//---------------------------------------------------------------------- +// Specialization for use when "Arg" is "EnumType::Member" +//---------------------------------------------------------------------- +template <> +class EnumTemplate<EnumType::Member>  +{ +public: +    EnumTemplate(int m) : +        m_member(m) +    { +    } + +    int getMember() const +    { +        return m_member; +    } + +protected: +    int m_member; +}; + +//---------------------------------------------------------------------- +// Specialization for use when "Arg" is "EnumType::Subclass" +//---------------------------------------------------------------------- +template <> +class EnumTemplate<EnumType::Subclass> :  +    public EnumTemplate<EnumType::Member>  +{ +public: +    EnumTemplate(int m) : EnumTemplate<EnumType::Member>(m) +    { +    }     +}; + +int main(int argc, char **argv) +{ +  TestObj<1> testpos; +  TestObj<-1> testneg; +  EnumTemplate<EnumType::Member> member(123); +  EnumTemplate<EnumType::Subclass> subclass(123*2); +  return testpos.getArg() - testneg.getArg() + member.getMember()*2 - subclass.getMember(); // Breakpoint 1 +} | 
