diff options
| -rw-r--r-- | lldb/include/lldb/API/SBType.h | 9 | ||||
| -rw-r--r-- | lldb/include/lldb/Symbol/ClangASTType.h | 10 | ||||
| -rw-r--r-- | lldb/include/lldb/Symbol/Type.h | 27 | ||||
| -rw-r--r-- | lldb/scripts/Python/interface/SBType.i | 9 | ||||
| -rw-r--r-- | lldb/source/API/SBType.cpp | 38 | ||||
| -rw-r--r-- | lldb/source/Symbol/ClangASTType.cpp | 133 | ||||
| -rw-r--r-- | lldb/source/Symbol/Type.cpp | 58 | ||||
| -rw-r--r-- | lldb/test/python_api/class_members/Makefile | 2 | ||||
| -rw-r--r-- | lldb/test/python_api/class_members/TestSBTypeClassMembers.py | 11 | ||||
| -rw-r--r-- | lldb/test/python_api/class_members/main.mm (renamed from lldb/test/python_api/class_members/main.cpp) | 19 |
10 files changed, 288 insertions, 28 deletions
diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h index a10406ca6ae..6df408ba34f 100644 --- a/lldb/include/lldb/API/SBType.h +++ b/lldb/include/lldb/API/SBType.h @@ -89,6 +89,15 @@ public: lldb::SBType GetType (); + lldb::SBType + GetReturnType (); + + uint32_t + GetNumberOfArguments (); + + lldb::SBType + GetArgumentTypeAtIndex (uint32_t); + lldb::MemberFunctionKind GetKind(); diff --git a/lldb/include/lldb/Symbol/ClangASTType.h b/lldb/include/lldb/Symbol/ClangASTType.h index 297d604b221..0c2fdc2f1d5 100644 --- a/lldb/include/lldb/Symbol/ClangASTType.h +++ b/lldb/include/lldb/Symbol/ClangASTType.h @@ -162,7 +162,7 @@ public: GetNumberOfFunctionArguments () const; ClangASTType - GetFunctionArgumentAtIndex (const size_t index); + GetFunctionArgumentAtIndex (const size_t index) const; bool IsVariadicFunctionType () const; @@ -329,7 +329,7 @@ public: GetFunctionArgumentCount () const; ClangASTType - GetFunctionArgumentTypeAtIndex (size_t idx); + GetFunctionArgumentTypeAtIndex (size_t idx) const; ClangASTType GetFunctionReturnType () const; @@ -337,10 +337,8 @@ public: size_t GetNumMemberFunctions () const; - ClangASTType - GetMemberFunctionAtIndex (size_t idx, - std::string& name, - lldb::MemberFunctionKind& kind); + TypeMemberFunctionImpl + GetMemberFunctionAtIndex (size_t idx); ClangASTType GetLValueReferenceType () const; diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index a2235f37225..51bd3dd82c9 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -816,6 +816,7 @@ class TypeMemberFunctionImpl public: TypeMemberFunctionImpl() : m_type(), + m_objc_method_decl(nullptr), m_name(), m_kind(lldb::eMemberFunctionKindUnknown) { @@ -825,13 +826,25 @@ public: const std::string& name, const lldb::MemberFunctionKind& kind) : m_type(type), + m_objc_method_decl(nullptr), m_name(name), m_kind(kind) { } + TypeMemberFunctionImpl (clang::ObjCMethodDecl *method, + const std::string& name, + const lldb::MemberFunctionKind& kind) : + m_type(), + m_objc_method_decl(method), + m_name(name), + m_kind(kind) + { + } + TypeMemberFunctionImpl (const TypeMemberFunctionImpl& rhs) : m_type(rhs.m_type), + m_objc_method_decl(rhs.m_objc_method_decl), m_name(rhs.m_name), m_kind(rhs.m_kind) { @@ -849,14 +862,28 @@ public: ClangASTType GetType () const; + ClangASTType + GetReturnType () const; + + size_t + GetNumArguments () const; + + ClangASTType + GetArgumentAtIndex (size_t idx) const; + lldb::MemberFunctionKind GetKind () const; bool GetDescription (Stream& stream); + +protected: + std::string + GetPrintableTypeName (); private: ClangASTType m_type; + clang::ObjCMethodDecl *m_objc_method_decl; ConstString m_name; lldb::MemberFunctionKind m_kind; }; diff --git a/lldb/scripts/Python/interface/SBType.i b/lldb/scripts/Python/interface/SBType.i index 7daa144feb1..9c37f89c772 100644 --- a/lldb/scripts/Python/interface/SBType.i +++ b/lldb/scripts/Python/interface/SBType.i @@ -86,6 +86,15 @@ public: lldb::SBType GetType (); + lldb::SBType + GetReturnType (); + + uint32_t + GetNumberOfArguments (); + + lldb::SBType + GetArgumentTypeAtIndex (uint32_t); + lldb::MemberFunctionKind GetKind(); diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp index 01ad368cf28..54cbdc8a77f 100644 --- a/lldb/source/API/SBType.cpp +++ b/lldb/source/API/SBType.cpp @@ -267,12 +267,7 @@ SBType::GetMemberFunctionAtIndex (uint32_t idx) { SBTypeMemberFunction sb_func_type; if (IsValid()) - { - 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)); - } + sb_func_type.reset(new TypeMemberFunctionImpl(m_opaque_sp->GetClangASTType(true).GetMemberFunctionAtIndex(idx))); return sb_func_type; } @@ -754,7 +749,36 @@ SBTypeMemberFunction::GetType () sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType()))); } return sb_type; - +} + +lldb::SBType +SBTypeMemberFunction::GetReturnType () +{ + SBType sb_type; + if (m_opaque_sp) + { + sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType()))); + } + return sb_type; +} + +uint32_t +SBTypeMemberFunction::GetNumberOfArguments () +{ + if (m_opaque_sp) + return m_opaque_sp->GetNumArguments(); + return 0; +} + +lldb::SBType +SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i) +{ + SBType sb_type; + if (m_opaque_sp) + { + sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i)))); + } + return sb_type; } lldb::MemberFunctionKind diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index 3ca33249f28..e35d2af7bba 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -516,7 +516,7 @@ ClangASTType::GetNumberOfFunctionArguments () const } ClangASTType -ClangASTType::GetFunctionArgumentAtIndex (const size_t index) +ClangASTType::GetFunctionArgumentAtIndex (const size_t index) const { if (IsValid()) { @@ -1714,7 +1714,7 @@ ClangASTType::GetFunctionArgumentCount () const } ClangASTType -ClangASTType::GetFunctionArgumentTypeAtIndex (size_t idx) +ClangASTType::GetFunctionArgumentTypeAtIndex (size_t idx) const { if (IsValid()) { @@ -1759,8 +1759,45 @@ ClangASTType::GetNumMemberFunctions () const const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl); if (cxx_record_decl) num_functions = std::distance(cxx_record_decl->method_begin(), cxx_record_decl->method_end()); - break; } + break; + + case clang::Type::ObjCObjectPointer: + if (GetCompleteType()) + { + const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); + if (class_interface_decl) + num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end()); + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType()) + { + const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + if (class_interface_decl) + num_functions = std::distance(class_interface_decl->meth_begin(), class_interface_decl->meth_end()); + } + } + break; + + + case clang::Type::Typedef: + return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetNumMemberFunctions(); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetNumMemberFunctions(); + + case clang::Type::Paren: + return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetNumMemberFunctions(); default: break; @@ -1769,11 +1806,13 @@ ClangASTType::GetNumMemberFunctions () const return num_functions; } -ClangASTType -ClangASTType::GetMemberFunctionAtIndex (size_t idx, - std::string& name, - lldb::MemberFunctionKind& kind) +TypeMemberFunctionImpl +ClangASTType::GetMemberFunctionAtIndex (size_t idx) { + std::string name(""); + MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown); + ClangASTType type{}; + clang::ObjCMethodDecl *method_decl(nullptr); if (IsValid()) { clang::QualType qual_type(GetCanonicalQualType()); @@ -1807,18 +1846,94 @@ ClangASTType::GetMemberFunctionAtIndex (size_t idx, kind = lldb::eMemberFunctionKindDestructor; else kind = lldb::eMemberFunctionKindInstanceMethod; - return ClangASTType(m_ast,method_decl->getType().getAsOpaquePtr()); + type = ClangASTType(m_ast,method_decl->getType().getAsOpaquePtr()); } } } } + break; + + case clang::Type::ObjCObjectPointer: + if (GetCompleteType()) + { + const clang::ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); + if (class_interface_decl) + { + auto method_iter = class_interface_decl->meth_begin(); + auto method_end = class_interface_decl->meth_end(); + if (idx < static_cast<size_t>(std::distance(method_iter, method_end))) + { + std::advance(method_iter, idx); + method_decl = method_iter->getCanonicalDecl(); + if (method_decl) + { + name = method_decl->getSelector().getAsString(); + if (method_decl->isClassMethod()) + kind = lldb::eMemberFunctionKindStaticMethod; + else + kind = lldb::eMemberFunctionKindInstanceMethod; + } + } + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteType()) + { + const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); + if (objc_class_type) + { + clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + if (class_interface_decl) + { + auto method_iter = class_interface_decl->meth_begin(); + auto method_end = class_interface_decl->meth_end(); + if (idx < static_cast<size_t>(std::distance(method_iter, method_end))) + { + std::advance(method_iter, idx); + method_decl = method_iter->getCanonicalDecl(); + if (method_decl) + { + name = method_decl->getSelector().getAsString(); + if (method_decl->isClassMethod()) + kind = lldb::eMemberFunctionKindStaticMethod; + else + kind = lldb::eMemberFunctionKindInstanceMethod; + } + } + } + } + } + break; + + case clang::Type::Typedef: + return ClangASTType (m_ast, llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType()).GetMemberFunctionAtIndex(idx); + + case clang::Type::Elaborated: + return ClangASTType (m_ast, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType()).GetMemberFunctionAtIndex(idx); + + case clang::Type::Paren: + return ClangASTType (m_ast, llvm::cast<clang::ParenType>(qual_type)->desugar()).GetMemberFunctionAtIndex(idx); default: break; } } - return ClangASTType(); + if (kind == eMemberFunctionKindUnknown) + return TypeMemberFunctionImpl(); + if (method_decl) + return TypeMemberFunctionImpl(method_decl, name, kind); + if (type) + return TypeMemberFunctionImpl(type, name, kind); + + return TypeMemberFunctionImpl(); } ClangASTType diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index f89d1a78328..42b76590aae 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -31,6 +31,7 @@ #include "llvm/ADT/StringRef.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" using namespace lldb; using namespace lldb_private; @@ -1297,6 +1298,7 @@ TypeMemberFunctionImpl::operator = (const TypeMemberFunctionImpl& rhs) if (this != &rhs) { m_type = rhs.m_type; + m_objc_method_decl = rhs.m_objc_method_decl; m_name = rhs.m_name; m_kind = rhs.m_kind; } @@ -1327,6 +1329,21 @@ TypeMemberFunctionImpl::GetKind () const return m_kind; } +std::string +TypeMemberFunctionImpl::GetPrintableTypeName () +{ + if (m_type) + return m_type.GetTypeName().AsCString("<unknown>"); + if (m_objc_method_decl) + { + if (m_objc_method_decl->getClassInterface()) + { + return m_objc_method_decl->getClassInterface()->getName(); + } + } + return "<unknown>"; +} + bool TypeMemberFunctionImpl::GetDescription (Stream& stream) { @@ -1334,25 +1351,58 @@ TypeMemberFunctionImpl::GetDescription (Stream& stream) case lldb::eMemberFunctionKindUnknown: return false; case lldb::eMemberFunctionKindConstructor: - stream.Printf("constructor for %s", m_type.GetTypeName().AsCString()); + stream.Printf("constructor for %s", GetPrintableTypeName().c_str()); break; case lldb::eMemberFunctionKindDestructor: - stream.Printf("destructor for %s", m_type.GetTypeName().AsCString()); + stream.Printf("destructor for %s", GetPrintableTypeName().c_str()); break; case lldb::eMemberFunctionKindInstanceMethod: stream.Printf("instance method %s of type %s", m_name.AsCString(), - m_type.GetTypeName().AsCString()); + GetPrintableTypeName().c_str()); break; case lldb::eMemberFunctionKindStaticMethod: stream.Printf("static method %s of type %s", m_name.AsCString(), - m_type.GetTypeName().AsCString()); + GetPrintableTypeName().c_str()); break; } return true; } +ClangASTType +TypeMemberFunctionImpl::GetReturnType () const +{ + if (m_type) + return m_type.GetFunctionReturnType(); + if (m_objc_method_decl) + return ClangASTType(&m_objc_method_decl->getASTContext(),m_objc_method_decl->getReturnType().getAsOpaquePtr()); + return ClangASTType(); +} + +size_t +TypeMemberFunctionImpl::GetNumArguments () const +{ + if (m_type) + return m_type.GetNumberOfFunctionArguments(); + if (m_objc_method_decl) + return m_objc_method_decl->param_size(); + return 0; +} + +ClangASTType +TypeMemberFunctionImpl::GetArgumentAtIndex (size_t idx) const +{ + if (m_type) + return m_type.GetFunctionArgumentAtIndex (idx); + if (m_objc_method_decl) + { + if (idx < m_objc_method_decl->param_size()) + return ClangASTType(&m_objc_method_decl->getASTContext(), m_objc_method_decl->parameters()[idx]->getOriginalType().getAsOpaquePtr()); + } + return ClangASTType(); +} + 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/Makefile b/lldb/test/python_api/class_members/Makefile index 8a7102e347a..0d7550f9f28 100644 --- a/lldb/test/python_api/class_members/Makefile +++ b/lldb/test/python_api/class_members/Makefile @@ -1,5 +1,5 @@ LEVEL = ../../make -CXX_SOURCES := main.cpp +OBJCXX_SOURCES := main.mm include $(LEVEL)/Makefile.rules diff --git a/lldb/test/python_api/class_members/TestSBTypeClassMembers.py b/lldb/test/python_api/class_members/TestSBTypeClassMembers.py index f60b58ec956..867114d059e 100644 --- a/lldb/test/python_api/class_members/TestSBTypeClassMembers.py +++ b/lldb/test/python_api/class_members/TestSBTypeClassMembers.py @@ -37,7 +37,7 @@ class SBTypeMemberFunctionsTest(TestBase): # We'll use the test method name as the exe_name. self.exe_name = self.testMethodName # Find the line number to break at. - self.source = 'main.cpp' + self.source = 'main.mm' self.line = line_number(self.source, '// set breakpoint here') def type_api(self, exe_name): @@ -76,6 +76,15 @@ class SBTypeMemberFunctionsTest(TestBase): 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") + + variable = frame0.FindVariable("thingy") + Thingy = variable.GetType() + + self.assertTrue(Thingy.GetNumberOfMemberFunctions() == 2, "Thingy declares two methods") + + self.assertTrue(Thingy.GetMemberFunctionAtIndex(0).GetReturnType().GetName() == "id", "Thingy::init returns an id") + self.assertTrue(Thingy.GetMemberFunctionAtIndex(1).GetNumberOfArguments() == 2, "Thingy::foo takes two arguments") + self.assertTrue(Thingy.GetMemberFunctionAtIndex(1).GetArgumentTypeAtIndex(0).GetName() == "int", "Thingy::foo takes an int") if __name__ == '__main__': import atexit diff --git a/lldb/test/python_api/class_members/main.cpp b/lldb/test/python_api/class_members/main.mm index 86392a219cc..ff61b369ee1 100644 --- a/lldb/test/python_api/class_members/main.cpp +++ b/lldb/test/python_api/class_members/main.mm @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +#import <Foundation/Foundation.h> + class Base { public: int foo(int x, int y) { return 1; } @@ -22,7 +24,24 @@ public: float baz(float b) { return b + 1.0; } }; +@interface Thingy: NSObject { +} +- (id)init; +- (id)fooWithBar: (int)bar andBaz:(id)baz; +@end + +@implementation Thingy { +} +- (id)init { + return (self = [super init]); +} +- (id)fooWithBar: (int)bar andBaz:(id)baz { + return nil; +} +@end + int main() { Derived d; + Thingy *thingy = [[Thingy alloc] init]; return 0; // set breakpoint here } |

