Fixed TypeMemberFunctionImpl to not use clang types directly but use the new CompilerDecl class to do the job in an abstract way.

Fixed a crash that would happen if you tried to get the name of a constructor or destructor by calling "getDeclName()" instead of calling getName() (which would assert and crash).

Added the ability to get function arguments names from SBFunction.

llvm-svn: 252622
This commit is contained in:
Greg Clayton 2015-11-10 17:47:04 +00:00
parent a01a5ee72f
commit fe68904fa6
15 changed files with 335 additions and 102 deletions

View File

@ -53,6 +53,9 @@ public:
lldb::SBAddress
GetEndAddress ();
const char *
GetArgumentName (uint32_t arg_idx);
uint32_t
GetPrologueByteSize ();

View File

@ -85,7 +85,13 @@ public:
const char *
GetName ();
const char *
GetDemangledName ();
const char *
GetMangledName ();
lldb::SBType
GetType ();

View File

@ -117,6 +117,9 @@ public:
clang::DiagnosticConsumer *
getDiagnosticConsumer();
clang::MangleContext *
getMangleContext();
std::shared_ptr<clang::TargetOptions> &getTargetOptions();
clang::TargetInfo *
@ -533,6 +536,21 @@ public:
ConstString
DeclGetName (void *opaque_decl) override;
ConstString
DeclGetMangledName (void *opaque_decl) override;
CompilerDeclContext
DeclGetDeclContext (void *opaque_decl) override;
CompilerType
DeclGetFunctionReturnType(void *opaque_decl) override;
size_t
DeclGetFunctionNumArguments(void *opaque_decl) override;
CompilerType
DeclGetFunctionArgumentType (void *opaque_decl, size_t arg_idx) override;
//----------------------------------------------------------------------
// CompilerDeclContext override functions
//----------------------------------------------------------------------
@ -1161,6 +1179,7 @@ protected:
std::unique_ptr<clang::Builtin::Context> m_builtins_ap;
std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap;
std::unique_ptr<ClangASTSource> m_scratch_ast_source_ap;
std::unique_ptr<clang::MangleContext> m_mangle_ctx_ap;
CompleteTagDeclCallback m_callback_tag_decl;
CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
void * m_callback_baton;

View File

@ -12,6 +12,7 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Symbol/CompilerType.h"
namespace lldb_private {
@ -102,6 +103,24 @@ public:
ConstString
GetName () const;
ConstString
GetMangledName () const;
CompilerDeclContext
GetDeclContext() const;
// If this decl represents a function, return the return type
CompilerType
GetFunctionReturnType() const;
// If this decl represents a function, return the number of arguments for the function
size_t
GetNumFunctionArguments() const;
// If this decl represents a function, return the argument type given a zero based argument index
CompilerType
GetFunctionArgumentType (size_t arg_idx) const;
private:
TypeSystem *m_type_system;
void *m_opaque_decl;

View File

@ -14,6 +14,7 @@
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/UserID.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Declaration.h"
@ -823,50 +824,33 @@ class TypeMemberFunctionImpl
{
public:
TypeMemberFunctionImpl() :
m_type(),
m_objc_method_decl(nullptr),
m_type (),
m_decl (),
m_name(),
m_kind(lldb::eMemberFunctionKindUnknown)
m_kind (lldb::eMemberFunctionKindUnknown)
{
}
TypeMemberFunctionImpl (const CompilerType& type,
const CompilerDecl& decl,
const std::string& name,
const lldb::MemberFunctionKind& kind) :
m_type(type),
m_objc_method_decl(nullptr),
m_type (type),
m_decl (decl),
m_name(name),
m_kind(kind)
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)
{
}
TypeMemberFunctionImpl&
operator = (const TypeMemberFunctionImpl& rhs);
bool
IsValid ();
ConstString
GetName () const;
ConstString
GetMangledName () const;
CompilerType
GetType () const;
@ -891,7 +875,7 @@ protected:
private:
CompilerType m_type;
clang::ObjCMethodDecl *m_objc_method_decl;
CompilerDecl m_decl;
ConstString m_name;
lldb::MemberFunctionKind m_kind;
};

View File

@ -116,12 +116,27 @@ public:
virtual ConstString
DeclGetName (void *opaque_decl) = 0;
virtual ConstString
DeclGetMangledName (void *opaque_decl);
virtual lldb::VariableSP
DeclGetVariable (void *opaque_decl) = 0;
virtual void
DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) = 0;
virtual CompilerDeclContext
DeclGetDeclContext (void *opaque_decl);
virtual CompilerType
DeclGetFunctionReturnType(void *opaque_decl);
virtual size_t
DeclGetFunctionNumArguments(void *opaque_decl);
virtual CompilerType
DeclGetFunctionArgumentType (void *opaque_decl, size_t arg_idx);
//----------------------------------------------------------------------
// CompilerDeclContext functions
//----------------------------------------------------------------------

View File

@ -608,6 +608,20 @@
return lldb_private::PythonString("").release();
}
}
%extend lldb::SBTypeMemberFunction {
PyObject *lldb::SBTypeMemberFunction::__str__ (){
lldb::SBStream description;
$self->GetDescription (description, lldb::eDescriptionLevelBrief);
const char *desc = description.GetData();
size_t desc_len = description.GetSize();
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
--desc_len;
if (desc_len > 0)
return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
else
return lldb_private::PythonString("").release();
}
}
%extend lldb::SBTypeEnumMember {
PyObject *lldb::SBTypeEnumMember::__str__ (){
lldb::SBStream description;

View File

@ -77,6 +77,9 @@ public:
lldb::SBAddress
GetEndAddress ();
const char *
GetArgumentName (uint32_t arg_idx);
uint32_t
GetPrologueByteSize ();

View File

@ -83,6 +83,12 @@ public:
const char *
GetName ();
const char *
GetDemangledName ();
const char *
GetMangledName ();
lldb::SBType
GetType ();

View File

@ -16,6 +16,7 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
@ -216,6 +217,24 @@ SBFunction::GetEndAddress ()
return addr;
}
const char *
SBFunction::GetArgumentName (uint32_t arg_idx)
{
if (m_opaque_ptr)
{
Block &block = m_opaque_ptr->GetBlock(true);
VariableListSP variable_list_sp = block.GetBlockVariableList(true);
if (variable_list_sp)
{
VariableList arguments;
variable_list_sp->AppendVariablesWithScope (eValueTypeVariableArgument, arguments, true);
lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
if (variable_sp)
return variable_sp->GetName().GetCString();
}
}
return nullptr;
}
uint32_t
SBFunction::GetPrologueByteSize ()

View File

@ -13,6 +13,7 @@
#include "lldb/API/SBStream.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Mangled.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Type.h"
@ -784,6 +785,30 @@ SBTypeMemberFunction::GetName ()
return NULL;
}
const char *
SBTypeMemberFunction::GetDemangledName ()
{
if (m_opaque_sp)
{
ConstString mangled_str = m_opaque_sp->GetMangledName();
if (mangled_str)
{
Mangled mangled(mangled_str, true);
return mangled.GetDemangledName(mangled.GuessLanguage()).GetCString();
}
}
return NULL;
}
const char *
SBTypeMemberFunction::GetMangledName()
{
if (m_opaque_sp)
return m_opaque_sp->GetMangledName().GetCString();
return NULL;
}
SBType
SBTypeMemberFunction::GetType ()
{

View File

@ -40,6 +40,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Type.h"
#include "clang/AST/VTableBuilder.h"
@ -662,6 +663,14 @@ ClangASTContext::getDiagnosticsEngine()
return m_diagnostics_engine_ap.get();
}
clang::MangleContext *
ClangASTContext::getMangleContext()
{
if (m_mangle_ctx_ap.get() == nullptr)
m_mangle_ctx_ap.reset (getASTContext()->createMangleContext());
return m_mangle_ctx_ap.get();
}
class NullDiagnosticConsumer : public DiagnosticConsumer
{
public:
@ -4114,10 +4123,10 @@ ClangASTContext::GetNumMemberFunctions (lldb::opaque_compiler_type_t type)
TypeMemberFunctionImpl
ClangASTContext::GetMemberFunctionAtIndex (lldb::opaque_compiler_type_t type, size_t idx)
{
std::string name("");
std::string name;
MemberFunctionKind kind(MemberFunctionKind::eMemberFunctionKindUnknown);
CompilerType clang_type{};
clang::ObjCMethodDecl *method_decl(nullptr);
CompilerType clang_type;
CompilerDecl clang_decl;
if (type)
{
clang::QualType qual_type(GetCanonicalQualType(type));
@ -4136,22 +4145,20 @@ ClangASTContext::GetMemberFunctionAtIndex (lldb::opaque_compiler_type_t type, si
if (idx < static_cast<size_t>(std::distance(method_iter, method_end)))
{
std::advance(method_iter, idx);
auto method_decl = method_iter->getCanonicalDecl();
if (method_decl)
clang::CXXMethodDecl *cxx_method_decl = method_iter->getCanonicalDecl();
if (cxx_method_decl)
{
if (!method_decl->getName().empty())
name.assign(method_decl->getName().data());
else
name.clear();
if (method_decl->isStatic())
name = cxx_method_decl->getDeclName().getAsString();
if (cxx_method_decl->isStatic())
kind = lldb::eMemberFunctionKindStaticMethod;
else if (llvm::isa<clang::CXXConstructorDecl>(method_decl))
else if (llvm::isa<clang::CXXConstructorDecl>(cxx_method_decl))
kind = lldb::eMemberFunctionKindConstructor;
else if (llvm::isa<clang::CXXDestructorDecl>(method_decl))
else if (llvm::isa<clang::CXXDestructorDecl>(cxx_method_decl))
kind = lldb::eMemberFunctionKindDestructor;
else
kind = lldb::eMemberFunctionKindInstanceMethod;
clang_type = CompilerType(getASTContext(),method_decl->getType());
clang_type = CompilerType(this, cxx_method_decl->getType().getAsOpaquePtr());
clang_decl = CompilerDecl(this, cxx_method_decl);
}
}
}
@ -4172,11 +4179,12 @@ ClangASTContext::GetMemberFunctionAtIndex (lldb::opaque_compiler_type_t type, si
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)
clang::ObjCMethodDecl *objc_method_decl = method_iter->getCanonicalDecl();
if (objc_method_decl)
{
name = method_decl->getSelector().getAsString();
if (method_decl->isClassMethod())
clang_decl = CompilerDecl(this, objc_method_decl);
name = objc_method_decl->getSelector().getAsString();
if (objc_method_decl->isClassMethod())
kind = lldb::eMemberFunctionKindStaticMethod;
else
kind = lldb::eMemberFunctionKindInstanceMethod;
@ -4202,11 +4210,12 @@ ClangASTContext::GetMemberFunctionAtIndex (lldb::opaque_compiler_type_t type, si
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)
clang::ObjCMethodDecl *objc_method_decl = method_iter->getCanonicalDecl();
if (objc_method_decl)
{
name = method_decl->getSelector().getAsString();
if (method_decl->isClassMethod())
clang_decl = CompilerDecl(this, objc_method_decl);
name = objc_method_decl->getSelector().getAsString();
if (objc_method_decl->isClassMethod())
kind = lldb::eMemberFunctionKindStaticMethod;
else
kind = lldb::eMemberFunctionKindInstanceMethod;
@ -4233,12 +4242,8 @@ ClangASTContext::GetMemberFunctionAtIndex (lldb::opaque_compiler_type_t type, si
if (kind == eMemberFunctionKindUnknown)
return TypeMemberFunctionImpl();
if (method_decl)
return TypeMemberFunctionImpl(method_decl, name, kind);
if (type)
return TypeMemberFunctionImpl(clang_type, name, kind);
return TypeMemberFunctionImpl();
else
return TypeMemberFunctionImpl(clang_type, clang_decl, name, kind);
}
CompilerType
@ -9071,11 +9076,95 @@ ClangASTContext::DeclGetName (void *opaque_decl)
{
clang::NamedDecl *nd = llvm::dyn_cast<NamedDecl>((clang::Decl*)opaque_decl);
if (nd != nullptr)
return ConstString(nd->getName());
return ConstString(nd->getDeclName().getAsString());
}
return ConstString();
}
ConstString
ClangASTContext::DeclGetMangledName (void *opaque_decl)
{
if (opaque_decl)
{
clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>((clang::Decl*)opaque_decl);
if (nd != nullptr && !llvm::isa<clang::ObjCMethodDecl>(nd))
{
clang::MangleContext *mc = getMangleContext();
if (mc && mc->shouldMangleCXXName(nd))
{
llvm::SmallVector<char, 1024> buf;
llvm::raw_svector_ostream llvm_ostrm (buf);
if (llvm::isa<clang::CXXConstructorDecl>(nd))
{
mc->mangleCXXCtor(llvm::dyn_cast<clang::CXXConstructorDecl>(nd), Ctor_Complete, llvm_ostrm);
}
else if (llvm::isa<clang::CXXDestructorDecl>(nd))
{
mc->mangleCXXDtor(llvm::dyn_cast<clang::CXXDestructorDecl>(nd), Dtor_Complete, llvm_ostrm);
}
else
{
mc->mangleName(nd, llvm_ostrm);
}
if (buf.size() > 0)
return ConstString(buf.data(), buf.size());
}
}
}
return ConstString();
}
CompilerDeclContext
ClangASTContext::DeclGetDeclContext (void *opaque_decl)
{
if (opaque_decl)
return CompilerDeclContext(this, ((clang::Decl*)opaque_decl)->getDeclContext());
else
return CompilerDeclContext();
}
CompilerType
ClangASTContext::DeclGetFunctionReturnType(void *opaque_decl)
{
if (clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>((clang::Decl*)opaque_decl))
return CompilerType(this, func_decl->getReturnType().getAsOpaquePtr());
if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl))
return CompilerType(this, objc_method->getReturnType().getAsOpaquePtr());
else
return CompilerType();
}
size_t
ClangASTContext::DeclGetFunctionNumArguments(void *opaque_decl)
{
if (clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>((clang::Decl*)opaque_decl))
return func_decl->param_size();
if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl))
return objc_method->param_size();
else
return 0;
}
CompilerType
ClangASTContext::DeclGetFunctionArgumentType (void *opaque_decl, size_t idx)
{
if (clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>((clang::Decl*)opaque_decl))
{
if (idx < func_decl->param_size())
{
ParmVarDecl *var_decl = func_decl->getParamDecl(idx);
if (var_decl)
return CompilerType(this, var_decl->getOriginalType().getAsOpaquePtr());
}
}
else if (clang::ObjCMethodDecl *objc_method = llvm::dyn_cast<clang::ObjCMethodDecl>((clang::Decl*)opaque_decl))
{
if (idx < objc_method->param_size())
return CompilerType(this, objc_method->parameters()[idx]->getOriginalType().getAsOpaquePtr());
}
return CompilerType();
}
//----------------------------------------------------------------------
// CompilerDeclContext functions
//----------------------------------------------------------------------

View File

@ -25,12 +25,42 @@ CompilerDecl::GetName() const
return m_type_system->DeclGetName(m_opaque_decl);
}
ConstString
CompilerDecl::GetMangledName () const
{
return m_type_system->DeclGetMangledName(m_opaque_decl);
}
lldb::VariableSP
CompilerDecl::GetAsVariable ()
{
return m_type_system->DeclGetVariable(m_opaque_decl);
}
CompilerDeclContext
CompilerDecl::GetDeclContext() const
{
return m_type_system->DeclGetDeclContext(m_opaque_decl);
}
CompilerType
CompilerDecl::GetFunctionReturnType() const
{
return m_type_system->DeclGetFunctionReturnType(m_opaque_decl);
}
size_t
CompilerDecl::GetNumFunctionArguments() const
{
return m_type_system->DeclGetFunctionNumArguments(m_opaque_decl);
}
CompilerType
CompilerDecl::GetFunctionArgumentType (size_t arg_idx) const
{
return m_type_system->DeclGetFunctionArgumentType(m_opaque_decl, arg_idx);
}
bool
lldb_private::operator == (const lldb_private::CompilerDecl &lhs, const lldb_private::CompilerDecl &rhs)
{

View File

@ -1253,19 +1253,6 @@ TypeImpl::GetDescription (lldb_private::Stream &strm,
return true;
}
TypeMemberFunctionImpl&
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;
}
return *this;
}
bool
TypeMemberFunctionImpl::IsValid ()
{
@ -1278,6 +1265,12 @@ TypeMemberFunctionImpl::GetName () const
return m_name;
}
ConstString
TypeMemberFunctionImpl::GetMangledName () const
{
return m_decl.GetMangledName();
}
CompilerType
TypeMemberFunctionImpl::GetType () const
{
@ -1290,21 +1283,6 @@ 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)
{
@ -1312,20 +1290,20 @@ TypeMemberFunctionImpl::GetDescription (Stream& stream)
case lldb::eMemberFunctionKindUnknown:
return false;
case lldb::eMemberFunctionKindConstructor:
stream.Printf("constructor for %s", GetPrintableTypeName().c_str());
stream.Printf("constructor for %s", m_type.GetTypeName().AsCString("<unknown>"));
break;
case lldb::eMemberFunctionKindDestructor:
stream.Printf("destructor for %s", GetPrintableTypeName().c_str());
stream.Printf("destructor for %s", m_type.GetTypeName().AsCString("<unknown>"));
break;
case lldb::eMemberFunctionKindInstanceMethod:
stream.Printf("instance method %s of type %s",
m_name.AsCString(),
GetPrintableTypeName().c_str());
m_decl.GetDeclContext().GetName().AsCString());
break;
case lldb::eMemberFunctionKindStaticMethod:
stream.Printf("static method %s of type %s",
m_name.AsCString(),
GetPrintableTypeName().c_str());
m_decl.GetDeclContext().GetName().AsCString());
break;
}
return true;
@ -1336,9 +1314,7 @@ TypeMemberFunctionImpl::GetReturnType () const
{
if (m_type)
return m_type.GetFunctionReturnType();
if (m_objc_method_decl)
return CompilerType(&m_objc_method_decl->getASTContext(), m_objc_method_decl->getReturnType());
return CompilerType();
return m_decl.GetFunctionReturnType();
}
size_t
@ -1346,9 +1322,8 @@ TypeMemberFunctionImpl::GetNumArguments () const
{
if (m_type)
return m_type.GetNumberOfFunctionArguments();
if (m_objc_method_decl)
return m_objc_method_decl->param_size();
return 0;
else
return m_decl.GetNumFunctionArguments();
}
CompilerType
@ -1356,12 +1331,8 @@ 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 CompilerType(&m_objc_method_decl->getASTContext(), m_objc_method_decl->parameters()[idx]->getOriginalType());
}
return CompilerType();
else
return m_decl.GetFunctionArgumentType(idx);
}
TypeEnumMemberImpl::TypeEnumMemberImpl (const lldb::TypeImplSP &integer_type_sp,

View File

@ -121,6 +121,36 @@ TypeSystem::IsMeaninglessWithoutDynamicResolution (void* type)
return false;
}
ConstString
TypeSystem::DeclGetMangledName (void *opaque_decl)
{
return ConstString();
}
CompilerDeclContext
TypeSystem::DeclGetDeclContext (void *opaque_decl)
{
return CompilerDeclContext();
}
CompilerType
TypeSystem::DeclGetFunctionReturnType(void *opaque_decl)
{
return CompilerType();
}
size_t
TypeSystem::DeclGetFunctionNumArguments(void *opaque_decl)
{
return 0;
}
CompilerType
TypeSystem::DeclGetFunctionArgumentType (void *opaque_decl, size_t arg_idx)
{
return CompilerType();
}
#pragma mark TypeSystemMap
TypeSystemMap::TypeSystemMap() :