Added the ability to create an objective C method for an objective C

interface in ClangASTContext. Also added two bool returning functions that
indicated if an opaque clang qual type is a CXX class type, and if it is an
ObjC class type.

Objective C classes now will get their methods added lazily as they are
encountered. The reason for this is currently, unlike C++, the 
DW_TAG_structure_type and owns the ivars, doesn't not also contain the
member functions. This means when we parse the objective C class interface
we either need to find all functions whose names start with "+[CLASS_NAME"
or "-[CLASS_NAME" and add them all to the class, or when we parse each objective
C function, we slowly add it to the class interface definition. Since objective
C's class doesn't change internal bits according to whether it has certain types
of member functions (like C++ does if it has virtual functions, or if it has
user ctors/dtors), I currently chose to lazily populate the class when each
functions is parsed. Another issue we run into with ObjC method declarations
is the "self" and "_cmd" implicit args are not marked as artificial in the
DWARF (DW_AT_artifical), so we currently have to look for the parameters by
name if we are trying to omit artificial function args if the language of the
compile unit is ObjC or ObjC++.

llvm-svn: 114722
This commit is contained in:
Greg Clayton 2010-09-24 05:15:53 +00:00
parent 45c42ec2f1
commit 0fffff5816
6 changed files with 400 additions and 235 deletions

View File

@ -174,12 +174,12 @@ public:
lldb::AccessType access,
uint32_t bitfield_bit_size)
{
return ClangASTContext::AddFieldToRecordType(getASTContext(),
record_qual_type,
name,
field_type,
access,
bitfield_bit_size);
return ClangASTContext::AddFieldToRecordType (getASTContext(),
record_qual_type,
name,
field_type,
access,
bitfield_bit_size);
}
static clang::CXXMethodDecl *
@ -188,22 +188,28 @@ public:
const char *name,
void *method_type,
lldb::AccessType access,
bool is_virtual);
bool is_virtual,
bool is_static,
bool is_inline);
clang::CXXMethodDecl *
AddMethodToCXXRecordType (void *record_opaque_type,
const char *name,
void *method_type,
lldb::AccessType access,
bool is_virtual)
bool is_virtual,
bool is_static,
bool is_inline)
{
return ClangASTContext::AddMethodToCXXRecordType(getASTContext(),
record_opaque_type,
name,
method_type,
access,
is_virtual);
return ClangASTContext::AddMethodToCXXRecordType (getASTContext(),
record_opaque_type,
name,
method_type,
access,
is_virtual,
is_static,
is_inline);
}
bool
@ -267,7 +273,28 @@ public:
ObjCDeclHasIVars (clang::ObjCInterfaceDecl *class_interface_decl,
bool check_superclass);
static clang::ObjCMethodDecl *
AddMethodToObjCObjectType (clang::ASTContext *ast_context,
void *class_opaque_type,
const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
void *method_opaque_type,
lldb::AccessType access);
clang::ObjCMethodDecl *
AddMethodToObjCObjectType (void *class_opaque_type,
const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
void *method_opaque_type,
lldb::AccessType access)
{
return AddMethodToObjCObjectType (getASTContext(),
class_opaque_type,
name,
method_opaque_type,
access);
}
//------------------------------------------------------------------
// Aggregate Types
//------------------------------------------------------------------
@ -495,6 +522,12 @@ public:
static bool
IsFloatingPointType (void *clang_type, uint32_t &count, bool &is_complex);
static bool
IsCXXClassType (void *clang_type);
static bool
IsObjCClassType (void *clang_type);
//static bool
//ConvertFloatValueToString (clang::ASTContext *ast_context,
// void *clang_type,

View File

@ -2432,6 +2432,7 @@
isa = PBXProject;
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,

View File

@ -1206,12 +1206,18 @@ ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
false,
ClangASTContext::GetTypeQualifiers(copied_type));
ClangASTContext::AddMethodToCXXRecordType(parser_ast_context,
copied_type,
"___clang_expr",
method_type,
lldb::eAccessPublic,
false);
const bool is_virtual = false;
const bool is_static = false;
const bool is_inline = false;
ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
copied_type,
"___clang_expr",
method_type,
lldb::eAccessPublic,
is_virtual,
is_static,
is_inline);
}
context.AddTypeDecl(copied_type);

View File

@ -476,7 +476,7 @@ SymbolFileDWARF::DebugRanges() const
}
bool
SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
{
if (cu != NULL)
{
@ -566,7 +566,7 @@ AddRangesToBlock
Function *
SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
{
DWARFDebugRanges::RangeList func_ranges;
const char *name = NULL;
@ -641,7 +641,7 @@ SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
{
assert (sc.comp_unit);
size_t functions_added = 0;
const DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
if (dwarf_cu)
{
DWARFDIECollection function_dies;
@ -894,7 +894,7 @@ SymbolFileDWARF::ParseFunctionBlocks
(
const SymbolContext& sc,
Block *parent_block,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *die,
addr_t subprogram_low_pc,
bool parse_siblings,
@ -1011,7 +1011,7 @@ SymbolFileDWARF::ParseChildMembers
(
const SymbolContext& sc,
TypeSP& type_sp,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
void *class_clang_type,
const LanguageType class_language,
@ -1107,135 +1107,8 @@ SymbolFileDWARF::ParseChildMembers
break;
case DW_TAG_subprogram:
{
DWARFDebugInfoEntry::Attributes attributes;
is_a_class = true;
if (default_accessibility == eAccessNone)
default_accessibility = eAccessPrivate;
//printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
// Set a bit that lets us know that we are currently parsing this
const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
const char *mangled = NULL;
dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Declaration decl;
bool is_variadic = false;
bool is_inline = false;
bool is_virtual = false;
unsigned type_quals = 0;
AccessType accessibility = default_accessibility;
clang::FunctionDecl::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
const char *type_name_cstr = NULL;
ConstString type_name_dbstr;
const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
if (num_attributes > 0)
{
uint32_t i;
for (i=0; i<num_attributes; ++i)
{
const dw_attr_t attr = attributes.AttributeAtIndex(i);
DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(this, i, form_value))
{
switch (attr)
{
case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name:
type_name_cstr = form_value.AsCString(&get_debug_str_data());
break;
case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
//case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
case DW_AT_external:
if (form_value.Unsigned())
{
if (storage == clang::SC_None)
storage = clang::SC_Extern;
else
storage = clang::SC_PrivateExtern;
}
break;
case DW_AT_inline:
is_inline = form_value.Unsigned() != 0;
break;
case DW_AT_virtuality:
is_virtual = form_value.Unsigned() != 0;
break;
case DW_AT_allocated:
case DW_AT_associated:
case DW_AT_address_class:
case DW_AT_artificial:
case DW_AT_calling_convention:
case DW_AT_data_location:
case DW_AT_elemental:
case DW_AT_entry_pc:
case DW_AT_explicit:
case DW_AT_frame_base:
case DW_AT_high_pc:
case DW_AT_low_pc:
case DW_AT_object_pointer:
case DW_AT_prototyped:
case DW_AT_pure:
case DW_AT_ranges:
case DW_AT_recursive:
case DW_AT_return_addr:
case DW_AT_segment:
case DW_AT_specification:
case DW_AT_start_scope:
case DW_AT_static_link:
case DW_AT_trampoline:
case DW_AT_visibility:
case DW_AT_vtable_elem_location:
case DW_AT_abstract_origin:
case DW_AT_description:
case DW_AT_sibling:
break;
}
}
}
void *return_clang_type = NULL;
Type *func_type = ResolveTypeUID(type_die_offset);
if (func_type)
return_clang_type = func_type->GetOpaqueClangQualType();
else
return_clang_type = type_list->GetClangASTContext().GetBuiltInType_void();
std::vector<void *> function_param_types;
std::vector<clang::ParmVarDecl*> function_param_decls;
// Parse the function children for the parameters
bool skip_artificial = true;
ParseChildParameters (sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls);
void *method_function_proto = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), is_variadic, type_quals);
if (type_name_cstr)
{
clang::CXXMethodDecl *method_decl = type_list->GetClangASTContext().AddMethodToCXXRecordType (class_clang_type,
type_name_cstr,
method_function_proto,
accessibility,
is_virtual);
assert (method_decl);
//m_die_to_decl_ctx[die] = method_decl;
}
const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
assert(type_sp.get());
}
}
// Let the type parsing code handle this one for us...
ResolveType (dwarf_cu, die);
break;
case DW_TAG_inheritance:
@ -1376,7 +1249,7 @@ SymbolFileDWARF::ResolveType (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* t
}
CompileUnit*
SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx)
SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* cu, uint32_t cu_idx)
{
// Check if the symbol vendor already knows about this compile unit?
if (cu->GetUserData() == NULL)
@ -2026,7 +1899,7 @@ SymbolFileDWARF::ParseChildParameters
(
const SymbolContext& sc,
TypeSP& type_sp,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
bool skip_artificial,
TypeList* type_list,
@ -2100,17 +1973,36 @@ SymbolFileDWARF::ParseChildParameters
}
}
if (skip_artificial && is_artificial)
continue;
Type *dc_type = ResolveTypeUID(param_type_die_offset);
if (dc_type)
bool skip = false;
if (skip_artificial)
{
function_param_types.push_back (dc_type->GetOpaqueClangQualType());
if (is_artificial)
skip = true;
else
{
clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParameterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage);
assert(param_var_decl);
function_param_decls.push_back(param_var_decl);
// HACK: Objective C formal parameters "self" and "_cmd"
// are not marked as artificial in the DWARF...
CompileUnit *cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
if (cu && (cu->GetLanguage() == eLanguageTypeObjC || cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
{
if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
skip = true;
}
}
}
if (!skip)
{
Type *type = ResolveTypeUID(param_type_die_offset);
if (type)
{
function_param_types.push_back (type->GetOpaqueClangQualType());
clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParameterDeclaration (name, type->GetOpaqueClangQualType(), storage);
assert(param_var_decl);
function_param_decls.push_back(param_var_decl);
}
}
}
}
@ -2130,7 +2022,7 @@ SymbolFileDWARF::ParseChildEnumerators
TypeSP& type_sp,
void * enumerator_qual_type,
uint32_t enumerator_byte_size,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die
)
{
@ -2200,7 +2092,7 @@ void
SymbolFileDWARF::ParseChildArrayInfo
(
const SymbolContext& sc,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
int64_t& first_index,
std::vector<uint64_t>& element_orders,
@ -2406,7 +2298,7 @@ SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
clang::DeclContext *
SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
{
DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
if (pos != m_die_to_decl_ctx.end())
@ -2450,14 +2342,14 @@ SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DW
}
TypeSP
SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new)
SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new)
{
TypeSP type_sp;
AccessType accessibility = eAccessNone;
if (die != NULL)
{
dw_tag_t tag = die->Tag();
const dw_tag_t tag = die->Tag();
if (die->GetUserData() == NULL)
{
type_is_new = true;
@ -2840,6 +2732,9 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
Declaration decl;
bool is_variadic = false;
bool is_inline = false;
bool is_static = false;
bool is_virtual = false;
unsigned type_quals = 0;
clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
@ -2850,7 +2745,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
uint32_t i;
for (i=0; i<num_attributes; ++i)
{
attr = attributes.AttributeAtIndex(i);
const dw_attr_t attr = attributes.AttributeAtIndex(i);
DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(this, i, form_value))
{
@ -2868,6 +2763,8 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
case DW_AT_external:
if (form_value.Unsigned())
{
@ -2877,9 +2774,6 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
storage = clang::SC_PrivateExtern;
}
break;
case DW_AT_inline:
is_inline = form_value.Unsigned() != 0;
break;
case DW_AT_allocated:
case DW_AT_associated:
@ -2905,7 +2799,6 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
case DW_AT_static_link:
case DW_AT_trampoline:
case DW_AT_visibility:
case DW_AT_virtuality:
case DW_AT_vtable_elem_location:
case DW_AT_abstract_origin:
case DW_AT_description:
@ -2926,18 +2819,92 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
std::vector<clang::ParmVarDecl*> function_param_decls;
// Parse the function children for the parameters
bool skip_artificial = false;
ParseChildParameters(sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls);
bool skip_artificial = true;
ParseChildParameters (sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls);
// clang_type will get the function prototype clang type after this call
clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), is_variadic, type_quals);
if (type_name_cstr)
{
clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
// Add the decl to our DIE to decl context map
assert (function_decl);
m_die_to_decl_ctx[die] = function_decl;
if (!function_param_decls.empty())
type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size());
bool type_handled = false;
const DWARFDebugInfoEntry *parent_die = die->GetParent();
if (tag == DW_TAG_subprogram)
{
if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
{
// We need to find the DW_TAG_class_type or
// DW_TAG_struct_type by name so we can add this
// as a member function of the class.
const char *class_name_start = type_name_cstr + 2;
const char *class_name_end = ::strchr (class_name_start, ' ');
SymbolContext empty_sc;
void *class_opaque_type = NULL;
if (class_name_start < class_name_end)
{
ConstString class_name (class_name_start, class_name_end - class_name_start);
TypeList types;
const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
if (match_count > 0)
{
for (uint32_t i=0; i<match_count; ++i)
{
Type *type = types.GetTypeAtIndex (i).get();
if (ClangASTContext::IsObjCClassType (type->GetOpaqueClangQualType()))
{
class_opaque_type = type->GetOpaqueClangQualType();
break;
}
}
}
}
if (class_opaque_type)
{
clang::ObjCMethodDecl *objc_method_decl;
objc_method_decl = type_list->GetClangASTContext().AddMethodToObjCObjectType (class_opaque_type,
type_name_cstr,
clang_type,
accessibility);
type_handled = objc_method_decl != NULL;
}
}
else if (parent_die->Tag() == DW_TAG_class_type ||
parent_die->Tag() == DW_TAG_structure_type)
{
// Look at the parent of this DIE and see if is is
// a class or struct and see if this is actually a
// C++ method
Type *class_type = ResolveType (dwarf_cu, parent_die);
if (class_type)
{
void *class_opaque_type = class_type->GetOpaqueClangQualType ();
if (ClangASTContext::IsCXXClassType (class_opaque_type))
{
clang::CXXMethodDecl *cxx_method_decl;
cxx_method_decl = type_list->GetClangASTContext().AddMethodToCXXRecordType (class_opaque_type,
type_name_cstr,
clang_type,
accessibility,
is_virtual,
is_static,
is_inline);
type_handled = cxx_method_decl != NULL;
}
}
}
}
if (!type_handled)
{
// We just have a function that isn't part of a class
clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
// Add the decl to our DIE to decl context map
assert (function_decl);
m_die_to_decl_ctx[die] = function_decl;
if (!function_param_decls.empty())
type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size());
}
}
type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
@ -3154,7 +3121,7 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
}
size_t
SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children)
SymbolFileDWARF::ParseTypes (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children)
{
size_t types_added = 0;
while (die != NULL)
@ -3296,7 +3263,7 @@ VariableSP
SymbolFileDWARF::ParseVariableDIE
(
const SymbolContext& sc,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *die,
const lldb::addr_t func_low_pc
)
@ -3439,7 +3406,7 @@ size_t
SymbolFileDWARF::ParseVariables
(
const SymbolContext& sc,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const lldb::addr_t func_low_pc,
const DWARFDebugInfoEntry *orig_die,
bool parse_siblings,

View File

@ -162,7 +162,7 @@ public:
SupportedVersion(uint16_t version);
clang::DeclContext *
GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die);
GetClangDeclContextForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die);
clang::DeclContext *
GetClangDeclContextForDIEOffset (dw_offset_t die_offset);
@ -200,31 +200,31 @@ protected:
};
DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF);
bool ParseCompileUnit(DWARFCompileUnit* cu, lldb::CompUnitSP& compile_unit_sp);
bool ParseCompileUnit (DWARFCompileUnit* cu, lldb::CompUnitSP& compile_unit_sp);
DWARFCompileUnit* GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid);
DWARFCompileUnit* GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu);
lldb_private::CompileUnit* GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx = UINT32_MAX);
bool GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, lldb_private::SymbolContext& sc);
lldb_private::Function * ParseCompileUnitFunction (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die);
lldb_private::Function * ParseCompileUnitFunction (const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die);
size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc,
lldb_private::Block *parent_block,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *die,
lldb::addr_t subprogram_low_pc,
bool parse_siblings,
bool parse_children);
size_t ParseTypes (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children);
lldb::TypeSP ParseType (const lldb_private::SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new);
size_t ParseTypes (const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children);
lldb::TypeSP ParseType (const lldb_private::SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new);
lldb::VariableSP ParseVariableDIE(
const lldb_private::SymbolContext& sc,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *die,
const lldb::addr_t func_low_pc);
size_t ParseVariables(
const lldb_private::SymbolContext& sc,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const lldb::addr_t func_low_pc,
const DWARFDebugInfoEntry *die,
bool parse_siblings,
@ -234,7 +234,7 @@ protected:
size_t ParseChildMembers(
const lldb_private::SymbolContext& sc,
lldb::TypeSP& type_sp,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *die,
void *class_clang_type,
const lldb::LanguageType class_language,
@ -246,7 +246,7 @@ protected:
size_t ParseChildParameters(
const lldb_private::SymbolContext& sc,
lldb::TypeSP& type_sp,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
bool skip_artificial,
lldb_private::TypeList* type_list,
@ -258,12 +258,12 @@ protected:
lldb::TypeSP& type_sp,
void *enumerator_qual_type,
uint32_t enumerator_byte_size,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *enum_die);
void ParseChildArrayInfo(
const lldb_private::SymbolContext& sc,
const DWARFCompileUnit* dwarf_cu,
DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
int64_t& first_index,
std::vector<uint64_t>& element_orders,

View File

@ -811,7 +811,9 @@ ClangASTContext::AddMethodToCXXRecordType
const char *name,
void *method_opaque_type,
lldb::AccessType access,
bool is_virtual
bool is_virtual,
bool is_static,
bool is_inline
)
{
if (!record_opaque_type || !method_opaque_type || !name)
@ -824,51 +826,56 @@ ClangASTContext::AddMethodToCXXRecordType
assert(identifier_table);
QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
clang::Type *record_type(record_qual_type.getTypePtr());
clang::Type *clang_type(record_qual_type.getTypePtr());
if (!record_type)
if (clang_type == NULL)
return NULL;
RecordType *record_recty(dyn_cast<RecordType>(record_type));
RecordType *record_clang_type(dyn_cast<RecordType>(clang_type));
if (!record_recty)
if (record_clang_type == NULL)
return NULL;
RecordDecl *record_decl = record_recty->getDecl();
RecordDecl *record_decl = record_clang_type->getDecl();
if (!record_decl)
if (record_decl == NULL)
return NULL;
CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
if (!cxx_record_decl)
if (cxx_record_decl == NULL)
return NULL;
QualType method_qual_type(QualType::getFromOpaquePtr(method_opaque_type));
QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
CXXMethodDecl *cxx_method_decl = CXXMethodDecl::Create(*ast_context,
cxx_record_decl,
DeclarationNameInfo(DeclarationName(&identifier_table->get(name)), SourceLocation()),
method_qual_type,
NULL);
CXXMethodDecl *cxx_method_decl = CXXMethodDecl::Create (*ast_context,
cxx_record_decl,
DeclarationNameInfo (DeclarationName (&identifier_table->get(name)), SourceLocation()),
method_qual_type,
NULL, // TypeSourceInfo *
is_static,
SC_None,
is_inline);
clang::AccessSpecifier AS = ConvertAccessTypeToAccessSpecifier(access);
cxx_method_decl->setAccess(AS);
cxx_method_decl->setVirtualAsWritten(is_virtual);
clang::AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
cxx_method_decl->setAccess (access_specifier);
cxx_method_decl->setVirtualAsWritten (is_virtual);
// Populate the method decl with parameter decls
clang::Type *method_type(method_qual_type.getTypePtr());
if (!method_type)
if (method_type == NULL)
return NULL;
FunctionProtoType *method_funprototy(dyn_cast<FunctionProtoType>(method_type));
FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
if (!method_funprototy)
if (!method_function_prototype)
return NULL;
unsigned int num_params = method_funprototy->getNumArgs();
unsigned int num_params = method_function_prototype->getNumArgs();
ParmVarDecl *params[num_params];
@ -876,20 +883,20 @@ ClangASTContext::AddMethodToCXXRecordType
param_index < num_params;
++param_index)
{
params[param_index] = ParmVarDecl::Create(*ast_context,
cxx_method_decl,
SourceLocation(),
NULL, // anonymous
method_funprototy->getArgType(param_index),
NULL,
SC_Auto,
SC_Auto,
NULL);
params[param_index] = ParmVarDecl::Create (*ast_context,
cxx_method_decl,
SourceLocation(),
NULL, // anonymous
method_function_prototype->getArgType(param_index),
NULL,
SC_None,
SC_None,
NULL);
}
cxx_method_decl->setParams(params, num_params);
cxx_method_decl->setParams (params, num_params);
cxx_record_decl->addDecl(cxx_method_decl);
cxx_record_decl->addDecl (cxx_method_decl);
return cxx_method_decl;
}
@ -988,14 +995,14 @@ ClangASTContext::AddFieldToRecordType
ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
if (objc_class_type)
{
bool isSynthesized = false;
bool is_synthesized = false;
ClangASTContext::AddObjCClassIVar (ast_context,
record_clang_type,
name,
field_type,
access,
bitfield_bit_size,
isSynthesized);
is_synthesized);
}
}
}
@ -1250,7 +1257,7 @@ ClangASTContext::AddObjCClassIVar
void *ivar_opaque_type,
AccessType access,
uint32_t bitfield_bit_size,
bool isSynthesized
bool is_synthesized
)
{
if (class_opaque_type == NULL || ivar_opaque_type == NULL)
@ -1289,7 +1296,7 @@ ClangASTContext::AddObjCClassIVar
NULL, // TypeSourceInfo *
ConvertAccessTypeToObjCIvarAccessControl (access),
bit_width,
isSynthesized);
is_synthesized);
if (field)
{
@ -1334,7 +1341,132 @@ ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool
}
return false;
}
clang::ObjCMethodDecl *
ClangASTContext::AddMethodToObjCObjectType
(
clang::ASTContext *ast_context,
void *class_opaque_type,
const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
void *method_opaque_type,
lldb::AccessType access
)
{
if (class_opaque_type == NULL || method_opaque_type == NULL)
return NULL;
IdentifierTable *identifier_table = &ast_context->Idents;
assert (ast_context != NULL);
assert (identifier_table != NULL);
QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
clang::Type *class_type = class_qual_type.getTypePtr();
if (class_type == NULL)
return NULL;
ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
if (objc_class_type == NULL)
return NULL;
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
if (class_interface_decl == NULL)
return NULL;
const char *selector_start = ::strchr (name, ' ');
if (selector_start == NULL)
return NULL;
selector_start++;
if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
return NULL;
llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
size_t len;
const char *start;
for (start = selector_start, len = ::strcspn(start, ":]");
start && *start != '\0' && *start != ']';
start += len + 1)
{
selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
}
if (selector_idents.size() == 0)
return 0;
clang::Selector method_selector = ast_context->Selectors.getSelector (selector_idents.size(),
selector_idents.data());
QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
// Populate the method decl with parameter decls
clang::Type *method_type(method_qual_type.getTypePtr());
if (method_type == NULL)
return NULL;
FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
if (!method_function_prototype)
return NULL;
bool is_variadic = false;
bool is_synthesized = false;
bool is_defined = false;
ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
const unsigned num_args = method_function_prototype->getNumArgs();
ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context,
SourceLocation(), // beginLoc,
SourceLocation(), // endLoc,
method_selector,
method_function_prototype->getResultType(),
NULL, // TypeSourceInfo *ResultTInfo,
GetDeclContextForType (class_opaque_type),
name[0] == '-',
is_variadic,
is_synthesized,
is_defined,
imp_control,
num_args);
if (objc_method_decl == NULL)
return NULL;
if (num_args > 0)
{
llvm::SmallVector<ParmVarDecl *, 12> params;
for (int param_index = 0; param_index < num_args; ++param_index)
{
params.push_back (ParmVarDecl::Create (*ast_context,
objc_method_decl,
SourceLocation(),
NULL, // anonymous
method_function_prototype->getArgType(param_index),
NULL,
SC_Auto,
SC_Auto,
NULL));
}
objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args);
}
class_interface_decl->addDecl (objc_method_decl);
return objc_method_decl;
}
#pragma mark Aggregate Types
@ -3044,6 +3176,32 @@ ClangASTContext::IsFloatingPointType (void *clang_type, uint32_t &count, bool &i
return false;
}
bool
ClangASTContext::IsCXXClassType (void *clang_type)
{
if (clang_type)
{
QualType qual_type (QualType::getFromOpaquePtr(clang_type));
if (qual_type->getAsCXXRecordDecl() != NULL)
return true;
}
return false;
}
bool
ClangASTContext::IsObjCClassType (void *clang_type)
{
if (clang_type)
{
QualType qual_type (QualType::getFromOpaquePtr(clang_type));
if (qual_type->isObjCObjectOrInterfaceType())
return true;
}
return false;
}
bool
ClangASTContext::IsCStringType (void *clang_type, uint32_t &length)