diff options
-rw-r--r-- | lldb/include/lldb/API/SBDefines.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBStream.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/API/SBType.h | 47 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ClangASTType.h | 4 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/Type.h | 50 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 13 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-forward.h | 2 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBType.i | 31 | ||||
-rw-r--r-- | lldb/source/API/SBType.cpp | 99 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTType.cpp | 18 | ||||
-rw-r--r-- | lldb/source/Symbol/Type.cpp | 62 | ||||
-rw-r--r-- | lldb/test/python_api/class_members/TestSBTypeClassMembers.py | 21 |
12 files changed, 332 insertions, 17 deletions
diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index 8f1fb0c4501..eb1d0bf4f44 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -77,6 +77,7 @@ class LLDB_API SBTypeEnumMember; class LLDB_API SBTypeEnumMemberList; class LLDB_API SBTypeFilter; class LLDB_API SBTypeFormat; +class LLDB_API SBTypeMemberFunction; class LLDB_API SBTypeNameSpecifier; class LLDB_API SBTypeSummary; #ifndef LLDB_DISABLE_PYTHON diff --git a/lldb/include/lldb/API/SBStream.h b/lldb/include/lldb/API/SBStream.h index fb69c12f0a9..07b23d166e3 100644 --- a/lldb/include/lldb/API/SBStream.h +++ b/lldb/include/lldb/API/SBStream.h @@ -87,6 +87,7 @@ protected: friend class SBThread; friend class SBType; friend class SBTypeEnumMember; + friend class SBTypeMemberFunction; friend class SBTypeMember; friend class SBValue; friend class SBWatchpoint; diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h index 9d348c88932..a10406ca6ae 100644 --- a/lldb/include/lldb/API/SBType.h +++ b/lldb/include/lldb/API/SBType.h @@ -67,6 +67,50 @@ protected: std::unique_ptr<lldb_private::TypeMemberImpl> m_opaque_ap; }; + +class SBTypeMemberFunction +{ +public: + SBTypeMemberFunction (); + + SBTypeMemberFunction (const lldb::SBTypeMemberFunction& rhs); + + ~SBTypeMemberFunction(); + + lldb::SBTypeMemberFunction& + operator = (const lldb::SBTypeMemberFunction& rhs); + + bool + IsValid() const; + + const char * + GetName (); + + lldb::SBType + GetType (); + + lldb::MemberFunctionKind + GetKind(); + + bool + GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level); + +protected: + friend class SBType; + + void + reset (lldb_private::TypeMemberFunctionImpl *); + + lldb_private::TypeMemberFunctionImpl & + ref (); + + const lldb_private::TypeMemberFunctionImpl & + ref () const; + + lldb::TypeMemberFunctionImplSP m_opaque_sp; +}; + class SBType { @@ -164,7 +208,7 @@ public: uint32_t GetNumberOfMemberFunctions (); - lldb::SBType + lldb::SBTypeMemberFunction GetMemberFunctionAtIndex (uint32_t idx); const char* @@ -215,6 +259,7 @@ protected: friend class SBTypeEnumMemberList; friend class SBTypeNameSpecifier; friend class SBTypeMember; + friend class SBTypeMemberFunction; friend class SBTypeList; friend class SBValue; diff --git a/lldb/include/lldb/Symbol/ClangASTType.h b/lldb/include/lldb/Symbol/ClangASTType.h index 3e0deda06ec..297d604b221 100644 --- a/lldb/include/lldb/Symbol/ClangASTType.h +++ b/lldb/include/lldb/Symbol/ClangASTType.h @@ -338,7 +338,9 @@ public: GetNumMemberFunctions () const; ClangASTType - GetMemberFunctionAtIndex (size_t idx); + GetMemberFunctionAtIndex (size_t idx, + std::string& name, + lldb::MemberFunctionKind& kind); ClangASTType GetLValueReferenceType () const; diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index eaa150e78ac..a2235f37225 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -810,6 +810,56 @@ private: TypePair m_type_pair; ConstString m_type_name; }; + +class TypeMemberFunctionImpl +{ +public: + TypeMemberFunctionImpl() : + m_type(), + m_name(), + m_kind(lldb::eMemberFunctionKindUnknown) + { + } + + TypeMemberFunctionImpl (const ClangASTType& type, + const std::string& name, + const lldb::MemberFunctionKind& kind) : + m_type(type), + m_name(name), + m_kind(kind) + { + } + + TypeMemberFunctionImpl (const TypeMemberFunctionImpl& rhs) : + m_type(rhs.m_type), + m_name(rhs.m_name), + m_kind(rhs.m_kind) + { + } + + TypeMemberFunctionImpl& + operator = (const TypeMemberFunctionImpl& rhs); + + bool + IsValid (); + + ConstString + GetName () const; + + ClangASTType + GetType () const; + + lldb::MemberFunctionKind + GetKind () const; + + bool + GetDescription (Stream& stream); + +private: + ClangASTType m_type; + ConstString m_name; + lldb::MemberFunctionKind m_kind; +}; class TypeEnumMemberImpl { diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index b95871cadb0..45e81b741cb 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -850,6 +850,19 @@ namespace lldb { ePathTypeLLDBTempSystemDir // The LLDB temp directory for this system that will be cleaned up on exit } PathType; + + //---------------------------------------------------------------------- + // Kind of member function + // Used by the type system + //---------------------------------------------------------------------- + typedef enum MemberFunctionKind + { + eMemberFunctionKindUnknown = 0, // Not sure what the type of this is + eMemberFunctionKindConstructor, // A function used to create instances + eMemberFunctionKindDestructor, // A function used to tear down existing instances + eMemberFunctionKindInstanceMethod, // A function that applies to a specific instance + eMemberFunctionKindStaticMethod // A function that applies to a type rather than any instance + } MemberFunctionKind; } // namespace lldb diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 9dac6f2477c..97660aaad30 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -246,6 +246,7 @@ class TypeImpl; class TypeList; class TypeListImpl; class TypeMemberImpl; +class TypeMemberFunctionImpl; class TypeEnumMemberImpl; class TypeEnumMemberListImpl; class TypeFormatImpl; @@ -390,6 +391,7 @@ namespace lldb { typedef std::weak_ptr<lldb_private::Type> TypeWP; typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP; typedef std::shared_ptr<lldb_private::TypeImpl> TypeImplSP; + typedef std::shared_ptr<lldb_private::TypeMemberFunctionImpl> TypeMemberFunctionImplSP; typedef std::shared_ptr<lldb_private::TypeEnumMemberImpl> TypeEnumMemberImplSP; typedef std::shared_ptr<lldb_private::TypeFilterImpl> TypeFilterImplSP; typedef std::shared_ptr<lldb_private::TypeFormatImpl> TypeFormatImplSP; diff --git a/lldb/scripts/Python/interface/SBType.i b/lldb/scripts/Python/interface/SBType.i index 1e45864b8c1..7daa144feb1 100644 --- a/lldb/scripts/Python/interface/SBType.i +++ b/lldb/scripts/Python/interface/SBType.i @@ -67,6 +67,35 @@ public: protected: std::unique_ptr<lldb_private::TypeMemberImpl> m_opaque_ap; }; + +class SBTypeMemberFunction +{ +public: + SBTypeMemberFunction (); + + SBTypeMemberFunction (const lldb::SBTypeMemberFunction& rhs); + + ~SBTypeMemberFunction(); + + bool + IsValid() const; + + const char * + GetName (); + + lldb::SBType + GetType (); + + lldb::MemberFunctionKind + GetKind(); + + bool + GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level); + +protected: + lldb::TypeMemberFunctionImplSP m_opaque_sp; +}; %feature("docstring", "Represents a data type in lldb. The FindFirstType() method of SBTarget/SBModule @@ -243,7 +272,7 @@ public: uint32_t GetNumberOfMemberFunctions (); - lldb::SBType + lldb::SBTypeMemberFunction GetMemberFunctionAtIndex (uint32_t idx); bool diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp index 3893312fce8..01ad368cf28 100644 --- a/lldb/source/API/SBType.cpp +++ b/lldb/source/API/SBType.cpp @@ -262,14 +262,16 @@ SBType::GetNumberOfMemberFunctions () return 0; } -lldb::SBType +lldb::SBTypeMemberFunction SBType::GetMemberFunctionAtIndex (uint32_t idx) { - SBType sb_func_type; + SBTypeMemberFunction sb_func_type; if (IsValid()) { - ClangASTType func_type(m_opaque_sp->GetClangASTType(true).GetMemberFunctionAtIndex(idx)); - sb_func_type = SBType(func_type); + lldb::MemberFunctionKind kind; + std::string name; + ClangASTType func_type(m_opaque_sp->GetClangASTType(true).GetMemberFunctionAtIndex(idx,name,kind)); + sb_func_type.reset(new TypeMemberFunctionImpl(func_type,name,kind)); } return sb_func_type; } @@ -706,3 +708,92 @@ SBTypeMember::ref () const { return *m_opaque_ap.get(); } + +SBTypeMemberFunction::SBTypeMemberFunction() : +m_opaque_sp() +{ +} + +SBTypeMemberFunction::~SBTypeMemberFunction() +{ +} + +SBTypeMemberFunction::SBTypeMemberFunction (const SBTypeMemberFunction& rhs) : + m_opaque_sp(rhs.m_opaque_sp) +{ +} + +lldb::SBTypeMemberFunction& +SBTypeMemberFunction::operator = (const lldb::SBTypeMemberFunction& rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +bool +SBTypeMemberFunction::IsValid() const +{ + return m_opaque_sp.get(); +} + +const char * +SBTypeMemberFunction::GetName () +{ + if (m_opaque_sp) + return m_opaque_sp->GetName().GetCString(); + return NULL; +} + +SBType +SBTypeMemberFunction::GetType () +{ + SBType sb_type; + if (m_opaque_sp) + { + sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType()))); + } + return sb_type; + +} + +lldb::MemberFunctionKind +SBTypeMemberFunction::GetKind () +{ + if (m_opaque_sp) + return m_opaque_sp->GetKind(); + return lldb::eMemberFunctionKindUnknown; + +} + +bool +SBTypeMemberFunction::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + Stream &strm = description.ref(); + + if (m_opaque_sp) + return m_opaque_sp->GetDescription(strm); + + return false; +} + +void +SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl) +{ + m_opaque_sp.reset(type_member_impl); +} + +TypeMemberFunctionImpl & +SBTypeMemberFunction::ref () +{ + if (!m_opaque_sp) + m_opaque_sp.reset (new TypeMemberFunctionImpl()); + return *m_opaque_sp.get(); +} + +const TypeMemberFunctionImpl & +SBTypeMemberFunction::ref () const +{ + return *m_opaque_sp.get(); +} diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index d8f6a5396ca..dce953ab048 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -1770,7 +1770,9 @@ ClangASTType::GetNumMemberFunctions () const } ClangASTType -ClangASTType::GetMemberFunctionAtIndex (size_t idx) +ClangASTType::GetMemberFunctionAtIndex (size_t idx, + std::string& name, + lldb::MemberFunctionKind& kind) { if (IsValid()) { @@ -1792,7 +1794,21 @@ ClangASTType::GetMemberFunctionAtIndex (size_t idx) std::advance(method_iter, idx); auto method_decl = method_iter->getCanonicalDecl(); if (method_decl) + { + if (!method_decl->getName().empty()) + name.assign(method_decl->getName().data()); + else + name.clear(); + if (method_decl->isStatic()) + kind = lldb::eMemberFunctionKindStaticMethod; + else if (llvm::isa<clang::CXXConstructorDecl>(method_decl)) + kind = lldb::eMemberFunctionKindConstructor; + else if (llvm::isa<clang::CXXDestructorDecl>(method_decl)) + kind = lldb::eMemberFunctionKindDestructor; + else + kind = lldb::eMemberFunctionKindInstanceMethod; return ClangASTType(m_ast,method_decl->getType().getAsOpaquePtr()); + } } } } diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 4eb538fb135..f89d1a78328 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -1291,6 +1291,68 @@ TypeImpl::GetDescription (lldb_private::Stream &strm, return true; } +TypeMemberFunctionImpl& +TypeMemberFunctionImpl::operator = (const TypeMemberFunctionImpl& rhs) +{ + if (this != &rhs) + { + m_type = rhs.m_type; + m_name = rhs.m_name; + m_kind = rhs.m_kind; + } + return *this; +} + +bool +TypeMemberFunctionImpl::IsValid () +{ + return m_type.IsValid() && m_kind != lldb::eMemberFunctionKindUnknown; +} + +ConstString +TypeMemberFunctionImpl::GetName () const +{ + return m_name; +} + +ClangASTType +TypeMemberFunctionImpl::GetType () const +{ + return m_type; +} + +lldb::MemberFunctionKind +TypeMemberFunctionImpl::GetKind () const +{ + return m_kind; +} + +bool +TypeMemberFunctionImpl::GetDescription (Stream& stream) +{ + switch (m_kind) { + case lldb::eMemberFunctionKindUnknown: + return false; + case lldb::eMemberFunctionKindConstructor: + stream.Printf("constructor for %s", m_type.GetTypeName().AsCString()); + break; + case lldb::eMemberFunctionKindDestructor: + stream.Printf("destructor for %s", m_type.GetTypeName().AsCString()); + break; + case lldb::eMemberFunctionKindInstanceMethod: + stream.Printf("instance method %s of type %s", + m_name.AsCString(), + m_type.GetTypeName().AsCString()); + break; + case lldb::eMemberFunctionKindStaticMethod: + stream.Printf("static method %s of type %s", + m_name.AsCString(), + m_type.GetTypeName().AsCString()); + break; + } + return true; +} + TypeEnumMemberImpl::TypeEnumMemberImpl (const clang::EnumConstantDecl* enum_member_decl, const lldb_private::ClangASTType& integer_type) : m_integer_type_sp(), diff --git a/lldb/test/python_api/class_members/TestSBTypeClassMembers.py b/lldb/test/python_api/class_members/TestSBTypeClassMembers.py index e286df9d57a..f60b58ec956 100644 --- a/lldb/test/python_api/class_members/TestSBTypeClassMembers.py +++ b/lldb/test/python_api/class_members/TestSBTypeClassMembers.py @@ -1,5 +1,5 @@ """ -Test SBType and SBTypeList API. +Test SBType APIs to fetch member function types. """ import os, time @@ -8,7 +8,7 @@ import unittest2 import lldb, lldbutil from lldbtest import * -class TypeAndTypeListTestCase(TestBase): +class SBTypeMemberFunctionsTest(TestBase): mydir = TestBase.compute_mydir(__file__) @@ -16,7 +16,7 @@ class TypeAndTypeListTestCase(TestBase): @python_api_test @dsym_test def test_with_dsym(self): - """Exercise SBType and SBTypeList API.""" + """Test SBType APIs to fetch member function types.""" d = {'EXE': self.exe_name} self.buildDsym(dictionary=d) self.setTearDownCleanup(dictionary=d) @@ -25,7 +25,7 @@ class TypeAndTypeListTestCase(TestBase): @python_api_test @dwarf_test def test_with_dwarf(self): - """Exercise SBType and SBTypeList API.""" + """Test SBType APIs to fetch member function types.""" d = {'EXE': self.exe_name} self.buildDwarf(dictionary=d) self.setTearDownCleanup(dictionary=d) @@ -41,7 +41,7 @@ class TypeAndTypeListTestCase(TestBase): self.line = line_number(self.source, '// set breakpoint here') def type_api(self, exe_name): - """Exercise SBType and SBTypeList API.""" + """Test SBType APIs to fetch member function types.""" exe = os.path.join(os.getcwd(), exe_name) # Create a target by the debugger. @@ -67,12 +67,15 @@ class TypeAndTypeListTestCase(TestBase): Base = Derived.GetDirectBaseClassAtIndex(0).GetType() self.assertTrue(Derived.GetNumberOfMemberFunctions() == 2, "Derived declares two methods") - self.assertTrue(Derived.GetMemberFunctionAtIndex(0).GetFunctionReturnType().GetName() == "int", "Derived::dImpl returns int") + self.assertTrue(Derived.GetMemberFunctionAtIndex(0).GetType().GetFunctionReturnType().GetName() == "int", "Derived::dImpl returns int") self.assertTrue(Base.GetNumberOfMemberFunctions() == 4, "Base declares three methods") - self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetFunctionArgumentTypes().GetSize() == 3, "Base::sfunc takes three arguments") - self.assertTrue(Base.GetMemberFunctionAtIndex(2).GetFunctionArgumentTypes().GetSize() == 0, "Base::dat takes no arguments") - self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetFunctionArgumentTypes().GetTypeAtIndex(1).GetName() == "char", "Base::bar takes a second 'char' argument") + self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetType().GetFunctionArgumentTypes().GetSize() == 3, "Base::sfunc takes three arguments") + self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetName() == "sfunc", "Base::sfunc not found") + self.assertTrue(Base.GetMemberFunctionAtIndex(3).GetKind() == lldb.eMemberFunctionKindStaticMethod, "Base::sfunc is a static") + self.assertTrue(Base.GetMemberFunctionAtIndex(2).GetType().GetFunctionArgumentTypes().GetSize() == 0, "Base::dat takes no arguments") + self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetType().GetFunctionArgumentTypes().GetTypeAtIndex(1).GetName() == "char", "Base::bar takes a second 'char' argument") + self.assertTrue(Base.GetMemberFunctionAtIndex(1).GetName() == "bar", "Base::bar not found") if __name__ == '__main__': import atexit |