diff options
author | Enrico Granata <egranata@apple.com> | 2014-09-19 18:21:05 +0000 |
---|---|---|
committer | Enrico Granata <egranata@apple.com> | 2014-09-19 18:21:05 +0000 |
commit | 47caf9a95618142a03316f91a72eed1910a79b14 (patch) | |
tree | b6268e1cc325cd52932f921b50b2a2df9ca0036a /lldb/source | |
parent | 4505f3a73db80414c9fed0049b8a75b6c4d1b1d8 (diff) | |
download | bcm5719-llvm-47caf9a95618142a03316f91a72eed1910a79b14.tar.gz bcm5719-llvm-47caf9a95618142a03316f91a72eed1910a79b14.zip |
Extend the member function discovery APIs to also support Objective-C as well as C++
For the Objective-C case, we do not have a "function type" notion, so we actually end up wrapping the clang ObjCMethodDecl in the Impl object, and ask function-y questions of it
In general, you can always ask for return type, number of arguments, and type of each argument using the TypeMemberFunction layer - but in the C++ case, you can also acquire a Type object for the function itself, which instead you can't do in the Objective-C case
llvm-svn: 218132
Diffstat (limited to 'lldb/source')
-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 |
3 files changed, 209 insertions, 20 deletions
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(), |