summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorEnrico Granata <egranata@apple.com>2014-09-19 18:21:05 +0000
committerEnrico Granata <egranata@apple.com>2014-09-19 18:21:05 +0000
commit47caf9a95618142a03316f91a72eed1910a79b14 (patch)
treeb6268e1cc325cd52932f921b50b2a2df9ca0036a /lldb/source
parent4505f3a73db80414c9fed0049b8a75b6c4d1b1d8 (diff)
downloadbcm5719-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.cpp38
-rw-r--r--lldb/source/Symbol/ClangASTType.cpp133
-rw-r--r--lldb/source/Symbol/Type.cpp58
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(),
OpenPOWER on IntegriCloud