Added motheds to C++ classes as we parse them to keep clang happy.
llvm-svn: 114616
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 7aa203d..b3199cc 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1108,18 +1108,133 @@
case DW_TAG_subprogram:
{
+ DWARFDebugInfoEntry::Attributes attributes;
is_a_class = true;
if (default_accessibility == eAccessNone)
default_accessibility = eAccessPrivate;
- // TODO: implement DW_TAG_subprogram type parsing
-// UserDefTypeChildInfo method_info(die->GetOffset());
-//
-// FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset()));
-// if (func_sp.get() == NULL)
-// ParseCompileUnitFunction(sc, dwarf_cu, die);
-//
-// method_info.SetEncodingTypeUID(die->GetOffset());
-// struct_udt->AddMethod(method_info);
+
+ //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::FunctionDecl::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::FunctionDecl::None)
+ storage = clang::FunctionDecl::Extern;
+ else
+ storage = clang::FunctionDecl::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());
+ }
}
break;
@@ -1913,6 +2028,7 @@
TypeSP& type_sp,
const DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
+ bool skip_artificial,
TypeList* type_list,
std::vector<void *>& function_param_types,
std::vector<clang::ParmVarDecl*>& function_param_decls
@@ -1939,6 +2055,7 @@
const char *name = NULL;
Declaration decl;
dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
+ bool is_artificial = false;
// one of None, Auto, Register, Extern, Static, PrivateExtern
clang::VarDecl::StorageClass storage = clang::VarDecl::None;
@@ -1956,6 +2073,7 @@
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
+ case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
case DW_AT_location:
// if (form_value.BlockData())
// {
@@ -1967,7 +2085,6 @@
// {
// }
// break;
- case DW_AT_artificial:
case DW_AT_const_value:
case DW_AT_default_value:
case DW_AT_description:
@@ -1982,6 +2099,10 @@
}
}
}
+
+ if (skip_artificial && is_artificial)
+ continue;
+
Type *dc_type = ResolveTypeUID(param_type_die_offset);
if (dc_type)
{
@@ -2717,7 +2838,7 @@
const char *mangled = NULL;
dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Declaration decl;
- bool isVariadic = false;
+ bool is_variadic = false;
bool is_inline = false;
unsigned type_quals = 0;
clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern
@@ -2805,9 +2926,10 @@
std::vector<clang::ParmVarDecl*> function_param_decls;
// Parse the function children for the parameters
- ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls);
+ bool skip_artificial = false;
+ ParseChildParameters(sc, type_sp, dwarf_cu, die, skip_artificial, type_list, function_param_types, function_param_decls);
- clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals);
+ 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);