[Lldb-commits] [lldb] r361471 - DWARFASTParserClang: Reduce indentation
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Thu May 23 02:41:39 PDT 2019
Author: labath
Date: Thu May 23 02:41:39 2019
New Revision: 361471
URL: http://llvm.org/viewvc/llvm-project?rev=361471&view=rev
Log:
DWARFASTParserClang: Reduce indentation
by two levels via early returns.
Modified:
lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=361471&r1=361470&r2=361471&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Thu May 23 02:41:39 2019
@@ -231,1673 +231,1661 @@ static void CompleteExternalTagDeclType(
TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
const DWARFDIE &die, Log *log,
bool *type_is_new_ptr) {
- TypeSP type_sp;
-
if (type_is_new_ptr)
*type_is_new_ptr = false;
AccessType accessibility = eAccessNone;
- if (die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- if (log) {
- DWARFDIE context_die;
- clang::DeclContext *context =
- GetClangDeclContextContainingDIE(die, &context_die);
-
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die "
- "0x%8.8x)) %s name = '%s')",
- die.GetOffset(), static_cast<void *>(context),
- context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
- }
- Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
- TypeList *type_list = dwarf->GetTypeList();
- if (type_ptr == NULL) {
- if (type_is_new_ptr)
- *type_is_new_ptr = true;
-
- const dw_tag_t tag = die.Tag();
-
- bool is_forward_declaration = false;
- DWARFAttributes attributes;
- const char *type_name_cstr = NULL;
- const char *mangled_name_cstr = NULL;
- ConstString type_name_const_str;
- Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
- llvm::Optional<uint64_t> byte_size;
- Declaration decl;
-
- Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
- CompilerType clang_type;
- DWARFFormValue form_value;
-
- dw_attr_t attr;
-
- switch (tag) {
- case DW_TAG_typedef:
- case DW_TAG_base_type:
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_const_type:
- case DW_TAG_restrict_type:
- case DW_TAG_volatile_type:
- case DW_TAG_unspecified_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- const size_t num_attributes = die.GetAttributes(attributes);
- uint32_t encoding = 0;
- DWARFFormValue encoding_uid;
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(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();
- if (type_name_cstr)
- type_name_const_str.SetCString(type_name_cstr);
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_encoding:
- encoding = form_value.Unsigned();
- break;
- case DW_AT_type:
- encoding_uid = form_value;
- break;
- default:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
+ if (!die)
+ return nullptr;
- if (tag == DW_TAG_typedef && encoding_uid.IsValid()) {
- // Try to parse a typedef from the DWO file first as modules can
- // contain typedef'ed structures that have no names like:
- //
- // typedef struct { int a; } Foo;
- //
- // In this case we will have a structure with no name and a typedef
- // named "Foo" that points to this unnamed structure. The name in the
- // typedef is the only identifier for the struct, so always try to
- // get typedefs from DWO files if possible.
- //
- // The type_sp returned will be empty if the typedef doesn't exist in
- // a DWO file, so it is cheap to call this function just to check.
- //
- // If we don't do this we end up creating a TypeSP that says this is
- // a typedef to type 0x123 (the DW_AT_type value would be 0x123 in
- // the DW_TAG_typedef), and this is the unnamed structure type. We
- // will have a hard time tracking down an unnammed structure type in
- // the module DWO file, so we make sure we don't get into this
- // situation by always resolving typedefs from the DWO file.
- const DWARFDIE encoding_die = encoding_uid.Reference();
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ if (log) {
+ DWARFDIE context_die;
+ clang::DeclContext *context =
+ GetClangDeclContextContainingDIE(die, &context_die);
+
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die "
+ "0x%8.8x)) %s name = '%s')",
+ die.GetOffset(), static_cast<void *>(context), context_die.GetOffset(),
+ die.GetTagAsCString(), die.GetName());
+ }
- // First make sure that the die that this is typedef'ed to _is_ just
- // a declaration (DW_AT_declaration == 1), not a full definition
- // since template types can't be represented in modules since only
- // concrete instances of templates are ever emitted and modules won't
- // contain those
- if (encoding_die &&
- encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) ==
- 1) {
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
- }
- }
+ Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
+ if (type_ptr == DIE_IS_BEING_PARSED)
+ return nullptr;
+ if (type_ptr)
+ return type_ptr->shared_from_this();
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n",
- die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr,
- encoding_uid.Reference());
+ TypeList *type_list = dwarf->GetTypeList();
+ if (type_is_new_ptr)
+ *type_is_new_ptr = true;
- switch (tag) {
- default:
- break;
+ const dw_tag_t tag = die.Tag();
- case DW_TAG_unspecified_type:
- if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
- strcmp(type_name_cstr, "decltype(nullptr)") == 0) {
- resolve_state = Type::eResolveStateFull;
- clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
+ bool is_forward_declaration = false;
+ DWARFAttributes attributes;
+ const char *type_name_cstr = NULL;
+ const char *mangled_name_cstr = NULL;
+ ConstString type_name_const_str;
+ Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
+ llvm::Optional<uint64_t> byte_size;
+ Declaration decl;
+
+ Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
+ CompilerType clang_type;
+ DWARFFormValue form_value;
+
+ dw_attr_t attr;
+ TypeSP type_sp;
+ switch (tag) {
+ case DW_TAG_typedef:
+ case DW_TAG_base_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_const_type:
+ case DW_TAG_restrict_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_unspecified_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ const size_t num_attributes = die.GetAttributes(attributes);
+ uint32_t encoding = 0;
+ DWARFFormValue encoding_uid;
+
+ if (num_attributes > 0) {
+ uint32_t i;
+ for (i = 0; i < num_attributes; ++i) {
+ attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(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();
+ if (type_name_cstr)
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_encoding:
+ encoding = form_value.Unsigned();
+ break;
+ case DW_AT_type:
+ encoding_uid = form_value;
+ break;
+ default:
+ case DW_AT_sibling:
break;
}
- // Fall through to base type below in case we can handle the type
- // there...
- LLVM_FALLTHROUGH;
-
- case DW_TAG_base_type:
- resolve_state = Type::eResolveStateFull;
- clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
- type_name_cstr, encoding, byte_size.getValueOr(0) * 8);
- break;
-
- case DW_TAG_pointer_type:
- encoding_data_type = Type::eEncodingIsPointerUID;
- break;
- case DW_TAG_reference_type:
- encoding_data_type = Type::eEncodingIsLValueReferenceUID;
- break;
- case DW_TAG_rvalue_reference_type:
- encoding_data_type = Type::eEncodingIsRValueReferenceUID;
- break;
- case DW_TAG_typedef:
- encoding_data_type = Type::eEncodingIsTypedefUID;
- break;
- case DW_TAG_const_type:
- encoding_data_type = Type::eEncodingIsConstUID;
- break;
- case DW_TAG_restrict_type:
- encoding_data_type = Type::eEncodingIsRestrictUID;
- break;
- case DW_TAG_volatile_type:
- encoding_data_type = Type::eEncodingIsVolatileUID;
- break;
}
+ }
+ }
- if (!clang_type &&
- (encoding_data_type == Type::eEncodingIsPointerUID ||
- encoding_data_type == Type::eEncodingIsTypedefUID)) {
- if (tag == DW_TAG_pointer_type) {
- DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
-
- if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) {
- // Blocks have a __FuncPtr inside them which is a pointer to a
- // function of the proper type.
-
- for (DWARFDIE child_die = target_die.GetFirstChild();
- child_die.IsValid(); child_die = child_die.GetSibling()) {
- if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
- "__FuncPtr")) {
- DWARFDIE function_pointer_type =
- child_die.GetReferencedDIE(DW_AT_type);
-
- if (function_pointer_type) {
- DWARFDIE function_type =
- function_pointer_type.GetReferencedDIE(DW_AT_type);
-
- bool function_type_is_new_pointer;
- TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
- sc, function_type, log, &function_type_is_new_pointer);
-
- if (lldb_function_type_sp) {
- clang_type = m_ast.CreateBlockPointerType(
- lldb_function_type_sp->GetForwardCompilerType());
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- }
- }
+ if (tag == DW_TAG_typedef && encoding_uid.IsValid()) {
+ // Try to parse a typedef from the DWO file first as modules can
+ // contain typedef'ed structures that have no names like:
+ //
+ // typedef struct { int a; } Foo;
+ //
+ // In this case we will have a structure with no name and a typedef
+ // named "Foo" that points to this unnamed structure. The name in the
+ // typedef is the only identifier for the struct, so always try to
+ // get typedefs from DWO files if possible.
+ //
+ // The type_sp returned will be empty if the typedef doesn't exist in
+ // a DWO file, so it is cheap to call this function just to check.
+ //
+ // If we don't do this we end up creating a TypeSP that says this is
+ // a typedef to type 0x123 (the DW_AT_type value would be 0x123 in
+ // the DW_TAG_typedef), and this is the unnamed structure type. We
+ // will have a hard time tracking down an unnammed structure type in
+ // the module DWO file, so we make sure we don't get into this
+ // situation by always resolving typedefs from the DWO file.
+ const DWARFDIE encoding_die = encoding_uid.Reference();
+
+ // First make sure that the die that this is typedef'ed to _is_ just
+ // a declaration (DW_AT_declaration == 1), not a full definition
+ // since template types can't be represented in modules since only
+ // concrete instances of templates are ever emitted and modules won't
+ // contain those
+ if (encoding_die &&
+ encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+ }
+ }
- break;
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n",
+ die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr,
+ encoding_uid.Reference());
+
+ switch (tag) {
+ default:
+ break;
+
+ case DW_TAG_unspecified_type:
+ if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
+ strcmp(type_name_cstr, "decltype(nullptr)") == 0) {
+ resolve_state = Type::eResolveStateFull;
+ clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
+ break;
+ }
+ // Fall through to base type below in case we can handle the type
+ // there...
+ LLVM_FALLTHROUGH;
+
+ case DW_TAG_base_type:
+ resolve_state = Type::eResolveStateFull;
+ clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
+ type_name_cstr, encoding, byte_size.getValueOr(0) * 8);
+ break;
+
+ case DW_TAG_pointer_type:
+ encoding_data_type = Type::eEncodingIsPointerUID;
+ break;
+ case DW_TAG_reference_type:
+ encoding_data_type = Type::eEncodingIsLValueReferenceUID;
+ break;
+ case DW_TAG_rvalue_reference_type:
+ encoding_data_type = Type::eEncodingIsRValueReferenceUID;
+ break;
+ case DW_TAG_typedef:
+ encoding_data_type = Type::eEncodingIsTypedefUID;
+ break;
+ case DW_TAG_const_type:
+ encoding_data_type = Type::eEncodingIsConstUID;
+ break;
+ case DW_TAG_restrict_type:
+ encoding_data_type = Type::eEncodingIsRestrictUID;
+ break;
+ case DW_TAG_volatile_type:
+ encoding_data_type = Type::eEncodingIsVolatileUID;
+ break;
+ }
+
+ if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID ||
+ encoding_data_type == Type::eEncodingIsTypedefUID)) {
+ if (tag == DW_TAG_pointer_type) {
+ DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
+
+ if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) {
+ // Blocks have a __FuncPtr inside them which is a pointer to a
+ // function of the proper type.
+
+ for (DWARFDIE child_die = target_die.GetFirstChild();
+ child_die.IsValid(); child_die = child_die.GetSibling()) {
+ if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
+ "__FuncPtr")) {
+ DWARFDIE function_pointer_type =
+ child_die.GetReferencedDIE(DW_AT_type);
+
+ if (function_pointer_type) {
+ DWARFDIE function_type =
+ function_pointer_type.GetReferencedDIE(DW_AT_type);
+
+ bool function_type_is_new_pointer;
+ TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
+ sc, function_type, log, &function_type_is_new_pointer);
+
+ if (lldb_function_type_sp) {
+ clang_type = m_ast.CreateBlockPointerType(
+ lldb_function_type_sp->GetForwardCompilerType());
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
}
}
+
+ break;
}
}
+ }
+ }
- bool translation_unit_is_objc =
- (sc.comp_unit->GetLanguage() == eLanguageTypeObjC ||
- sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
-
- if (translation_unit_is_objc) {
- if (type_name_cstr != NULL) {
- static ConstString g_objc_type_name_id("id");
- static ConstString g_objc_type_name_Class("Class");
- static ConstString g_objc_type_name_selector("SEL");
+ bool translation_unit_is_objc =
+ (sc.comp_unit->GetLanguage() == eLanguageTypeObjC ||
+ sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
+
+ if (translation_unit_is_objc) {
+ if (type_name_cstr != NULL) {
+ static ConstString g_objc_type_name_id("id");
+ static ConstString g_objc_type_name_Class("Class");
+ static ConstString g_objc_type_name_selector("SEL");
- if (type_name_const_str == g_objc_type_name_id) {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective-C 'id' built-in type.",
- die.GetOffset(), die.GetTagAsCString(), die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
+ if (type_name_const_str == g_objc_type_name_id) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective-C 'id' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
- } else if (type_name_const_str == g_objc_type_name_Class) {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective-C 'Class' built-in type.",
- die.GetOffset(), die.GetTagAsCString(), die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- } else if (type_name_const_str == g_objc_type_name_selector) {
+ } else if (type_name_const_str == g_objc_type_name_Class) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective-C 'Class' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
+ } else if (type_name_const_str == g_objc_type_name_selector) {
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
+ "is Objective-C 'selector' built-in type.",
+ die.GetOffset(), die.GetTagAsCString(), die.GetName());
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid.Clear();
+ resolve_state = Type::eResolveStateFull;
+ }
+ } else if (encoding_data_type == Type::eEncodingIsPointerUID &&
+ encoding_uid.IsValid()) {
+ // Clang sometimes erroneously emits id as objc_object*. In that
+ // case we fix up the type to "id".
+
+ const DWARFDIE encoding_die = encoding_uid.Reference();
+
+ if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
+ if (const char *struct_name = encoding_die.GetName()) {
+ if (!strcmp(struct_name, "objc_object")) {
if (log)
dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
- "is Objective-C 'selector' built-in type.",
+ log,
+ "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s "
+ "'%s' is 'objc_object*', which we overrode to "
+ "'id'.",
die.GetOffset(), die.GetTagAsCString(), die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
+ clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
encoding_data_type = Type::eEncodingIsUID;
encoding_uid.Clear();
resolve_state = Type::eResolveStateFull;
}
- } else if (encoding_data_type == Type::eEncodingIsPointerUID &&
- encoding_uid.IsValid()) {
- // Clang sometimes erroneously emits id as objc_object*. In that
- // case we fix up the type to "id".
-
- const DWARFDIE encoding_die = encoding_uid.Reference();
-
- if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
- if (const char *struct_name = encoding_die.GetName()) {
- if (!strcmp(struct_name, "objc_object")) {
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s "
- "'%s' is 'objc_object*', which we overrode to "
- "'id'.",
- die.GetOffset(), die.GetTagAsCString(),
- die.GetName());
- clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid.Clear();
- resolve_state = Type::eResolveStateFull;
- }
- }
- }
}
}
}
+ }
+ }
- type_sp = std::make_shared<Type>(
- die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
- dwarf->GetUID(DIERef(encoding_uid)), encoding_data_type, &decl,
- clang_type, resolve_state);
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
+ dwarf->GetUID(DIERef(encoding_uid)), encoding_data_type, &decl,
+ clang_type, resolve_state);
+
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ } break;
+
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ LanguageType class_language = eLanguageTypeUnknown;
+ bool is_complete_objc_class = false;
+ size_t calling_convention = llvm::dwarf::CallingConvention::DW_CC_normal;
+
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes > 0) {
+ uint32_t i;
+ for (i = 0; i < num_attributes; ++i) {
+ attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_decl_file:
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
+ break;
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- } break;
+ case DW_AT_decl_line:
+ decl.SetLine(form_value.Unsigned());
+ break;
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_class_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- LanguageType class_language = eLanguageTypeUnknown;
- bool is_complete_objc_class = false;
- size_t calling_convention
- = llvm::dwarf::CallingConvention::DW_CC_normal;
-
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(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();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
-
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
-
- case DW_AT_declaration:
- is_forward_declaration = form_value.Boolean();
- break;
-
- case DW_AT_APPLE_runtime_class:
- class_language = (LanguageType)form_value.Signed();
- break;
-
- case DW_AT_APPLE_objc_complete_type:
- is_complete_objc_class = form_value.Signed();
- break;
- case DW_AT_calling_convention:
- calling_convention = form_value.Unsigned();
- break;
-
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- default:
- case DW_AT_sibling:
- break;
- }
- }
- }
- }
+ case DW_AT_decl_column:
+ decl.SetColumn(form_value.Unsigned());
+ break;
- // UniqueDWARFASTType is large, so don't create a local variables on
- // the stack, put it on the heap. This function is often called
- // recursively and clang isn't good and sharing the stack space for
- // variables in different blocks.
- std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_up(
- new UniqueDWARFASTType());
-
- ConstString unique_typename(type_name_const_str);
- Declaration unique_decl(decl);
-
- if (type_name_const_str) {
- LanguageType die_language = die.GetLanguage();
- if (Language::LanguageIsCPlusPlus(die_language)) {
- // For C++, we rely solely upon the one definition rule that says
- // only one thing can exist at a given decl context. We ignore the
- // file and line that things are declared on.
- std::string qualified_name;
- if (die.GetQualifiedName(qualified_name))
- unique_typename = ConstString(qualified_name);
- unique_decl.Clear();
- }
-
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(
- unique_typename, die, unique_decl,
- byte_size ? *byte_size : -1, *unique_ast_entry_up)) {
- type_sp = unique_ast_entry_up->m_type_sp;
- if (type_sp) {
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
+ case DW_AT_name:
+ type_name_cstr = form_value.AsCString();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
+
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
+
+ case DW_AT_declaration:
+ is_forward_declaration = form_value.Boolean();
+ break;
+
+ case DW_AT_APPLE_runtime_class:
+ class_language = (LanguageType)form_value.Signed();
+ break;
+
+ case DW_AT_APPLE_objc_complete_type:
+ is_complete_objc_class = form_value.Signed();
+ break;
+ case DW_AT_calling_convention:
+ calling_convention = form_value.Unsigned();
+ break;
+
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_data_location:
+ case DW_AT_description:
+ case DW_AT_start_scope:
+ case DW_AT_visibility:
+ default:
+ case DW_AT_sibling:
+ break;
}
}
+ }
+ }
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
+ // UniqueDWARFASTType is large, so don't create a local variables on
+ // the stack, put it on the heap. This function is often called
+ // recursively and clang isn't good and sharing the stack space for
+ // variables in different blocks.
+ std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_up(
+ new UniqueDWARFASTType());
+
+ ConstString unique_typename(type_name_const_str);
+ Declaration unique_decl(decl);
+
+ if (type_name_const_str) {
+ LanguageType die_language = die.GetLanguage();
+ if (Language::LanguageIsCPlusPlus(die_language)) {
+ // For C++, we rely solely upon the one definition rule that says
+ // only one thing can exist at a given decl context. We ignore the
+ // file and line that things are declared on.
+ std::string qualified_name;
+ if (die.GetQualifiedName(qualified_name))
+ unique_typename = ConstString(qualified_name);
+ unique_decl.Clear();
+ }
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type) {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- } else if (tag == DW_TAG_union_type) {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- } else if (tag == DW_TAG_class_type) {
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
-
- if (byte_size && *byte_size == 0 && type_name_cstr &&
- !die.HasChildren() &&
- sc.comp_unit->GetLanguage() == eLanguageTypeObjC) {
- // Work around an issue with clang at the moment where forward
- // declarations for objective C classes are emitted as:
- // DW_TAG_structure_type [2]
- // DW_AT_name( "ForwardObjcClass" )
- // DW_AT_byte_size( 0x00 )
- // DW_AT_decl_file( "..." )
- // DW_AT_decl_line( 1 )
- //
- // Note that there is no DW_AT_declaration and there are no children,
- // and the byte size is zero.
- is_forward_declaration = true;
- }
-
- if (class_language == eLanguageTypeObjC ||
- class_language == eLanguageTypeObjC_plus_plus) {
- if (!is_complete_objc_class &&
- die.Supports_DW_AT_APPLE_objc_complete_type()) {
- // We have a valid eSymbolTypeObjCClass class symbol whose name
- // matches the current objective C class that we are trying to find
- // and this DIE isn't the complete definition (we checked
- // is_complete_objc_class above and know it is false), so the real
- // definition is in here somewhere
- type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE(
- die, type_name_const_str, true);
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(
+ unique_typename, die, unique_decl, byte_size ? *byte_size : -1,
+ *unique_ast_entry_up)) {
+ type_sp = unique_ast_entry_up->m_type_sp;
+ if (type_sp) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
+ }
+ }
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp =
- debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
- die, type_name_const_str, true);
- }
- }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
- "incomplete objc type, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr,
- type_sp->GetID());
- }
+ int tag_decl_kind = -1;
+ AccessType default_accessibility = eAccessNone;
+ if (tag == DW_TAG_structure_type) {
+ tag_decl_kind = clang::TTK_Struct;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_union_type) {
+ tag_decl_kind = clang::TTK_Union;
+ default_accessibility = eAccessPublic;
+ } else if (tag == DW_TAG_class_type) {
+ tag_decl_kind = clang::TTK_Class;
+ default_accessibility = eAccessPrivate;
+ }
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this
- // die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
+ if (byte_size && *byte_size == 0 && type_name_cstr && !die.HasChildren() &&
+ sc.comp_unit->GetLanguage() == eLanguageTypeObjC) {
+ // Work around an issue with clang at the moment where forward
+ // declarations for objective C classes are emitted as:
+ // DW_TAG_structure_type [2]
+ // DW_AT_name( "ForwardObjcClass" )
+ // DW_AT_byte_size( 0x00 )
+ // DW_AT_decl_file( "..." )
+ // DW_AT_decl_line( 1 )
+ //
+ // Note that there is no DW_AT_declaration and there are no children,
+ // and the byte size is zero.
+ is_forward_declaration = true;
+ }
+
+ if (class_language == eLanguageTypeObjC ||
+ class_language == eLanguageTypeObjC_plus_plus) {
+ if (!is_complete_objc_class &&
+ die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ // We have a valid eSymbolTypeObjCClass class symbol whose name
+ // matches the current objective C class that we are trying to find
+ // and this DIE isn't the complete definition (we checked
+ // is_complete_objc_class above and know it is false), so the real
+ // definition is in here somewhere
+ type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name_const_str, true);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
+ die, type_name_const_str, true);
}
}
- if (is_forward_declaration) {
- // We have a forward declaration to a type and we need to try and
- // find a full declaration. We look in the current type index just in
- // case we have a forward declaration followed by an actual
- // declarations in the DWARF. If this fails, we need to look
- // elsewhere...
+ if (type_sp) {
if (log) {
dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, trying to find complete type",
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
+ "incomplete objc type, complete type is 0x%8.8" PRIx64,
static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr);
+ DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
}
- // See if the type comes from a DWO module and if so, track down that
- // type.
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
- // type_name_const_str);
- type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF, see
- // if we have a declaration anywhere else...
- type_sp =
- debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
- die_decl_ctx);
- }
- }
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
+ }
+ }
+
+ if (is_forward_declaration) {
+ // We have a forward declaration to a type and we need to try and
+ // find a full declaration. We look in the current type index just in
+ // case we have a forward declaration followed by an actual
+ // declarations in the DWARF. If this fails, we need to look
+ // elsewhere...
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, trying to find complete type",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+ }
+
+ // See if the type comes from a DWO module and if so, track down that
+ // type.
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
+
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
+
+ // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
+ // type_name_const_str);
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF, see
+ // if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
+ }
+ }
+
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
+ }
+
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ assert(tag_decl_kind != -1);
+ bool clang_type_was_created = false;
+ clang_type.SetCompilerType(
+ &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ clang::DeclContext *decl_ctx =
+ GetClangDeclContextContainingDIE(die, nullptr);
+
+ // If your decl context is a record that was imported from another
+ // AST context (in the gmodules case), we need to make sure the type
+ // backing the Decl is complete before adding children to it. This is
+ // not an issue in the non-gmodules case because the debug info will
+ // always contain a full definition of parent types in that case.
+ CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
+ type_name_cstr);
+
+ if (accessibility == eAccessNone && decl_ctx) {
+ // Check the decl context that contains this class/struct/union. If
+ // it is a class we must give it an accessibility.
+ const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
+ if (DeclKindIsCXXClass(containing_decl_kind))
+ accessibility = default_accessibility;
+ }
- if (type_sp) {
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+ metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
+
+ if (type_name_cstr && strchr(type_name_cstr, '<')) {
+ ClangASTContext::TemplateParameterInfos template_param_infos;
+ if (ParseTemplateParameterInfos(die, template_param_infos)) {
+ clang::ClassTemplateDecl *class_template_decl =
+ m_ast.ParseClassTemplateDecl(decl_ctx, accessibility,
+ type_name_cstr, tag_decl_kind,
+ template_param_infos);
+ if (!class_template_decl) {
if (log) {
dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, complete type is 0x%8.8" PRIx64,
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
+ "clang::ClassTemplateDecl failed to return a decl.",
static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
+ DW_TAG_value_to_name(tag), type_name_cstr);
}
+ return TypeSP();
+ }
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
- dwarf->GetDIE(type_sp->GetID()));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
- }
- assert(tag_decl_kind != -1);
- bool clang_type_was_created = false;
- clang_type.SetCompilerType(
- &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
- if (!clang_type) {
- clang::DeclContext *decl_ctx =
- GetClangDeclContextContainingDIE(die, nullptr);
-
- // If your decl context is a record that was imported from another
- // AST context (in the gmodules case), we need to make sure the type
- // backing the Decl is complete before adding children to it. This is
- // not an issue in the non-gmodules case because the debug info will
- // always contain a full definition of parent types in that case.
- CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
- type_name_cstr);
-
- if (accessibility == eAccessNone && decl_ctx) {
- // Check the decl context that contains this class/struct/union. If
- // it is a class we must give it an accessibility.
- const clang::Decl::Kind containing_decl_kind =
- decl_ctx->getDeclKind();
- if (DeclKindIsCXXClass(containing_decl_kind))
- accessibility = default_accessibility;
- }
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
- metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
+ clang::ClassTemplateSpecializationDecl *class_specialization_decl =
+ m_ast.CreateClassTemplateSpecializationDecl(
+ decl_ctx, class_template_decl, tag_decl_kind,
+ template_param_infos);
+ clang_type = m_ast.CreateClassTemplateSpecializationType(
+ class_specialization_decl);
+ clang_type_was_created = true;
- if (type_name_cstr && strchr(type_name_cstr, '<')) {
- ClangASTContext::TemplateParameterInfos template_param_infos;
- if (ParseTemplateParameterInfos(die, template_param_infos)) {
- clang::ClassTemplateDecl *class_template_decl =
- m_ast.ParseClassTemplateDecl(decl_ctx, accessibility,
- type_name_cstr, tag_decl_kind,
- template_param_infos);
- if (!class_template_decl) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" "
- "clang::ClassTemplateDecl failed to return a decl.",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr);
- }
- return TypeSP();
- }
-
- clang::ClassTemplateSpecializationDecl
- *class_specialization_decl =
- m_ast.CreateClassTemplateSpecializationDecl(
- decl_ctx, class_template_decl, tag_decl_kind,
- template_param_infos);
- clang_type = m_ast.CreateClassTemplateSpecializationType(
- class_specialization_decl);
- clang_type_was_created = true;
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
+ }
+ }
- m_ast.SetMetadata(class_template_decl, metadata);
- m_ast.SetMetadata(class_specialization_decl, metadata);
- }
- }
+ if (!clang_type_was_created) {
+ clang_type_was_created = true;
+ clang_type =
+ m_ast.CreateRecordType(decl_ctx, accessibility, type_name_cstr,
+ tag_decl_kind, class_language, &metadata);
+ }
+ }
- if (!clang_type_was_created) {
- clang_type_was_created = true;
- clang_type = m_ast.CreateRecordType(decl_ctx, accessibility,
- type_name_cstr, tag_decl_kind,
- class_language, &metadata);
- }
+ // Store a forward declaration to this class type in case any
+ // parameters in any class methods need it for the clang types for
+ // function prototypes.
+ LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
+ type_sp = std::make_shared<Type>(die.GetID(), dwarf, type_name_const_str,
+ byte_size, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, &decl, clang_type,
+ Type::eResolveStateForward);
+
+ type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
+
+ // Add our type to the unique type map so we don't end up creating many
+ // copies of the same type over and over in the ASTContext for our
+ // module
+ unique_ast_entry_up->m_type_sp = type_sp;
+ unique_ast_entry_up->m_die = die;
+ unique_ast_entry_up->m_declaration = unique_decl;
+ unique_ast_entry_up->m_byte_size = byte_size.getValueOr(0);
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
+ *unique_ast_entry_up);
+
+ if (is_forward_declaration && die.HasChildren()) {
+ // Check to see if the DIE actually has a definition, some version of
+ // GCC will
+ // emit DIEs with DW_AT_declaration set to true, but yet still have
+ // subprogram, members, or inheritance, so we can't trust it
+ DWARFDIE child_die = die.GetFirstChild();
+ while (child_die) {
+ switch (child_die.Tag()) {
+ case DW_TAG_inheritance:
+ case DW_TAG_subprogram:
+ case DW_TAG_member:
+ case DW_TAG_APPLE_property:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ child_die.Clear();
+ is_forward_declaration = false;
+ break;
+ default:
+ child_die = child_die.GetSibling();
+ break;
}
-
- // Store a forward declaration to this class type in case any
- // parameters in any class methods need it for the clang types for
- // function prototypes.
- LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
- type_sp = std::make_shared<Type>(
- die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, clang_type,
- Type::eResolveStateForward);
+ }
+ }
- type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
+ if (!is_forward_declaration) {
+ // Always start the definition for a class type so that if the class
+ // has child classes or types that require the class to be created
+ // for use as their decl contexts the class will be ready to accept
+ // these child definitions.
+ if (!die.HasChildren()) {
+ // No children for this struct/union/class, lets finish it
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), type_name_cstr);
+ }
+
+ if (tag == DW_TAG_structure_type) // this only applies in C
+ {
+ clang::RecordDecl *record_decl =
+ ClangASTContext::GetAsRecordDecl(clang_type);
- // Add our type to the unique type map so we don't end up creating many
- // copies of the same type over and over in the ASTContext for our
- // module
- unique_ast_entry_up->m_type_sp = type_sp;
- unique_ast_entry_up->m_die = die;
- unique_ast_entry_up->m_declaration = unique_decl;
- unique_ast_entry_up->m_byte_size = byte_size.getValueOr(0);
- dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
- *unique_ast_entry_up);
-
- if (is_forward_declaration && die.HasChildren()) {
- // Check to see if the DIE actually has a definition, some version of
- // GCC will
- // emit DIEs with DW_AT_declaration set to true, but yet still have
- // subprogram, members, or inheritance, so we can't trust it
- DWARFDIE child_die = die.GetFirstChild();
- while (child_die) {
- switch (child_die.Tag()) {
- case DW_TAG_inheritance:
- case DW_TAG_subprogram:
- case DW_TAG_member:
- case DW_TAG_APPLE_property:
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- child_die.Clear();
- is_forward_declaration = false;
- break;
- default:
- child_die = child_die.GetSibling();
- break;
- }
+ if (record_decl) {
+ GetClangASTImporter().InsertRecordDecl(
+ record_decl, ClangASTImporter::LayoutInfo());
}
}
+ } else if (clang_type_was_created) {
+ // Start the definition if the class is not objective C since the
+ // underlying decls respond to isCompleteDefinition(). Objective
+ // C decls don't respond to isCompleteDefinition() so we can't
+ // start the declaration definition right away. For C++
+ // class/union/structs we want to start the definition in case the
+ // class is needed as the declaration context for a contained class
+ // or type without the need to complete that type..
+
+ if (class_language != eLanguageTypeObjC &&
+ class_language != eLanguageTypeObjC_plus_plus)
+ ClangASTContext::StartTagDeclarationDefinition(clang_type);
+
+ // Leave this as a forward declaration until we need to know the
+ // details of the type. lldb_private::Type will automatically call
+ // the SymbolFile virtual function
+ // "SymbolFileDWARF::CompleteType(Type *)" When the definition
+ // needs to be defined.
+ assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+ ClangUtil::RemoveFastQualifiers(clang_type)
+ .GetOpaqueQualType()) &&
+ "Type already in the forward declaration map!");
+ // Can't assume m_ast.GetSymbolFile() is actually a
+ // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
+ // binaries.
+ dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
+ clang_type.GetOpaqueQualType();
+ dwarf->GetForwardDeclClangTypeToDie()
+ [ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] =
+ die.GetDIERef();
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+ }
+ }
- if (!is_forward_declaration) {
- // Always start the definition for a class type so that if the class
- // has child classes or types that require the class to be created
- // for use as their decl contexts the class will be ready to accept
- // these child definitions.
- if (!die.HasChildren()) {
- // No children for this struct/union/class, lets finish it
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
- "definition.\nPlease file a bug and attach the file at the "
- "start of this error message",
- die.GetOffset(), type_name_cstr);
- }
+ // If we made a clang type, set the trivial abi if applicable: We only
+ // do this for pass by value - which implies the Trivial ABI. There
+ // isn't a way to assert that something that would normally be pass by
+ // value is pass by reference, so we ignore that attribute if set.
+ if (calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl) {
+ record_decl->setHasTrivialSpecialMemberForCall();
+ }
+ }
- if (tag == DW_TAG_structure_type) // this only applies in C
- {
- clang::RecordDecl *record_decl =
- ClangASTContext::GetAsRecordDecl(clang_type);
-
- if (record_decl) {
- GetClangASTImporter().InsertRecordDecl(
- record_decl, ClangASTImporter::LayoutInfo());
- }
- }
- } else if (clang_type_was_created) {
- // Start the definition if the class is not objective C since the
- // underlying decls respond to isCompleteDefinition(). Objective
- // C decls don't respond to isCompleteDefinition() so we can't
- // start the declaration definition right away. For C++
- // class/union/structs we want to start the definition in case the
- // class is needed as the declaration context for a contained class
- // or type without the need to complete that type..
-
- if (class_language != eLanguageTypeObjC &&
- class_language != eLanguageTypeObjC_plus_plus)
- ClangASTContext::StartTagDeclarationDefinition(clang_type);
-
- // Leave this as a forward declaration until we need to know the
- // details of the type. lldb_private::Type will automatically call
- // the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)" When the definition
- // needs to be defined.
- assert(!dwarf->GetForwardDeclClangTypeToDie().count(
- ClangUtil::RemoveFastQualifiers(clang_type)
- .GetOpaqueQualType()) &&
- "Type already in the forward declaration map!");
- // Can't assume m_ast.GetSymbolFile() is actually a
- // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
- // binaries.
- dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
- clang_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()
- [ClangUtil::RemoveFastQualifiers(clang_type)
- .GetOpaqueQualType()] = die.GetDIERef();
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
- }
- }
-
- // If we made a clang type, set the trivial abi if applicable: We only
- // do this for pass by value - which implies the Trivial ABI. There
- // isn't a way to assert that something that would normally be pass by
- // value is pass by reference, so we ignore that attribute if set.
- if (calling_convention == llvm::dwarf::DW_CC_pass_by_value) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl) {
- record_decl->setHasTrivialSpecialMemberForCall();
+ if (calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ if (record_decl)
+ record_decl->setArgPassingRestrictions(
+ clang::RecordDecl::APK_CannotPassInRegs);
+ }
+
+ } break;
+
+ case DW_TAG_enumeration_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ bool is_scoped = false;
+ DWARFFormValue encoding_form;
+
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes > 0) {
+ uint32_t i;
+
+ for (i = 0; i < num_attributes; ++i) {
+ attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(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();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
+ case DW_AT_type:
+ encoding_form = form_value;
+ break;
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ break;
+ case DW_AT_accessibility:
+ break; // accessibility =
+ // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+ case DW_AT_declaration:
+ is_forward_declaration = form_value.Boolean();
+ break;
+ case DW_AT_enum_class:
+ is_scoped = form_value.Boolean();
+ break;
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_bit_stride:
+ case DW_AT_byte_stride:
+ case DW_AT_data_location:
+ case DW_AT_description:
+ case DW_AT_start_scope:
+ case DW_AT_visibility:
+ case DW_AT_specification:
+ case DW_AT_abstract_origin:
+ case DW_AT_sibling:
+ break;
}
}
+ }
- if (calling_convention == llvm::dwarf::DW_CC_pass_by_reference) {
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
- if (record_decl)
- record_decl->setArgPassingRestrictions(
- clang::RecordDecl::APK_CannotPassInRegs);
- }
-
- } break;
-
- case DW_TAG_enumeration_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- bool is_scoped = false;
- DWARFFormValue encoding_form;
-
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- uint32_t i;
-
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(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();
- type_name_const_str.SetCString(type_name_cstr);
- break;
- case DW_AT_type:
- encoding_form = form_value;
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_accessibility:
- break; // accessibility =
- // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration:
- is_forward_declaration = form_value.Boolean();
- break;
- case DW_AT_enum_class:
- is_scoped = form_value.Boolean();
- break;
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_bit_stride:
- case DW_AT_byte_stride:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
+ if (is_forward_declaration) {
+ type_sp = ParseTypeFromDWO(die, log);
+ if (type_sp)
+ return type_sp;
- if (is_forward_declaration) {
- type_sp = ParseTypeFromDWO(die, log);
- if (type_sp)
- return type_sp;
-
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- type_sp =
- dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp =
- debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
- die_decl_ctx);
- }
- }
+ DWARFDeclContext die_decl_ctx;
+ die.GetDWARFDeclContext(die_decl_ctx);
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
- "forward declaration, complete type is 0x%8.8" PRIx64,
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), type_name_cstr,
- type_sp->GetID());
- }
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this
- // die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx =
- GetCachedClangDeclContextForDIE(
- dwarf->GetDIE(type_sp->GetID()));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
+ die_decl_ctx);
}
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
+ }
- CompilerType enumerator_clang_type;
- clang_type.SetCompilerType(
- &m_ast,
- dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
- if (!clang_type) {
- if (encoding_form.IsValid()) {
- Type *enumerator_type =
- dwarf->ResolveTypeUID(DIERef(encoding_form));
- if (enumerator_type)
- enumerator_clang_type = enumerator_type->GetFullCompilerType();
- }
+ if (type_sp) {
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
+ "forward declaration, complete type is 0x%8.8" PRIx64,
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
+ }
- if (!enumerator_clang_type) {
- if (byte_size) {
- enumerator_clang_type =
- m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
- NULL, DW_ATE_signed, *byte_size * 8);
- } else {
- enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
- }
- }
+ // We found a real definition for this type elsewhere so lets use
+ // it and cache the fact that we found a complete type for this
+ // die
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+ clang::DeclContext *defn_decl_ctx =
+ GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
+ if (defn_decl_ctx)
+ LinkDeclContextToDIE(defn_decl_ctx, die);
+ return type_sp;
+ }
+ }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
- clang_type = m_ast.CreateEnumerationType(
- type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr),
- decl, enumerator_clang_type, is_scoped);
- } else {
+ CompilerType enumerator_clang_type;
+ clang_type.SetCompilerType(
+ &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+ if (!clang_type) {
+ if (encoding_form.IsValid()) {
+ Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form));
+ if (enumerator_type)
+ enumerator_clang_type = enumerator_type->GetFullCompilerType();
+ }
+
+ if (!enumerator_clang_type) {
+ if (byte_size) {
enumerator_clang_type =
- m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
+ m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
+ NULL, DW_ATE_signed, *byte_size * 8);
+ } else {
+ enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
}
+ }
- LinkDeclContextToDIE(
- ClangASTContext::GetDeclContextForType(clang_type), die);
+ clang_type = m_ast.CreateEnumerationType(
+ type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr),
+ decl, enumerator_clang_type, is_scoped);
+ } else {
+ enumerator_clang_type =
+ m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
+ }
- type_sp = std::make_shared<Type>(
- die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
- dwarf->GetUID(DIERef(encoding_form)), Type::eEncodingIsUID, &decl,
- clang_type, Type::eResolveStateForward);
-
- if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
- if (die.HasChildren()) {
- SymbolContext cu_sc(die.GetLLDBCompileUnit());
- bool is_signed = false;
- enumerator_clang_type.IsIntegerType(is_signed);
- ParseChildEnumerators(cu_sc, clang_type, is_signed,
- type_sp->GetByteSize().getValueOr(0), die);
- }
- ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
- "definition.\nPlease file a bug and attach the file at the "
- "start of this error message",
- die.GetOffset(), type_name_cstr);
- }
- }
- } break;
-
- case DW_TAG_inlined_subroutine:
- case DW_TAG_subprogram:
- case DW_TAG_subroutine_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- DWARFFormValue type_die_form;
- bool is_variadic = false;
- bool is_inline = false;
- bool is_static = false;
- bool is_virtual = false;
- bool is_explicit = false;
- bool is_artificial = false;
- bool has_template_params = false;
- DWARFFormValue specification_die_form;
- DWARFFormValue abstract_origin_die_form;
- DWARFDIE object_pointer_die;
-
- unsigned type_quals = 0;
- clang::StorageClass storage =
- clang::SC_None; //, Extern, Static, PrivateExtern
-
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(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();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name:
- mangled_name_cstr = form_value.AsCString();
- break;
- case DW_AT_type:
- type_die_form = form_value;
- break;
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
- case DW_AT_declaration:
- break; // is_forward_declaration = form_value.Boolean(); break;
- case DW_AT_inline:
- is_inline = form_value.Boolean();
- break;
- case DW_AT_virtuality:
- is_virtual = form_value.Boolean();
- break;
- case DW_AT_explicit:
- is_explicit = form_value.Boolean();
- break;
- case DW_AT_artificial:
- is_artificial = form_value.Boolean();
- break;
-
- case DW_AT_external:
- if (form_value.Unsigned()) {
- if (storage == clang::SC_None)
- storage = clang::SC_Extern;
- else
- storage = clang::SC_PrivateExtern;
- }
- break;
+ LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type),
+ die);
- case DW_AT_specification:
- specification_die_form = form_value;
- break;
-
- case DW_AT_abstract_origin:
- abstract_origin_die_form = form_value;
- break;
-
- case DW_AT_object_pointer:
- object_pointer_die = form_value.Reference();
- break;
-
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_address_class:
- case DW_AT_calling_convention:
- case DW_AT_data_location:
- case DW_AT_elemental:
- case DW_AT_entry_pc:
- case DW_AT_frame_base:
- case DW_AT_high_pc:
- case DW_AT_low_pc:
- 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_start_scope:
- case DW_AT_static_link:
- case DW_AT_trampoline:
- case DW_AT_visibility:
- case DW_AT_vtable_elem_location:
- case DW_AT_description:
- case DW_AT_sibling:
- break;
- }
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
+ dwarf->GetUID(DIERef(encoding_form)), Type::eEncodingIsUID, &decl,
+ clang_type, Type::eResolveStateForward);
+
+ if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
+ if (die.HasChildren()) {
+ SymbolContext cu_sc(die.GetLLDBCompileUnit());
+ bool is_signed = false;
+ enumerator_clang_type.IsIntegerType(is_signed);
+ ParseChildEnumerators(cu_sc, clang_type, is_signed,
+ type_sp->GetByteSize().getValueOr(0), die);
+ }
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
+ "definition.\nPlease file a bug and attach the file at the "
+ "start of this error message",
+ die.GetOffset(), type_name_cstr);
+ }
+ }
+ } break;
+
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ DWARFFormValue type_die_form;
+ bool is_variadic = false;
+ bool is_inline = false;
+ bool is_static = false;
+ bool is_virtual = false;
+ bool is_explicit = false;
+ bool is_artificial = false;
+ bool has_template_params = false;
+ DWARFFormValue specification_die_form;
+ DWARFFormValue abstract_origin_die_form;
+ DWARFDIE object_pointer_die;
+
+ unsigned type_quals = 0;
+ clang::StorageClass storage =
+ clang::SC_None; //, Extern, Static, PrivateExtern
+
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes > 0) {
+ uint32_t i;
+ for (i = 0; i < num_attributes; ++i) {
+ attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(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();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
+
+ case DW_AT_linkage_name:
+ case DW_AT_MIPS_linkage_name:
+ mangled_name_cstr = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
+ case DW_AT_declaration:
+ break; // is_forward_declaration = form_value.Boolean(); break;
+ case DW_AT_inline:
+ is_inline = form_value.Boolean();
+ break;
+ case DW_AT_virtuality:
+ is_virtual = form_value.Boolean();
+ break;
+ case DW_AT_explicit:
+ is_explicit = form_value.Boolean();
+ break;
+ case DW_AT_artificial:
+ is_artificial = form_value.Boolean();
+ 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_specification:
+ specification_die_form = form_value;
+ break;
+
+ case DW_AT_abstract_origin:
+ abstract_origin_die_form = form_value;
+ break;
+
+ case DW_AT_object_pointer:
+ object_pointer_die = form_value.Reference();
+ break;
+
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_address_class:
+ case DW_AT_calling_convention:
+ case DW_AT_data_location:
+ case DW_AT_elemental:
+ case DW_AT_entry_pc:
+ case DW_AT_frame_base:
+ case DW_AT_high_pc:
+ case DW_AT_low_pc:
+ 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_start_scope:
+ case DW_AT_static_link:
+ case DW_AT_trampoline:
+ case DW_AT_visibility:
+ case DW_AT_vtable_elem_location:
+ case DW_AT_description:
+ case DW_AT_sibling:
+ break;
}
}
+ }
+ }
- std::string object_pointer_name;
- if (object_pointer_die) {
- const char *object_pointer_name_cstr = object_pointer_die.GetName();
- if (object_pointer_name_cstr)
- object_pointer_name = object_pointer_name_cstr;
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- CompilerType return_clang_type;
- Type *func_type = NULL;
-
- if (type_die_form.IsValid())
- func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
-
- if (func_type)
- return_clang_type = func_type->GetForwardCompilerType();
- else
- return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
-
- std::vector<CompilerType> function_param_types;
- std::vector<clang::ParmVarDecl *> function_param_decls;
-
- // Parse the function children for the parameters
-
- DWARFDIE decl_ctx_die;
- clang::DeclContext *containing_decl_ctx =
- GetClangDeclContextContainingDIE(die, &decl_ctx_die);
- const clang::Decl::Kind containing_decl_kind =
- containing_decl_ctx->getDeclKind();
-
- bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
- // Start off static. This will be set to false in
- // ParseChildParameters(...) if we find a "this" parameters as the
- // first parameter
- if (is_cxx_method) {
- is_static = true;
- }
+ std::string object_pointer_name;
+ if (object_pointer_die) {
+ const char *object_pointer_name_cstr = object_pointer_die.GetName();
+ if (object_pointer_name_cstr)
+ object_pointer_name = object_pointer_name_cstr;
+ }
- if (die.HasChildren()) {
- bool skip_artificial = true;
- ParseChildParameters(*sc.comp_unit, containing_decl_ctx, die,
- skip_artificial, is_static, is_variadic,
- has_template_params, function_param_types,
- function_param_decls, type_quals);
- }
-
- bool ignore_containing_context = false;
- // Check for templatized class member functions. If we had any
- // DW_TAG_template_type_parameter or DW_TAG_template_value_parameter
- // the DW_TAG_subprogram DIE, then we can't let this become a method in
- // a class. Why? Because templatized functions are only emitted if one
- // of the templatized methods is used in the current compile unit and
- // we will end up with classes that may or may not include these member
- // functions and this means one class won't match another class
- // definition and it affects our ability to use a class in the clang
- // expression parser. So for the greater good, we currently must not
- // allow any template member functions in a class definition.
- if (is_cxx_method && has_template_params) {
- ignore_containing_context = true;
- is_cxx_method = false;
- }
-
- // clang_type will get the function prototype clang type after this
- // call
- clang_type = m_ast.CreateFunctionType(
- return_clang_type, function_param_types.data(),
- function_param_types.size(), is_variadic, type_quals);
-
- if (type_name_cstr) {
- bool type_handled = false;
- if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
- ObjCLanguage::MethodName objc_method(type_name_cstr, true);
- if (objc_method.IsValid(true)) {
- CompilerType class_opaque_type;
- ConstString class_name(objc_method.GetClassName());
- if (class_name) {
- TypeSP complete_objc_class_type_sp(
- dwarf->FindCompleteObjCDefinitionTypeForDIE(
- DWARFDIE(), class_name, false));
-
- if (complete_objc_class_type_sp) {
- CompilerType type_clang_forward_type =
- complete_objc_class_type_sp->GetForwardCompilerType();
- if (ClangASTContext::IsObjCObjectOrInterfaceType(
- type_clang_forward_type))
- class_opaque_type = type_clang_forward_type;
- }
- }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
- if (class_opaque_type) {
- // If accessibility isn't set to anything valid, assume public
- // for now...
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
-
- clang::ObjCMethodDecl *objc_method_decl =
- m_ast.AddMethodToObjCObjectType(
- class_opaque_type, type_name_cstr, clang_type,
- accessibility, is_artificial, is_variadic);
- type_handled = objc_method_decl != NULL;
- if (type_handled) {
- LinkDeclContextToDIE(
- ClangASTContext::GetAsDeclContext(objc_method_decl), die);
- m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), "
- "please file a bug and attach the file at the start of "
- "this error message",
- die.GetOffset(), tag, DW_TAG_value_to_name(tag));
+ CompilerType return_clang_type;
+ Type *func_type = NULL;
+
+ if (type_die_form.IsValid())
+ func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
+
+ if (func_type)
+ return_clang_type = func_type->GetForwardCompilerType();
+ else
+ return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
+
+ std::vector<CompilerType> function_param_types;
+ std::vector<clang::ParmVarDecl *> function_param_decls;
+
+ // Parse the function children for the parameters
+
+ DWARFDIE decl_ctx_die;
+ clang::DeclContext *containing_decl_ctx =
+ GetClangDeclContextContainingDIE(die, &decl_ctx_die);
+ const clang::Decl::Kind containing_decl_kind =
+ containing_decl_ctx->getDeclKind();
+
+ bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
+ // Start off static. This will be set to false in
+ // ParseChildParameters(...) if we find a "this" parameters as the
+ // first parameter
+ if (is_cxx_method) {
+ is_static = true;
+ }
+
+ if (die.HasChildren()) {
+ bool skip_artificial = true;
+ ParseChildParameters(*sc.comp_unit, containing_decl_ctx, die,
+ skip_artificial, is_static, is_variadic,
+ has_template_params, function_param_types,
+ function_param_decls, type_quals);
+ }
+
+ bool ignore_containing_context = false;
+ // Check for templatized class member functions. If we had any
+ // DW_TAG_template_type_parameter or DW_TAG_template_value_parameter
+ // the DW_TAG_subprogram DIE, then we can't let this become a method in
+ // a class. Why? Because templatized functions are only emitted if one
+ // of the templatized methods is used in the current compile unit and
+ // we will end up with classes that may or may not include these member
+ // functions and this means one class won't match another class
+ // definition and it affects our ability to use a class in the clang
+ // expression parser. So for the greater good, we currently must not
+ // allow any template member functions in a class definition.
+ if (is_cxx_method && has_template_params) {
+ ignore_containing_context = true;
+ is_cxx_method = false;
+ }
+
+ // clang_type will get the function prototype clang type after this
+ // call
+ clang_type = m_ast.CreateFunctionType(
+ return_clang_type, function_param_types.data(),
+ function_param_types.size(), is_variadic, type_quals);
+
+ if (type_name_cstr) {
+ bool type_handled = false;
+ if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
+ ObjCLanguage::MethodName objc_method(type_name_cstr, true);
+ if (objc_method.IsValid(true)) {
+ CompilerType class_opaque_type;
+ ConstString class_name(objc_method.GetClassName());
+ if (class_name) {
+ TypeSP complete_objc_class_type_sp(
+ dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(),
+ class_name, false));
+
+ if (complete_objc_class_type_sp) {
+ CompilerType type_clang_forward_type =
+ complete_objc_class_type_sp->GetForwardCompilerType();
+ if (ClangASTContext::IsObjCObjectOrInterfaceType(
+ type_clang_forward_type))
+ class_opaque_type = type_clang_forward_type;
+ }
+ }
+
+ if (class_opaque_type) {
+ // If accessibility isn't set to anything valid, assume public
+ // for now...
+ if (accessibility == eAccessNone)
+ accessibility = eAccessPublic;
+
+ clang::ObjCMethodDecl *objc_method_decl =
+ m_ast.AddMethodToObjCObjectType(
+ class_opaque_type, type_name_cstr, clang_type,
+ accessibility, is_artificial, is_variadic);
+ type_handled = objc_method_decl != NULL;
+ if (type_handled) {
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(objc_method_decl), die);
+ m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), "
+ "please file a bug and attach the file at the start of "
+ "this error message",
+ die.GetOffset(), tag, DW_TAG_value_to_name(tag));
+ }
+ }
+ } else if (is_cxx_method) {
+ // 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 = dwarf->ResolveType(decl_ctx_die);
+ if (class_type) {
+ bool alternate_defn = false;
+ if (class_type->GetID() != decl_ctx_die.GetID() ||
+ decl_ctx_die.GetContainingDWOModuleDIE()) {
+ alternate_defn = true;
+
+ // We uniqued the parent class of this function to another
+ // class so we now need to associate all dies under
+ // "decl_ctx_die" to DIEs in the DIE for "class_type"...
+ DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID());
+
+ if (class_type_die) {
+ std::vector<DWARFDIE> failures;
+
+ CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
+ class_type, failures);
+
+ // FIXME do something with these failures that's smarter
+ // than
+ // just dropping them on the ground. Unfortunately classes
+ // don't like having stuff added to them after their
+ // definitions are complete...
+
+ type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
+ type_sp = type_ptr->shared_from_this();
+ break;
}
}
- } else if (is_cxx_method) {
- // 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 = dwarf->ResolveType(decl_ctx_die);
- if (class_type) {
- bool alternate_defn = false;
- if (class_type->GetID() != decl_ctx_die.GetID() ||
- decl_ctx_die.GetContainingDWOModuleDIE()) {
- alternate_defn = true;
-
- // We uniqued the parent class of this function to another
- // class so we now need to associate all dies under
- // "decl_ctx_die" to DIEs in the DIE for "class_type"...
- DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID());
-
- if (class_type_die) {
- std::vector<DWARFDIE> failures;
-
- CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
- class_type, failures);
-
- // FIXME do something with these failures that's smarter
- // than
- // just dropping them on the ground. Unfortunately classes
- // don't like having stuff added to them after their
- // definitions are complete...
-
- type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
- type_sp = type_ptr->shared_from_this();
- break;
- }
- }
- }
+ }
- if (specification_die_form.IsValid()) {
- // We have a specification which we are going to base our
- // function prototype off of, so we need this type to be
- // completed so that the m_die_to_decl_ctx for the method in
- // the specification has a valid clang decl context.
+ if (specification_die_form.IsValid()) {
+ // We have a specification which we are going to base our
+ // function prototype off of, so we need this type to be
+ // completed so that the m_die_to_decl_ctx for the method in
+ // the specification has a valid clang decl context.
+ class_type->GetForwardCompilerType();
+ // If we have a specification, then the function type should
+ // have been made with the specification and not with this
+ // die.
+ DWARFDIE spec_die =
+ dwarf->DebugInfo()->GetDIE(DIERef(specification_die_form));
+ clang::DeclContext *spec_clang_decl_ctx =
+ GetClangDeclContextForDIE(spec_die);
+ if (spec_clang_decl_ctx) {
+ LinkDeclContextToDIE(spec_clang_decl_ctx, die);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x"
+ ") has no decl\n",
+ die.GetID(),
+ specification_die_form.Reference().GetOffset());
+ }
+ type_handled = true;
+ } else if (abstract_origin_die_form.IsValid()) {
+ // We have a specification which we are going to base our
+ // function prototype off of, so we need this type to be
+ // completed so that the m_die_to_decl_ctx for the method in
+ // the abstract origin has a valid clang decl context.
+ class_type->GetForwardCompilerType();
+
+ DWARFDIE abs_die =
+ dwarf->DebugInfo()->GetDIE(DIERef(abstract_origin_die_form));
+ clang::DeclContext *abs_clang_decl_ctx =
+ GetClangDeclContextForDIE(abs_die);
+ if (abs_clang_decl_ctx) {
+ LinkDeclContextToDIE(abs_clang_decl_ctx, die);
+ } else {
+ dwarf->GetObjectFile()->GetModule()->ReportWarning(
+ "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x"
+ ") has no decl\n",
+ die.GetID(),
+ abstract_origin_die_form.Reference().GetOffset());
+ }
+ type_handled = true;
+ } else {
+ CompilerType class_opaque_type =
class_type->GetForwardCompilerType();
- // If we have a specification, then the function type should
- // have been made with the specification and not with this
- // die.
- DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(
- DIERef(specification_die_form));
- clang::DeclContext *spec_clang_decl_ctx =
- GetClangDeclContextForDIE(spec_die);
- if (spec_clang_decl_ctx) {
- LinkDeclContextToDIE(spec_clang_decl_ctx, die);
+ if (ClangASTContext::IsCXXClassType(class_opaque_type)) {
+ if (class_opaque_type.IsBeingDefined() || alternate_defn) {
+ if (!is_static && !die.HasChildren()) {
+ // We have a C++ member function with no children (this
+ // pointer!) and clang will get mad if we try and make
+ // a function that isn't well formed in the DWARF, so
+ // we will just skip it...
+ type_handled = true;
} else {
- dwarf->GetObjectFile()->GetModule()->ReportWarning(
- "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x"
- ") has no decl\n",
- die.GetID(),
- specification_die_form.Reference().GetOffset());
- }
- type_handled = true;
- } else if (abstract_origin_die_form.IsValid()) {
- // We have a specification which we are going to base our
- // function prototype off of, so we need this type to be
- // completed so that the m_die_to_decl_ctx for the method in
- // the abstract origin has a valid clang decl context.
- class_type->GetForwardCompilerType();
+ bool add_method = true;
+ if (alternate_defn) {
+ // If an alternate definition for the class exists,
+ // then add the method only if an equivalent is not
+ // already present.
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(
+ class_opaque_type.GetOpaqueQualType());
+ if (record_decl) {
+ for (auto method_iter = record_decl->method_begin();
+ method_iter != record_decl->method_end();
+ method_iter++) {
+ clang::CXXMethodDecl *method_decl = *method_iter;
+ if (method_decl->getNameInfo().getAsString() ==
+ std::string(type_name_cstr)) {
+ if (method_decl->getType() ==
+ ClangUtil::GetQualType(clang_type)) {
+ add_method = false;
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(
+ method_decl),
+ die);
+ type_handled = true;
- DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE(
- DIERef(abstract_origin_die_form));
- clang::DeclContext *abs_clang_decl_ctx =
- GetClangDeclContextForDIE(abs_die);
- if (abs_clang_decl_ctx) {
- LinkDeclContextToDIE(abs_clang_decl_ctx, die);
- } else {
- dwarf->GetObjectFile()->GetModule()->ReportWarning(
- "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x"
- ") has no decl\n",
- die.GetID(),
- abstract_origin_die_form.Reference().GetOffset());
- }
- type_handled = true;
- } else {
- CompilerType class_opaque_type =
- class_type->GetForwardCompilerType();
- if (ClangASTContext::IsCXXClassType(class_opaque_type)) {
- if (class_opaque_type.IsBeingDefined() || alternate_defn) {
- if (!is_static && !die.HasChildren()) {
- // We have a C++ member function with no children (this
- // pointer!) and clang will get mad if we try and make
- // a function that isn't well formed in the DWARF, so
- // we will just skip it...
- type_handled = true;
- } else {
- bool add_method = true;
- if (alternate_defn) {
- // If an alternate definition for the class exists,
- // then add the method only if an equivalent is not
- // already present.
- clang::CXXRecordDecl *record_decl =
- m_ast.GetAsCXXRecordDecl(
- class_opaque_type.GetOpaqueQualType());
- if (record_decl) {
- for (auto method_iter = record_decl->method_begin();
- method_iter != record_decl->method_end();
- method_iter++) {
- clang::CXXMethodDecl *method_decl = *method_iter;
- if (method_decl->getNameInfo().getAsString() ==
- std::string(type_name_cstr)) {
- if (method_decl->getType() ==
- ClangUtil::GetQualType(clang_type)) {
- add_method = false;
- LinkDeclContextToDIE(
- ClangASTContext::GetAsDeclContext(
- method_decl),
- die);
- type_handled = true;
-
- break;
- }
- }
+ break;
}
}
}
+ }
+ }
- if (add_method) {
- llvm::PrettyStackTraceFormat stack_trace(
- "SymbolFileDWARF::ParseType() is adding a method "
- "%s to class %s in DIE 0x%8.8" PRIx64 " from %s",
- type_name_cstr,
- class_type->GetName().GetCString(), die.GetID(),
- dwarf->GetObjectFile()
- ->GetFileSpec()
- .GetPath()
- .c_str());
-
- const bool is_attr_used = false;
- // Neither GCC 4.2 nor clang++ currently set a valid
- // accessibility in the DWARF for C++ methods...
- // Default to public for now...
- if (accessibility == eAccessNone)
- accessibility = eAccessPublic;
-
- clang::CXXMethodDecl *cxx_method_decl =
- m_ast.AddMethodToCXXRecordType(
- class_opaque_type.GetOpaqueQualType(),
- type_name_cstr, mangled_name_cstr, clang_type,
- accessibility, is_virtual, is_static,
- is_inline, is_explicit, is_attr_used,
- is_artificial);
-
- type_handled = cxx_method_decl != NULL;
-
- if (type_handled) {
- LinkDeclContextToDIE(
- ClangASTContext::GetAsDeclContext(
- cxx_method_decl),
- die);
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
-
- if (!object_pointer_name.empty()) {
- metadata.SetObjectPtrName(
- object_pointer_name.c_str());
- if (log)
- log->Printf(
- "Setting object pointer name: %s on method "
- "object %p.\n",
- object_pointer_name.c_str(),
- static_cast<void *>(cxx_method_decl));
- }
- m_ast.SetMetadata(cxx_method_decl, metadata);
- } else {
- ignore_containing_context = true;
- }
+ if (add_method) {
+ llvm::PrettyStackTraceFormat stack_trace(
+ "SymbolFileDWARF::ParseType() is adding a method "
+ "%s to class %s in DIE 0x%8.8" PRIx64 " from %s",
+ type_name_cstr, class_type->GetName().GetCString(),
+ die.GetID(),
+ dwarf->GetObjectFile()
+ ->GetFileSpec()
+ .GetPath()
+ .c_str());
+
+ const bool is_attr_used = false;
+ // Neither GCC 4.2 nor clang++ currently set a valid
+ // accessibility in the DWARF for C++ methods...
+ // Default to public for now...
+ if (accessibility == eAccessNone)
+ accessibility = eAccessPublic;
+
+ clang::CXXMethodDecl *cxx_method_decl =
+ m_ast.AddMethodToCXXRecordType(
+ class_opaque_type.GetOpaqueQualType(),
+ type_name_cstr, mangled_name_cstr, clang_type,
+ accessibility, is_virtual, is_static, is_inline,
+ is_explicit, is_attr_used, is_artificial);
+
+ type_handled = cxx_method_decl != NULL;
+
+ if (type_handled) {
+ LinkDeclContextToDIE(
+ ClangASTContext::GetAsDeclContext(cxx_method_decl),
+ die);
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+
+ if (!object_pointer_name.empty()) {
+ metadata.SetObjectPtrName(
+ object_pointer_name.c_str());
+ if (log)
+ log->Printf(
+ "Setting object pointer name: %s on method "
+ "object %p.\n",
+ object_pointer_name.c_str(),
+ static_cast<void *>(cxx_method_decl));
}
+ m_ast.SetMetadata(cxx_method_decl, metadata);
+ } else {
+ ignore_containing_context = true;
}
- } else {
- // We were asked to parse the type for a method in a
- // class, yet the class hasn't been asked to complete
- // itself through the clang::ExternalASTSource protocol,
- // so we need to just have the class complete itself and
- // do things the right way, then our
- // DIE should then have an entry in the
- // dwarf->GetDIEToType() map. First
- // we need to modify the dwarf->GetDIEToType() so it
- // doesn't think we are trying to parse this DIE
- // anymore...
- dwarf->GetDIEToType()[die.GetDIE()] = NULL;
-
- // Now we get the full type to force our class type to
- // complete itself using the clang::ExternalASTSource
- // protocol which will parse all base classes and all
- // methods (including the method for this DIE).
- class_type->GetFullCompilerType();
-
- // The type for this DIE should have been filled in the
- // function call above
- type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
- type_sp = type_ptr->shared_from_this();
- break;
- }
-
- // FIXME This is fixing some even uglier behavior but we
- // really need to
- // uniq the methods of each class as well as the class
- // itself. <rdar://problem/11240464>
- type_handled = true;
}
}
+ } else {
+ // We were asked to parse the type for a method in a
+ // class, yet the class hasn't been asked to complete
+ // itself through the clang::ExternalASTSource protocol,
+ // so we need to just have the class complete itself and
+ // do things the right way, then our
+ // DIE should then have an entry in the
+ // dwarf->GetDIEToType() map. First
+ // we need to modify the dwarf->GetDIEToType() so it
+ // doesn't think we are trying to parse this DIE
+ // anymore...
+ dwarf->GetDIEToType()[die.GetDIE()] = NULL;
+
+ // Now we get the full type to force our class type to
+ // complete itself using the clang::ExternalASTSource
+ // protocol which will parse all base classes and all
+ // methods (including the method for this DIE).
+ class_type->GetFullCompilerType();
+
+ // The type for this DIE should have been filled in the
+ // function call above
+ type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
+ type_sp = type_ptr->shared_from_this();
+ break;
+ }
+
+ // FIXME This is fixing some even uglier behavior but we
+ // really need to
+ // uniq the methods of each class as well as the class
+ // itself. <rdar://problem/11240464>
+ type_handled = true;
}
}
}
}
+ }
+ }
- if (!type_handled) {
- clang::FunctionDecl *function_decl = nullptr;
- clang::FunctionDecl *template_function_decl = nullptr;
+ if (!type_handled) {
+ clang::FunctionDecl *function_decl = nullptr;
+ clang::FunctionDecl *template_function_decl = nullptr;
- if (abstract_origin_die_form.IsValid()) {
- DWARFDIE abs_die = abstract_origin_die_form.Reference();
+ if (abstract_origin_die_form.IsValid()) {
+ DWARFDIE abs_die = abstract_origin_die_form.Reference();
- SymbolContext sc;
+ SymbolContext sc;
- if (dwarf->ResolveType(abs_die)) {
- function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
- GetCachedClangDeclContextForDIE(abs_die));
+ if (dwarf->ResolveType(abs_die)) {
+ function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
+ GetCachedClangDeclContextForDIE(abs_die));
- if (function_decl) {
- LinkDeclContextToDIE(function_decl, die);
- }
- }
+ if (function_decl) {
+ LinkDeclContextToDIE(function_decl, die);
}
+ }
+ }
- if (!function_decl) {
- // We just have a function that isn't part of a class
- function_decl = m_ast.CreateFunctionDeclaration(
- ignore_containing_context ? m_ast.GetTranslationUnitDecl()
- : containing_decl_ctx,
- type_name_cstr, clang_type, storage, is_inline);
-
- if (has_template_params) {
- ClangASTContext::TemplateParameterInfos template_param_infos;
- ParseTemplateParameterInfos(die, template_param_infos);
- template_function_decl = m_ast.CreateFunctionDeclaration(
- ignore_containing_context ? m_ast.GetTranslationUnitDecl()
- : containing_decl_ctx,
- type_name_cstr, clang_type, storage, is_inline);
- clang::FunctionTemplateDecl *func_template_decl =
- m_ast.CreateFunctionTemplateDecl(
- containing_decl_ctx, template_function_decl,
- type_name_cstr, template_param_infos);
- m_ast.CreateFunctionTemplateSpecializationInfo(
- function_decl, func_template_decl, template_param_infos);
- }
-
- lldbassert(function_decl);
-
- if (function_decl) {
- LinkDeclContextToDIE(function_decl, die);
-
- if (!function_param_decls.empty()) {
- m_ast.SetFunctionParameters(function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
- if (template_function_decl)
- m_ast.SetFunctionParameters(template_function_decl,
- &function_param_decls.front(),
- function_param_decls.size());
- }
-
- ClangASTMetadata metadata;
- metadata.SetUserID(die.GetID());
+ if (!function_decl) {
+ // We just have a function that isn't part of a class
+ function_decl = m_ast.CreateFunctionDeclaration(
+ ignore_containing_context ? m_ast.GetTranslationUnitDecl()
+ : containing_decl_ctx,
+ type_name_cstr, clang_type, storage, is_inline);
- if (!object_pointer_name.empty()) {
- metadata.SetObjectPtrName(object_pointer_name.c_str());
- if (log)
- log->Printf("Setting object pointer name: %s on function "
- "object %p.",
- object_pointer_name.c_str(),
- static_cast<void *>(function_decl));
- }
- m_ast.SetMetadata(function_decl, metadata);
- }
+ if (has_template_params) {
+ ClangASTContext::TemplateParameterInfos template_param_infos;
+ ParseTemplateParameterInfos(die, template_param_infos);
+ template_function_decl = m_ast.CreateFunctionDeclaration(
+ ignore_containing_context ? m_ast.GetTranslationUnitDecl()
+ : containing_decl_ctx,
+ type_name_cstr, clang_type, storage, is_inline);
+ clang::FunctionTemplateDecl *func_template_decl =
+ m_ast.CreateFunctionTemplateDecl(
+ containing_decl_ctx, template_function_decl, type_name_cstr,
+ template_param_infos);
+ m_ast.CreateFunctionTemplateSpecializationInfo(
+ function_decl, func_template_decl, template_param_infos);
+ }
+
+ lldbassert(function_decl);
+
+ if (function_decl) {
+ LinkDeclContextToDIE(function_decl, die);
+
+ if (!function_param_decls.empty()) {
+ m_ast.SetFunctionParameters(function_decl,
+ &function_param_decls.front(),
+ function_param_decls.size());
+ if (template_function_decl)
+ m_ast.SetFunctionParameters(template_function_decl,
+ &function_param_decls.front(),
+ function_param_decls.size());
+ }
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(die.GetID());
+
+ if (!object_pointer_name.empty()) {
+ metadata.SetObjectPtrName(object_pointer_name.c_str());
+ if (log)
+ log->Printf("Setting object pointer name: %s on function "
+ "object %p.",
+ object_pointer_name.c_str(),
+ static_cast<void *>(function_decl));
}
+ m_ast.SetMetadata(function_decl, metadata);
}
}
- type_sp = std::make_shared<Type>(
- die.GetID(), dwarf, type_name_const_str, llvm::None, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, clang_type,
- Type::eResolveStateFull);
- assert(type_sp.get());
- } break;
-
- case DW_TAG_array_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- DWARFFormValue type_die_form;
- uint32_t byte_stride = 0;
- uint32_t bit_stride = 0;
- bool is_vector = false;
- const size_t num_attributes = die.GetAttributes(attributes);
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(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();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_type:
- type_die_form = form_value;
- break;
- case DW_AT_byte_size:
- break; // byte_size = form_value.Unsigned(); break;
- case DW_AT_byte_stride:
- byte_stride = form_value.Unsigned();
- break;
- case DW_AT_bit_stride:
- bit_stride = form_value.Unsigned();
- break;
- case DW_AT_GNU_vector:
- is_vector = form_value.Boolean();
- break;
- case DW_AT_accessibility:
- break; // accessibility =
- // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
- case DW_AT_declaration:
- break; // is_forward_declaration = form_value.Boolean(); break;
- case DW_AT_allocated:
- case DW_AT_associated:
- case DW_AT_data_location:
- case DW_AT_description:
- case DW_AT_ordering:
- case DW_AT_start_scope:
- case DW_AT_visibility:
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_sibling:
- break;
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
+ }
+ }
+ type_sp = std::make_shared<Type>(die.GetID(), dwarf, type_name_const_str,
+ llvm::None, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, &decl, clang_type,
+ Type::eResolveStateFull);
+ assert(type_sp.get());
+ } break;
+
+ case DW_TAG_array_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ DWARFFormValue type_die_form;
+ uint32_t byte_stride = 0;
+ uint32_t bit_stride = 0;
+ bool is_vector = false;
+ const size_t num_attributes = die.GetAttributes(attributes);
+
+ if (num_attributes > 0) {
+ uint32_t i;
+ for (i = 0; i < num_attributes; ++i) {
+ attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(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();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
- DIERef type_die_ref(type_die_form);
- Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_byte_size:
+ break; // byte_size = form_value.Unsigned(); break;
+ case DW_AT_byte_stride:
+ byte_stride = form_value.Unsigned();
+ break;
+ case DW_AT_bit_stride:
+ bit_stride = form_value.Unsigned();
+ break;
+ case DW_AT_GNU_vector:
+ is_vector = form_value.Boolean();
+ break;
+ case DW_AT_accessibility:
+ break; // accessibility =
+ // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+ case DW_AT_declaration:
+ break; // is_forward_declaration = form_value.Boolean(); break;
+ case DW_AT_allocated:
+ case DW_AT_associated:
+ case DW_AT_data_location:
+ case DW_AT_description:
+ case DW_AT_ordering:
+ case DW_AT_start_scope:
+ case DW_AT_visibility:
+ case DW_AT_specification:
+ case DW_AT_abstract_origin:
+ case DW_AT_sibling:
+ break;
+ }
+ }
+ }
- if (element_type) {
- auto array_info = ParseChildArrayInfo(die);
- if (array_info) {
- byte_stride = array_info->byte_stride;
- bit_stride = array_info->bit_stride;
- }
- if (byte_stride == 0 && bit_stride == 0)
- byte_stride = element_type->GetByteSize().getValueOr(0);
- CompilerType array_element_type =
- element_type->GetForwardCompilerType();
-
- if (ClangASTContext::IsCXXClassType(array_element_type) &&
- !array_element_type.GetCompleteType()) {
- ModuleSP module_sp = die.GetModule();
- if (module_sp) {
- if (die.GetCU()->GetProducer() == eProducerClang)
- module_sp->ReportError(
- "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
- "class/union/struct element type DIE 0x%8.8x that is a "
- "forward declaration, not a complete definition.\nTry "
- "compiling the source file with -fstandalone-debug or "
- "disable -gmodules",
- die.GetOffset(), type_die_ref.die_offset);
- else
- module_sp->ReportError(
- "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
- "class/union/struct element type DIE 0x%8.8x that is a "
- "forward declaration, not a complete definition.\nPlease "
- "file a bug against the compiler and include the "
- "preprocessed output for %s",
- die.GetOffset(), type_die_ref.die_offset,
- die.GetLLDBCompileUnit()
- ? die.GetLLDBCompileUnit()->GetPath().c_str()
- : "the source file");
- }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
- // We have no choice other than to pretend that the element class
- // type is complete. If we don't do this, clang will crash when
- // trying to layout the class. Since we provide layout
- // assistance, all ivars in this class and other classes will be
- // fine, this is the best we can do short of crashing.
- if (ClangASTContext::StartTagDeclarationDefinition(
- array_element_type)) {
- ClangASTContext::CompleteTagDeclarationDefinition(
- array_element_type);
- } else {
- module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
- "start its definition.\nPlease file a "
- "bug and attach the file at the start "
- "of this error message",
- type_die_ref.die_offset);
- }
- }
+ DIERef type_die_ref(type_die_form);
+ Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
- uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
- if (array_info && array_info->element_orders.size() > 0) {
- uint64_t num_elements = 0;
- auto end = array_info->element_orders.rend();
- for (auto pos = array_info->element_orders.rbegin(); pos != end;
- ++pos) {
- num_elements = *pos;
- clang_type = m_ast.CreateArrayType(array_element_type,
- num_elements, is_vector);
- array_element_type = clang_type;
- array_element_bit_stride =
- num_elements ? array_element_bit_stride * num_elements
- : array_element_bit_stride;
- }
- } else {
- clang_type =
- m_ast.CreateArrayType(array_element_type, 0, is_vector);
- }
- ConstString empty_name;
- type_sp = std::make_shared<Type>(
- die.GetID(), dwarf, empty_name, array_element_bit_stride / 8,
- nullptr, dwarf->GetUID(DIERef(type_die_form)),
- Type::eEncodingIsUID, &decl, clang_type,
- Type::eResolveStateFull);
- type_sp->SetEncodingType(element_type);
- m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(),
- die.GetID());
- }
- }
- } break;
-
- case DW_TAG_ptr_to_member_type: {
- DWARFFormValue type_die_form;
- DWARFFormValue containing_type_die_form;
-
- const size_t num_attributes = die.GetAttributes(attributes);
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_type:
- type_die_form = form_value;
- break;
- case DW_AT_containing_type:
- containing_type_die_form = form_value;
- break;
- }
- }
+ if (element_type) {
+ auto array_info = ParseChildArrayInfo(die);
+ if (array_info) {
+ byte_stride = array_info->byte_stride;
+ bit_stride = array_info->bit_stride;
+ }
+ if (byte_stride == 0 && bit_stride == 0)
+ byte_stride = element_type->GetByteSize().getValueOr(0);
+ CompilerType array_element_type =
+ element_type->GetForwardCompilerType();
+
+ if (ClangASTContext::IsCXXClassType(array_element_type) &&
+ !array_element_type.GetCompleteType()) {
+ ModuleSP module_sp = die.GetModule();
+ if (module_sp) {
+ if (die.GetCU()->GetProducer() == eProducerClang)
+ module_sp->ReportError(
+ "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
+ "class/union/struct element type DIE 0x%8.8x that is a "
+ "forward declaration, not a complete definition.\nTry "
+ "compiling the source file with -fstandalone-debug or "
+ "disable -gmodules",
+ die.GetOffset(), type_die_ref.die_offset);
+ else
+ module_sp->ReportError(
+ "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
+ "class/union/struct element type DIE 0x%8.8x that is a "
+ "forward declaration, not a complete definition.\nPlease "
+ "file a bug against the compiler and include the "
+ "preprocessed output for %s",
+ die.GetOffset(), type_die_ref.die_offset,
+ die.GetLLDBCompileUnit()
+ ? die.GetLLDBCompileUnit()->GetPath().c_str()
+ : "the source file");
+ }
+
+ // We have no choice other than to pretend that the element class
+ // type is complete. If we don't do this, clang will crash when
+ // trying to layout the class. Since we provide layout
+ // assistance, all ivars in this class and other classes will be
+ // fine, this is the best we can do short of crashing.
+ if (ClangASTContext::StartTagDeclarationDefinition(
+ array_element_type)) {
+ ClangASTContext::CompleteTagDeclarationDefinition(
+ array_element_type);
+ } else {
+ module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
+ "start its definition.\nPlease file a "
+ "bug and attach the file at the start "
+ "of this error message",
+ type_die_ref.die_offset);
}
+ }
- Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
- Type *class_type =
- dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
-
- CompilerType pointee_clang_type =
- pointee_type->GetForwardCompilerType();
- CompilerType class_clang_type = class_type->GetLayoutCompilerType();
-
- clang_type = ClangASTContext::CreateMemberPointerType(
- class_clang_type, pointee_clang_type);
-
- if (llvm::Optional<uint64_t> clang_type_size =
- clang_type.GetByteSize(nullptr)) {
- byte_size = *clang_type_size;
- type_sp = std::make_shared<Type>(
- die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
- LLDB_INVALID_UID, Type::eEncodingIsUID, nullptr, clang_type,
- Type::eResolveStateForward);
+ uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
+ if (array_info && array_info->element_orders.size() > 0) {
+ uint64_t num_elements = 0;
+ auto end = array_info->element_orders.rend();
+ for (auto pos = array_info->element_orders.rbegin(); pos != end;
+ ++pos) {
+ num_elements = *pos;
+ clang_type = m_ast.CreateArrayType(array_element_type, num_elements,
+ is_vector);
+ array_element_type = clang_type;
+ array_element_bit_stride =
+ num_elements ? array_element_bit_stride * num_elements
+ : array_element_bit_stride;
}
+ } else {
+ clang_type = m_ast.CreateArrayType(array_element_type, 0, is_vector);
}
+ ConstString empty_name;
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, empty_name, array_element_bit_stride / 8,
+ nullptr, dwarf->GetUID(DIERef(type_die_form)), Type::eEncodingIsUID,
+ &decl, clang_type, Type::eResolveStateFull);
+ type_sp->SetEncodingType(element_type);
+ m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(), die.GetID());
+ }
+ }
+ } break;
- break;
+ case DW_TAG_ptr_to_member_type: {
+ DWARFFormValue type_die_form;
+ DWARFFormValue containing_type_die_form;
+
+ const size_t num_attributes = die.GetAttributes(attributes);
+
+ if (num_attributes > 0) {
+ uint32_t i;
+ for (i = 0; i < num_attributes; ++i) {
+ attr = attributes.AttributeAtIndex(i);
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_type:
+ type_die_form = form_value;
+ break;
+ case DW_AT_containing_type:
+ containing_type_die_form = form_value;
+ break;
+ }
+ }
}
- default:
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and "
- "attach the file at the start of this error message",
- die.GetOffset(), tag, DW_TAG_value_to_name(tag));
- break;
+
+ Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
+ Type *class_type =
+ dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
+
+ CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
+ CompilerType class_clang_type = class_type->GetLayoutCompilerType();
+
+ clang_type = ClangASTContext::CreateMemberPointerType(class_clang_type,
+ pointee_clang_type);
+
+ if (llvm::Optional<uint64_t> clang_type_size =
+ clang_type.GetByteSize(nullptr)) {
+ byte_size = *clang_type_size;
+ type_sp = std::make_shared<Type>(
+ die.GetID(), dwarf, type_name_const_str, byte_size, nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, nullptr, clang_type,
+ Type::eResolveStateForward);
}
+ }
- if (type_sp.get()) {
- DWARFDIE sc_parent_die =
- SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
-
- SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit ||
- sc_parent_tag == DW_TAG_partial_unit) {
- symbol_context_scope = sc.comp_unit;
- } else if (sc.function != NULL && sc_parent_die) {
- symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
- }
-
- if (symbol_context_scope != NULL) {
- type_sp->SetSymbolContextScope(symbol_context_scope);
- }
-
- // We are ready to put this type into the uniqued list up at the module
- // level
- type_list->Insert(type_sp);
+ break;
+ }
+ default:
+ dwarf->GetObjectFile()->GetModule()->ReportError(
+ "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and "
+ "attach the file at the start of this error message",
+ die.GetOffset(), tag, DW_TAG_value_to_name(tag));
+ break;
+ }
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- }
- } else if (type_ptr != DIE_IS_BEING_PARSED) {
- type_sp = type_ptr->shared_from_this();
+ if (type_sp.get()) {
+ DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
+ dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+
+ SymbolContextScope *symbol_context_scope = NULL;
+ if (sc_parent_tag == DW_TAG_compile_unit ||
+ sc_parent_tag == DW_TAG_partial_unit) {
+ symbol_context_scope = sc.comp_unit;
+ } else if (sc.function != NULL && sc_parent_die) {
+ symbol_context_scope =
+ sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+ if (symbol_context_scope == NULL)
+ symbol_context_scope = sc.function;
+ }
+
+ if (symbol_context_scope != NULL) {
+ type_sp->SetSymbolContextScope(symbol_context_scope);
}
+
+ // We are ready to put this type into the uniqued list up at the module
+ // level
+ type_list->Insert(type_sp);
+
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
}
return type_sp;
}
More information about the lldb-commits
mailing list