aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp')
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp1391
1 files changed, 668 insertions, 723 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
index 346e2d63b908..2507465750c7 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -11,11 +11,11 @@
#include "DWARFASTParserGo.h"
#include "DWARFCompileUnit.h"
+#include "DWARFDIE.h"
+#include "DWARFDIECollection.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDefines.h"
-#include "DWARFDIE.h"
-#include "DWARFDIECollection.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDebugMap.h"
#include "UniqueDWARFASTType.h"
@@ -44,787 +44,732 @@
using namespace lldb;
using namespace lldb_private;
-DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast)
- : m_ast(ast)
-{
-}
+DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {}
-DWARFASTParserGo::~DWARFASTParserGo()
-{
-}
+DWARFASTParserGo::~DWARFASTParserGo() {}
-TypeSP
-DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::Log *log,
- bool *type_is_new_ptr)
-{
- TypeSP type_sp;
+TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
+ const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ lldb_private::Log *log, bool *type_is_new_ptr) {
+ TypeSP type_sp;
- if (type_is_new_ptr)
- *type_is_new_ptr = false;
+ if (type_is_new_ptr)
+ *type_is_new_ptr = false;
- if (die)
- {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- if (log)
- {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = '%s')", die.GetOffset(),
- DW_TAG_value_to_name(die.Tag()), die.GetName());
- }
+ if (die) {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = "
+ "'%s')",
+ die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
+ }
- Type *type_ptr = dwarf->m_die_to_type.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;
- ConstString type_name_const_str;
- Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
- uint64_t byte_size = 0;
- uint64_t go_kind = 0;
- Declaration decl;
-
- Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
- CompilerType compiler_type;
- DWARFFormValue form_value;
-
- dw_attr_t attr;
-
- switch (tag)
- {
- case DW_TAG_base_type:
- case DW_TAG_pointer_type:
- case DW_TAG_typedef:
- case DW_TAG_unspecified_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- const size_t num_attributes = die.GetAttributes(attributes);
- lldb::user_id_t encoding_uid = LLDB_INVALID_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_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:
- // = form_value.Unsigned();
- break;
- case DW_AT_type:
- encoding_uid = form_value.Reference();
- break;
- case DW_AT_go_kind:
- go_kind = form_value.Unsigned();
- break;
- default:
- // Do we care about DW_AT_go_key or DW_AT_go_elem?
- 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);
-
- switch (tag)
- {
- default:
- break;
-
- case DW_TAG_unspecified_type:
- resolve_state = Type::eResolveStateFull;
- compiler_type = m_ast.CreateVoidType(type_name_const_str);
- break;
-
- case DW_TAG_base_type:
- resolve_state = Type::eResolveStateFull;
- compiler_type = m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size);
- break;
-
- case DW_TAG_pointer_type:
- encoding_data_type = Type::eEncodingIsPointerUID;
- break;
- case DW_TAG_typedef:
- encoding_data_type = Type::eEncodingIsTypedefUID;
- CompilerType impl;
- Type *type = dwarf->ResolveTypeUID(encoding_uid);
- if (type)
- {
- if (go_kind == 0 && type->GetName() == type_name_const_str)
- {
- // Go emits extra typedefs as a forward declaration. Ignore these.
- dwarf->m_die_to_type[die.GetDIE()] = type;
- return type->shared_from_this();
- }
- impl = type->GetForwardCompilerType();
- compiler_type = m_ast.CreateTypedefType (go_kind, type_name_const_str, impl);
- }
- break;
- }
-
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size,
- NULL, encoding_uid, encoding_data_type, &decl, compiler_type, resolve_state));
-
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
- }
+ Type *type_ptr = dwarf->m_die_to_type.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;
+ ConstString type_name_const_str;
+ Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
+ uint64_t byte_size = 0;
+ uint64_t go_kind = 0;
+ Declaration decl;
+
+ Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
+ CompilerType compiler_type;
+ DWARFFormValue form_value;
+
+ dw_attr_t attr;
+
+ switch (tag) {
+ case DW_TAG_base_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_typedef:
+ case DW_TAG_unspecified_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ const size_t num_attributes = die.GetAttributes(attributes);
+ lldb::user_id_t encoding_uid = LLDB_INVALID_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_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:
+ // = form_value.Unsigned();
+ break;
+ case DW_AT_type:
+ encoding_uid = form_value.Reference();
+ break;
+ case DW_AT_go_kind:
+ go_kind = form_value.Unsigned();
+ break;
+ default:
+ // Do we care about DW_AT_go_key or DW_AT_go_elem?
+ break;
+ }
+ }
+ }
+ }
- case DW_TAG_structure_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
- bool byte_size_valid = 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_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();
- byte_size_valid = true;
- break;
-
- case DW_AT_go_kind:
- go_kind = form_value.Unsigned();
- break;
-
- // TODO: Should we use SLICETYPE's DW_AT_go_elem?
- default:
- break;
- }
- }
- }
- }
-
- // TODO(ribrdb): Do we need this?
-
- // 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_ap(new UniqueDWARFASTType());
-
- // Only try and unique the type if it has a name.
- if (type_name_const_str &&
- dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl,
- byte_size_valid ? byte_size : -1, *unique_ast_entry_ap))
- {
- // We have already parsed this type or from another
- // compile unit. GCC loves to use the "one definition
- // rule" which can result in multiple definitions
- // of the same class over and over in each compile
- // unit.
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp)
- {
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- bool compiler_type_was_created = false;
- compiler_type.SetCompilerType(&m_ast, dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
- if (!compiler_type)
- {
- compiler_type_was_created = true;
- compiler_type = m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
- }
-
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size,
- NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
- Type::eResolveStateForward));
-
- // 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_ap->m_type_sp = type_sp;
- unique_ast_entry_ap->m_die = die;
- unique_ast_entry_ap->m_declaration = decl;
- unique_ast_entry_ap->m_byte_size = byte_size;
- dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str, *unique_ast_entry_ap);
-
- 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() == false)
- {
- // No children for this struct/union/class, lets finish it
- m_ast.CompleteStructType(compiler_type);
- }
- else if (compiler_type_was_created)
- {
- // 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.
- dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] = compiler_type.GetOpaqueQualType();
- dwarf->m_forward_decl_clang_type_to_die[compiler_type.GetOpaqueQualType()] = die.GetDIERef();
- // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
- }
- }
- }
+ 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);
+
+ switch (tag) {
+ default:
+ break;
+
+ case DW_TAG_unspecified_type:
+ resolve_state = Type::eResolveStateFull;
+ compiler_type = m_ast.CreateVoidType(type_name_const_str);
+ break;
+
+ case DW_TAG_base_type:
+ resolve_state = Type::eResolveStateFull;
+ compiler_type =
+ m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size);
+ break;
+
+ case DW_TAG_pointer_type:
+ encoding_data_type = Type::eEncodingIsPointerUID;
+ break;
+ case DW_TAG_typedef:
+ encoding_data_type = Type::eEncodingIsTypedefUID;
+ CompilerType impl;
+ Type *type = dwarf->ResolveTypeUID(encoding_uid);
+ if (type) {
+ if (go_kind == 0 && type->GetName() == type_name_const_str) {
+ // Go emits extra typedefs as a forward declaration. Ignore these.
+ dwarf->m_die_to_type[die.GetDIE()] = type;
+ return type->shared_from_this();
+ }
+ impl = type->GetForwardCompilerType();
+ compiler_type =
+ m_ast.CreateTypedefType(go_kind, type_name_const_str, impl);
+ }
+ break;
+ }
+
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
+ byte_size, NULL, encoding_uid,
+ encoding_data_type, &decl, compiler_type,
+ resolve_state));
+
+ dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+ } break;
+
+ case DW_TAG_structure_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+ bool byte_size_valid = 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_name:
+ type_name_cstr = form_value.AsCString();
+ type_name_const_str.SetCString(type_name_cstr);
break;
- case DW_TAG_subprogram:
- case DW_TAG_subroutine_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- bool is_variadic = false;
- 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_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- 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_high_pc:
- case DW_AT_low_pc:
- break;
- }
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- std::vector<CompilerType> function_param_types;
-
- // Parse the function children for the parameters
-
- if (die.HasChildren())
- {
- ParseChildParameters(sc, die, is_variadic, function_param_types);
- }
-
- // compiler_type will get the function prototype clang type after this call
- compiler_type = m_ast.CreateFunctionType(type_name_const_str, function_param_types.data(),
- function_param_types.size(), is_variadic);
-
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
- LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
- Type::eResolveStateFull));
- assert(type_sp.get());
- }
+ case DW_AT_byte_size:
+ byte_size = form_value.Unsigned();
+ byte_size_valid = true;
break;
- case DW_TAG_array_type:
- {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
- int64_t first_index = 0;
- uint32_t byte_stride = 0;
- uint32_t bit_stride = 0;
- 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_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_type:
- type_die_offset = form_value.Reference();
- break;
- case DW_AT_byte_size:
- break; // byte_size = form_value.Unsigned(); break;
- case DW_AT_go_kind:
- go_kind = form_value.Unsigned();
- break;
- default:
- break;
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
-
- if (element_type)
- {
- std::vector<uint64_t> element_orders;
- ParseChildArrayInfo(sc, die, first_index, element_orders, byte_stride, bit_stride);
- if (byte_stride == 0)
- byte_stride = element_type->GetByteSize();
- CompilerType array_element_type = element_type->GetForwardCompilerType();
- if (element_orders.size() > 0)
- {
- if (element_orders.size() > 1)
- printf("golang: unsupported multi-dimensional array %s\n", type_name_cstr);
- compiler_type =
- m_ast.CreateArrayType(type_name_const_str, array_element_type, element_orders[0]);
- }
- else
- {
- compiler_type = m_ast.CreateArrayType(type_name_const_str, array_element_type, 0);
- }
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
- byte_stride, NULL, type_die_offset, Type::eEncodingIsUID, &decl,
- compiler_type, Type::eResolveStateFull));
- type_sp->SetEncodingType(element_type);
- }
- }
- }
+ case DW_AT_go_kind:
+ go_kind = form_value.Unsigned();
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;
+ // TODO: Should we use SLICETYPE's DW_AT_go_elem?
+ default:
+ break;
+ }
}
+ }
+ }
- if (type_sp.get())
- {
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+ // TODO(ribrdb): Do we need this?
+
+ // 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_ap(
+ new UniqueDWARFASTType());
+
+ // Only try and unique the type if it has a name.
+ if (type_name_const_str &&
+ dwarf->GetUniqueDWARFASTTypeMap().Find(
+ type_name_const_str, die, decl,
+ byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
+ // We have already parsed this type or from another
+ // compile unit. GCC loves to use the "one definition
+ // rule" which can result in multiple definitions
+ // of the same class over and over in each compile
+ // unit.
+ type_sp = unique_ast_entry_ap->m_type_sp;
+ if (type_sp) {
+ dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+ return type_sp;
+ }
+ }
- SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_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;
- }
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ bool compiler_type_was_created = false;
+ compiler_type.SetCompilerType(
+ &m_ast,
+ dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
+ if (!compiler_type) {
+ compiler_type_was_created = true;
+ compiler_type =
+ m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
+ }
- if (symbol_context_scope != NULL)
- {
- type_sp->SetSymbolContextScope(symbol_context_scope);
- }
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
+ byte_size, NULL, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, &decl, compiler_type,
+ Type::eResolveStateForward));
+
+ // 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_ap->m_type_sp = type_sp;
+ unique_ast_entry_ap->m_die = die;
+ unique_ast_entry_ap->m_declaration = decl;
+ unique_ast_entry_ap->m_byte_size = byte_size;
+ dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str,
+ *unique_ast_entry_ap);
+
+ 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() == false) {
+ // No children for this struct/union/class, lets finish it
+ m_ast.CompleteStructType(compiler_type);
+ } else if (compiler_type_was_created) {
+ // 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.
+ dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] =
+ compiler_type.GetOpaqueQualType();
+ dwarf->m_forward_decl_clang_type_to_die[compiler_type
+ .GetOpaqueQualType()] =
+ die.GetDIERef();
+ // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
+ }
+ }
+ } break;
+
+ case DW_TAG_subprogram:
+ case DW_TAG_subroutine_type: {
+ // Set a bit that lets us know that we are currently parsing this
+ dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ bool is_variadic = false;
+ 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_name:
+ type_name_cstr = form_value.AsCString();
+ type_name_const_str.SetCString(type_name_cstr);
+ break;
- // We are ready to put this type into the uniqued list up at the module level
- type_list->Insert(type_sp);
+ case DW_AT_external:
+ if (form_value.Unsigned()) {
+ if (storage == clang::SC_None)
+ storage = clang::SC_Extern;
+ else
+ storage = clang::SC_PrivateExtern;
+ }
+ break;
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+ case DW_AT_high_pc:
+ case DW_AT_low_pc:
+ break;
+ }
}
+ }
}
- else if (type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- }
- }
- return type_sp;
-}
-size_t
-DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc,
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
- const DWARFDIE &parent_die, bool &is_variadic,
- std::vector<CompilerType> &function_param_types)
-{
- if (!parent_die)
- return 0;
+ std::vector<CompilerType> function_param_types;
- size_t arg_idx = 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
- {
+ // Parse the function children for the parameters
- dw_tag_t tag = die.Tag();
- switch (tag)
- {
- case DW_TAG_formal_parameter:
- {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0)
- {
- Declaration decl;
- DWARFFormValue param_type_die_offset;
-
- uint32_t i;
- for (i = 0; i < num_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- {
- switch (attr)
- {
- case DW_AT_name:
- // = form_value.AsCString();
- break;
- case DW_AT_type:
- param_type_die_offset = form_value;
- break;
- case DW_AT_location:
- // if (form_value.BlockData())
- // {
- // const DWARFDataExtractor& debug_info_data =
- // debug_info();
- // uint32_t block_length = form_value.Unsigned();
- // DWARFDataExtractor location(debug_info_data,
- // form_value.BlockData() - debug_info_data.GetDataStart(),
- // block_length);
- // }
- // else
- // {
- // }
- // break;
- default:
- break;
- }
- }
- }
-
- Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
- if (type)
- {
- function_param_types.push_back(type->GetForwardCompilerType());
- }
- }
- arg_idx++;
- }
- break;
+ if (die.HasChildren()) {
+ ParseChildParameters(sc, die, is_variadic, function_param_types);
+ }
- case DW_TAG_unspecified_parameters:
- is_variadic = true;
+ // compiler_type will get the function prototype clang type after this
+ // call
+ compiler_type = m_ast.CreateFunctionType(
+ type_name_const_str, function_param_types.data(),
+ function_param_types.size(), is_variadic);
+
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, &decl,
+ compiler_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->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+ lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
+ int64_t first_index = 0;
+ uint32_t byte_stride = 0;
+ uint32_t bit_stride = 0;
+ 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_name:
+ type_name_cstr = form_value.AsCString();
+ type_name_const_str.SetCString(type_name_cstr);
break;
- default:
+ case DW_AT_type:
+ type_die_offset = form_value.Reference();
+ break;
+ case DW_AT_byte_size:
+ break; // byte_size = form_value.Unsigned(); break;
+ case DW_AT_go_kind:
+ go_kind = form_value.Unsigned();
+ break;
+ default:
break;
+ }
+ }
+ }
+
+ DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
+ DW_TAG_value_to_name(tag), type_name_cstr);
+
+ Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
+
+ if (element_type) {
+ std::vector<uint64_t> element_orders;
+ ParseChildArrayInfo(sc, die, first_index, element_orders,
+ byte_stride, bit_stride);
+ if (byte_stride == 0)
+ byte_stride = element_type->GetByteSize();
+ CompilerType array_element_type =
+ element_type->GetForwardCompilerType();
+ if (element_orders.size() > 0) {
+ if (element_orders.size() > 1)
+ printf("golang: unsupported multi-dimensional array %s\n",
+ type_name_cstr);
+ compiler_type = m_ast.CreateArrayType(
+ type_name_const_str, array_element_type, element_orders[0]);
+ } else {
+ compiler_type = m_ast.CreateArrayType(type_name_const_str,
+ array_element_type, 0);
+ }
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
+ byte_stride, NULL, type_die_offset,
+ Type::eEncodingIsUID, &decl, compiler_type,
+ Type::eResolveStateFull));
+ type_sp->SetEncodingType(element_type);
+ }
+ }
+ } 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;
+ }
+
+ 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) {
+ 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->m_die_to_type[die.GetDIE()] = type_sp.get();
+ }
+ } else if (type_ptr != DIE_IS_BEING_PARSED) {
+ type_sp = type_ptr->shared_from_this();
}
- return arg_idx;
+ }
+ return type_sp;
}
-void
-DWARFASTParserGo::ParseChildArrayInfo(const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
- std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
- uint32_t &bit_stride)
-{
- if (!parent_die)
- return;
-
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
- {
- const dw_tag_t tag = die.Tag();
- switch (tag)
- {
- case DW_TAG_subrange_type:
- {
- DWARFAttributes attributes;
- const size_t num_child_attributes = die.GetAttributes(attributes);
- if (num_child_attributes > 0)
- {
- uint64_t num_elements = 0;
- uint32_t i;
- for (i = 0; i < num_child_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- {
- switch (attr)
- {
- case DW_AT_count:
- num_elements = form_value.Unsigned();
- break;
-
- default:
- case DW_AT_type:
- break;
- }
- }
- }
-
- element_orders.push_back(num_elements);
- }
+size_t DWARFASTParserGo::ParseChildParameters(
+ const SymbolContext &sc,
+
+ const DWARFDIE &parent_die, bool &is_variadic,
+ std::vector<CompilerType> &function_param_types) {
+ if (!parent_die)
+ return 0;
+
+ size_t arg_idx = 0;
+ for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
+ die = die.GetSibling()) {
+
+ dw_tag_t tag = die.Tag();
+ switch (tag) {
+ case DW_TAG_formal_parameter: {
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes > 0) {
+ Declaration decl;
+ DWARFFormValue param_type_die_offset;
+
+ uint32_t i;
+ for (i = 0; i < num_attributes; ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_name:
+ // = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ param_type_die_offset = form_value;
+ break;
+ case DW_AT_location:
+ // if (form_value.BlockData())
+ // {
+ // const DWARFDataExtractor&
+ // debug_info_data =
+ // debug_info();
+ // uint32_t block_length =
+ // form_value.Unsigned();
+ // DWARFDataExtractor
+ // location(debug_info_data,
+ // form_value.BlockData() -
+ // debug_info_data.GetDataStart(),
+ // block_length);
+ // }
+ // else
+ // {
+ // }
+ // break;
+ default:
+ break;
}
- break;
+ }
+ }
+
+ Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
+ if (type) {
+ function_param_types.push_back(type->GetForwardCompilerType());
}
+ }
+ arg_idx++;
+ } break;
+
+ case DW_TAG_unspecified_parameters:
+ is_variadic = true;
+ break;
+
+ default:
+ break;
}
+ }
+ return arg_idx;
}
-bool
-DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &compiler_type)
-{
- if (!die)
- return false;
+void DWARFASTParserGo::ParseChildArrayInfo(
+ const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
+ std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
+ uint32_t &bit_stride) {
+ if (!parent_die)
+ return;
+ for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
+ die = die.GetSibling()) {
const dw_tag_t tag = die.Tag();
+ switch (tag) {
+ case DW_TAG_subrange_type: {
+ DWARFAttributes attributes;
+ const size_t num_child_attributes = die.GetAttributes(attributes);
+ if (num_child_attributes > 0) {
+ uint64_t num_elements = 0;
+ uint32_t i;
+ for (i = 0; i < num_child_attributes; ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_count:
+ num_elements = form_value.Unsigned();
+ break;
- SymbolFileDWARF *dwarf = die.GetDWARF();
- Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
- log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", die.GetID(),
- DW_TAG_value_to_name(tag), type->GetName().AsCString());
- assert(compiler_type);
- DWARFAttributes attributes;
-
- switch (tag)
- {
- case DW_TAG_structure_type:
- {
- {
- if (die.HasChildren())
- {
- SymbolContext sc(die.GetLLDBCompileUnit());
-
- ParseChildMembers(sc, die, compiler_type);
- }
+ default:
+ case DW_AT_type:
+ break;
}
- m_ast.CompleteStructType(compiler_type);
- return (bool)compiler_type;
+ }
}
- default:
- assert(false && "not a forward go type decl!");
- break;
+ element_orders.push_back(num_elements);
+ }
+ } break;
}
+ }
+}
+bool DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die,
+ lldb_private::Type *type,
+ CompilerType &compiler_type) {
+ if (!die)
return false;
-}
-size_t
-DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die, CompilerType &class_compiler_type)
-{
- size_t count = 0;
- uint32_t member_idx = 0;
+ const dw_tag_t tag = die.Tag();
- ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
- GoASTContext *ast = llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem());
- if (ast == nullptr)
- return 0;
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ Log *log =
+ nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
+ if (log)
+ dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
+ log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
+ die.GetID(), DW_TAG_value_to_name(tag), type->GetName().AsCString());
+ assert(compiler_type);
+ DWARFAttributes attributes;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
+ switch (tag) {
+ case DW_TAG_structure_type: {
{
- dw_tag_t tag = die.Tag();
-
- switch (tag)
- {
- case DW_TAG_member:
- {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0)
- {
- Declaration decl;
- const char *name = NULL;
-
- DWARFFormValue encoding_uid;
- uint32_t member_byte_offset = UINT32_MAX;
- uint32_t i;
- for (i = 0; i < num_attributes; ++i)
- {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value))
- {
- switch (attr)
- {
- case DW_AT_name:
- name = form_value.AsCString();
- break;
- case DW_AT_type:
- encoding_uid = form_value;
- break;
- case DW_AT_data_member_location:
- if (form_value.BlockData())
- {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data =
- die.GetDWARF()->get_debug_info_data();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
- NULL, // ClangExpressionVariableList *
- NULL, // ClangExpressionDeclMap *
- NULL, // RegisterContext *
- module_sp, debug_info_data, die.GetCU(),
- block_offset, block_length, eRegisterKindDWARF,
- &initialValue, NULL, memberOffset, NULL))
- {
- member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
- }
- }
- else
- {
- // With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning
- // of the containing entity.
- member_byte_offset = form_value.Unsigned();
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
- if (member_type)
- {
- CompilerType member_go_type = member_type->GetFullCompilerType();
- ConstString name_const_str(name);
- m_ast.AddFieldToStruct(class_compiler_type, name_const_str, member_go_type, member_byte_offset);
- }
+ if (die.HasChildren()) {
+ SymbolContext sc(die.GetLLDBCompileUnit());
+
+ ParseChildMembers(sc, die, compiler_type);
+ }
+ }
+ m_ast.CompleteStructType(compiler_type);
+ return (bool)compiler_type;
+ }
+
+ default:
+ assert(false && "not a forward go type decl!");
+ break;
+ }
+
+ return false;
+}
+
+size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
+ const DWARFDIE &parent_die,
+ CompilerType &class_compiler_type) {
+ size_t count = 0;
+ uint32_t member_idx = 0;
+
+ ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
+ GoASTContext *ast =
+ llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem());
+ if (ast == nullptr)
+ return 0;
+
+ for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
+ die = die.GetSibling()) {
+ dw_tag_t tag = die.Tag();
+
+ switch (tag) {
+ case DW_TAG_member: {
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes > 0) {
+ Declaration decl;
+ const char *name = NULL;
+
+ DWARFFormValue encoding_uid;
+ uint32_t member_byte_offset = UINT32_MAX;
+ uint32_t i;
+ for (i = 0; i < num_attributes; ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_name:
+ name = form_value.AsCString();
+ break;
+ case DW_AT_type:
+ encoding_uid = form_value;
+ break;
+ case DW_AT_data_member_location:
+ if (form_value.BlockData()) {
+ Value initialValue(0);
+ Value memberOffset(0);
+ const DWARFDataExtractor &debug_info_data =
+ die.GetDWARF()->get_debug_info_data();
+ uint32_t block_length = form_value.Unsigned();
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ if (DWARFExpression::Evaluate(
+ NULL, // ExecutionContext *
+ NULL, // ClangExpressionVariableList *
+ NULL, // ClangExpressionDeclMap *
+ NULL, // RegisterContext *
+ module_sp, debug_info_data, die.GetCU(), block_offset,
+ block_length, eRegisterKindDWARF, &initialValue, NULL,
+ memberOffset, NULL)) {
+ member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
}
- ++member_idx;
- }
- break;
+ } else {
+ // With DWARF 3 and later, if the value is an integer constant,
+ // this form value is the offset in bytes from the beginning
+ // of the containing entity.
+ member_byte_offset = form_value.Unsigned();
+ }
+ break;
default:
- break;
+ break;
+ }
+ }
}
+
+ Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
+ if (member_type) {
+ CompilerType member_go_type = member_type->GetFullCompilerType();
+ ConstString name_const_str(name);
+ m_ast.AddFieldToStruct(class_compiler_type, name_const_str,
+ member_go_type, member_byte_offset);
+ }
+ }
+ ++member_idx;
+ } break;
+
+ default:
+ break;
}
+ }
- return count;
+ return count;
}
-Function *
-DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc, const DWARFDIE &die)
-{
- DWARFRangeList func_ranges;
- const char *name = NULL;
- const char *mangled = NULL;
- int decl_file = 0;
- int decl_line = 0;
- int decl_column = 0;
- int call_file = 0;
- int call_line = 0;
- int call_column = 0;
- DWARFExpression frame_base(die.GetCU());
-
- assert(die.Tag() == DW_TAG_subprogram);
-
- if (die.Tag() != DW_TAG_subprogram)
- return NULL;
-
- if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line,
- call_column, &frame_base))
- {
- // Union of all ranges in the function DIE (if the function is discontiguous)
- AddressRange func_range;
- lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
- lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
- if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
- {
- ModuleSP module_sp(die.GetModule());
- func_range.GetBaseAddress().ResolveAddressUsingFileSections(lowest_func_addr, module_sp->GetSectionList());
- if (func_range.GetBaseAddress().IsValid())
- func_range.SetByteSize(highest_func_addr - lowest_func_addr);
- }
+Function *DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc,
+ const DWARFDIE &die) {
+ DWARFRangeList func_ranges;
+ const char *name = NULL;
+ const char *mangled = NULL;
+ int decl_file = 0;
+ int decl_line = 0;
+ int decl_column = 0;
+ int call_file = 0;
+ int call_line = 0;
+ int call_column = 0;
+ DWARFExpression frame_base(die.GetCU());
+
+ assert(die.Tag() == DW_TAG_subprogram);
+
+ if (die.Tag() != DW_TAG_subprogram)
+ return NULL;
- if (func_range.GetBaseAddress().IsValid())
- {
- Mangled func_name;
- func_name.SetValue(ConstString(name), false);
-
- FunctionSP func_sp;
- std::unique_ptr<Declaration> decl_ap;
- if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line,
- decl_column));
-
- SymbolFileDWARF *dwarf = die.GetDWARF();
- // Supply the type _only_ if it has already been parsed
- Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
-
- assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
-
- if (dwarf->FixupAddress(func_range.GetBaseAddress()))
- {
- const user_id_t func_user_id = die.GetID();
- func_sp.reset(new Function(sc.comp_unit,
- func_user_id, // UserID is the DIE offset
- func_user_id,
- func_name,
- func_type,
- func_range)); // first address range
-
- if (func_sp.get() != NULL)
- {
- if (frame_base.IsValid())
- func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
- return func_sp.get();
- }
- }
+ if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
+ decl_column, call_file, call_line, call_column,
+ &frame_base)) {
+ // Union of all ranges in the function DIE (if the function is
+ // discontiguous)
+ AddressRange func_range;
+ lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
+ lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
+ if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
+ lowest_func_addr <= highest_func_addr) {
+ ModuleSP module_sp(die.GetModule());
+ func_range.GetBaseAddress().ResolveAddressUsingFileSections(
+ lowest_func_addr, module_sp->GetSectionList());
+ if (func_range.GetBaseAddress().IsValid())
+ func_range.SetByteSize(highest_func_addr - lowest_func_addr);
+ }
+
+ if (func_range.GetBaseAddress().IsValid()) {
+ Mangled func_name;
+ func_name.SetValue(ConstString(name), false);
+
+ FunctionSP func_sp;
+ std::unique_ptr<Declaration> decl_ap;
+ if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+ decl_ap.reset(new Declaration(
+ sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
+ decl_line, decl_column));
+
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ // Supply the type _only_ if it has already been parsed
+ Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
+
+ assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
+
+ if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
+ const user_id_t func_user_id = die.GetID();
+ func_sp.reset(new Function(sc.comp_unit,
+ func_user_id, // UserID is the DIE offset
+ func_user_id, func_name, func_type,
+ func_range)); // first address range
+
+ if (func_sp.get() != NULL) {
+ if (frame_base.IsValid())
+ func_sp->GetFrameBaseExpression() = frame_base;
+ sc.comp_unit->AddFunction(func_sp);
+ return func_sp.get();
}
+ }
}
- return NULL;
+ }
+ return NULL;
}