1 //===-- DWARFASTParserGo.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "DWARFASTParserGo.h"
12 #include "DWARFASTParserGo.h"
13 #include "DWARFCompileUnit.h"
15 #include "DWARFDIECollection.h"
16 #include "DWARFDebugInfo.h"
17 #include "DWARFDeclContext.h"
18 #include "DWARFDefines.h"
19 #include "SymbolFileDWARF.h"
20 #include "SymbolFileDWARFDebugMap.h"
21 #include "UniqueDWARFASTType.h"
23 #include "clang/Basic/Specifiers.h"
25 #include "lldb/Core/Module.h"
26 #include "lldb/Core/Value.h"
27 #include "lldb/Symbol/CompileUnit.h"
28 #include "lldb/Symbol/Function.h"
29 #include "lldb/Symbol/ObjectFile.h"
30 #include "lldb/Symbol/TypeList.h"
32 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
34 #ifdef ENABLE_DEBUG_PRINTF
36 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
38 #define DEBUG_PRINTF(fmt, ...)
41 #define DW_AT_go_kind 0x2900
42 #define DW_AT_go_key 0x2901
43 #define DW_AT_go_elem 0x2902
46 using namespace lldb_private;
47 DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {}
49 DWARFASTParserGo::~DWARFASTParserGo() {}
51 TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
52 const lldb_private::SymbolContext &sc, const DWARFDIE &die,
53 lldb_private::Log *log, bool *type_is_new_ptr) {
57 *type_is_new_ptr = false;
60 SymbolFileDWARF *dwarf = die.GetDWARF();
62 dwarf->GetObjectFile()->GetModule()->LogMessage(
63 log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = "
65 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
68 Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
69 TypeList *type_list = dwarf->GetTypeList();
70 if (type_ptr == NULL) {
72 *type_is_new_ptr = true;
74 const dw_tag_t tag = die.Tag();
76 bool is_forward_declaration = false;
77 DWARFAttributes attributes;
78 const char *type_name_cstr = NULL;
79 ConstString type_name_const_str;
80 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
81 uint64_t byte_size = 0;
85 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
86 CompilerType compiler_type;
87 DWARFFormValue form_value;
92 case DW_TAG_base_type:
93 case DW_TAG_pointer_type:
95 case DW_TAG_unspecified_type: {
96 // Set a bit that lets us know that we are currently parsing this
97 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
99 const size_t num_attributes = die.GetAttributes(attributes);
100 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
102 if (num_attributes > 0) {
104 for (i = 0; i < num_attributes; ++i) {
105 attr = attributes.AttributeAtIndex(i);
106 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
109 type_name_cstr = form_value.AsCString();
111 type_name_const_str.SetCString(type_name_cstr);
113 case DW_AT_byte_size:
114 byte_size = form_value.Unsigned();
117 // = form_value.Unsigned();
120 encoding_uid = form_value.Reference();
123 go_kind = form_value.Unsigned();
126 // Do we care about DW_AT_go_key or DW_AT_go_elem?
133 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n",
134 die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr,
141 case DW_TAG_unspecified_type:
142 resolve_state = Type::eResolveStateFull;
143 compiler_type = m_ast.CreateVoidType(type_name_const_str);
146 case DW_TAG_base_type:
147 resolve_state = Type::eResolveStateFull;
149 m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size);
152 case DW_TAG_pointer_type:
153 encoding_data_type = Type::eEncodingIsPointerUID;
156 encoding_data_type = Type::eEncodingIsTypedefUID;
158 Type *type = dwarf->ResolveTypeUID(encoding_uid);
160 if (go_kind == 0 && type->GetName() == type_name_const_str) {
161 // Go emits extra typedefs as a forward declaration. Ignore these.
162 dwarf->m_die_to_type[die.GetDIE()] = type;
163 return type->shared_from_this();
165 impl = type->GetForwardCompilerType();
167 m_ast.CreateTypedefType(go_kind, type_name_const_str, impl);
172 type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
173 byte_size, NULL, encoding_uid,
174 encoding_data_type, &decl, compiler_type,
177 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
180 case DW_TAG_structure_type: {
181 // Set a bit that lets us know that we are currently parsing this
182 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
183 bool byte_size_valid = false;
185 const size_t num_attributes = die.GetAttributes(attributes);
186 if (num_attributes > 0) {
188 for (i = 0; i < num_attributes; ++i) {
189 attr = attributes.AttributeAtIndex(i);
190 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
193 type_name_cstr = form_value.AsCString();
194 type_name_const_str.SetCString(type_name_cstr);
197 case DW_AT_byte_size:
198 byte_size = form_value.Unsigned();
199 byte_size_valid = true;
203 go_kind = form_value.Unsigned();
206 // TODO: Should we use SLICETYPE's DW_AT_go_elem?
214 // TODO(ribrdb): Do we need this?
216 // UniqueDWARFASTType is large, so don't create a local variables on the
217 // stack, put it on the heap. This function is often called recursively
218 // and clang isn't good and sharing the stack space for variables in
220 std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(
221 new UniqueDWARFASTType());
223 // Only try and unique the type if it has a name.
224 if (type_name_const_str &&
225 dwarf->GetUniqueDWARFASTTypeMap().Find(
226 type_name_const_str, die, decl,
227 byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
228 // We have already parsed this type or from another
229 // compile unit. GCC loves to use the "one definition
230 // rule" which can result in multiple definitions
231 // of the same class over and over in each compile
233 type_sp = unique_ast_entry_ap->m_type_sp;
235 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
240 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
241 DW_TAG_value_to_name(tag), type_name_cstr);
243 bool compiler_type_was_created = false;
244 compiler_type.SetCompilerType(
246 dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
247 if (!compiler_type) {
248 compiler_type_was_created = true;
250 m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
253 type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
254 byte_size, NULL, LLDB_INVALID_UID,
255 Type::eEncodingIsUID, &decl, compiler_type,
256 Type::eResolveStateForward));
258 // Add our type to the unique type map so we don't
259 // end up creating many copies of the same type over
260 // and over in the ASTContext for our module
261 unique_ast_entry_ap->m_type_sp = type_sp;
262 unique_ast_entry_ap->m_die = die;
263 unique_ast_entry_ap->m_declaration = decl;
264 unique_ast_entry_ap->m_byte_size = byte_size;
265 dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str,
266 *unique_ast_entry_ap);
268 if (!is_forward_declaration) {
269 // Always start the definition for a class type so that
270 // if the class has child classes or types that require
271 // the class to be created for use as their decl contexts
272 // the class will be ready to accept these child definitions.
273 if (die.HasChildren() == false) {
274 // No children for this struct/union/class, lets finish it
275 m_ast.CompleteStructType(compiler_type);
276 } else if (compiler_type_was_created) {
277 // Leave this as a forward declaration until we need
278 // to know the details of the type. lldb_private::Type
279 // will automatically call the SymbolFile virtual function
280 // "SymbolFileDWARF::CompleteType(Type *)"
281 // When the definition needs to be defined.
282 dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] =
283 compiler_type.GetOpaqueQualType();
284 dwarf->m_forward_decl_clang_type_to_die[compiler_type
285 .GetOpaqueQualType()] =
287 // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
292 case DW_TAG_subprogram:
293 case DW_TAG_subroutine_type: {
294 // Set a bit that lets us know that we are currently parsing this
295 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
297 bool is_variadic = false;
298 clang::StorageClass storage =
299 clang::SC_None; //, Extern, Static, PrivateExtern
301 const size_t num_attributes = die.GetAttributes(attributes);
302 if (num_attributes > 0) {
304 for (i = 0; i < num_attributes; ++i) {
305 attr = attributes.AttributeAtIndex(i);
306 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
309 type_name_cstr = form_value.AsCString();
310 type_name_const_str.SetCString(type_name_cstr);
314 if (form_value.Unsigned()) {
315 if (storage == clang::SC_None)
316 storage = clang::SC_Extern;
318 storage = clang::SC_PrivateExtern;
330 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
331 DW_TAG_value_to_name(tag), type_name_cstr);
333 std::vector<CompilerType> function_param_types;
335 // Parse the function children for the parameters
337 if (die.HasChildren()) {
338 ParseChildParameters(sc, die, is_variadic, function_param_types);
341 // compiler_type will get the function prototype clang type after this
343 compiler_type = m_ast.CreateFunctionType(
344 type_name_const_str, function_param_types.data(),
345 function_param_types.size(), is_variadic);
347 type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
348 LLDB_INVALID_UID, Type::eEncodingIsUID, &decl,
349 compiler_type, Type::eResolveStateFull));
350 assert(type_sp.get());
353 case DW_TAG_array_type: {
354 // Set a bit that lets us know that we are currently parsing this
355 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
357 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
358 int64_t first_index = 0;
359 uint32_t byte_stride = 0;
360 uint32_t bit_stride = 0;
361 const size_t num_attributes = die.GetAttributes(attributes);
363 if (num_attributes > 0) {
365 for (i = 0; i < num_attributes; ++i) {
366 attr = attributes.AttributeAtIndex(i);
367 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
370 type_name_cstr = form_value.AsCString();
371 type_name_const_str.SetCString(type_name_cstr);
375 type_die_offset = form_value.Reference();
377 case DW_AT_byte_size:
378 break; // byte_size = form_value.Unsigned(); break;
380 go_kind = form_value.Unsigned();
388 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
389 DW_TAG_value_to_name(tag), type_name_cstr);
391 Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
394 std::vector<uint64_t> element_orders;
395 ParseChildArrayInfo(sc, die, first_index, element_orders,
396 byte_stride, bit_stride);
397 if (byte_stride == 0)
398 byte_stride = element_type->GetByteSize();
399 CompilerType array_element_type =
400 element_type->GetForwardCompilerType();
401 if (element_orders.size() > 0) {
402 if (element_orders.size() > 1)
403 printf("golang: unsupported multi-dimensional array %s\n",
405 compiler_type = m_ast.CreateArrayType(
406 type_name_const_str, array_element_type, element_orders[0]);
408 compiler_type = m_ast.CreateArrayType(type_name_const_str,
409 array_element_type, 0);
411 type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
412 byte_stride, NULL, type_die_offset,
413 Type::eEncodingIsUID, &decl, compiler_type,
414 Type::eResolveStateFull));
415 type_sp->SetEncodingType(element_type);
421 dwarf->GetObjectFile()->GetModule()->ReportError(
422 "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), "
423 "please file a bug and attach the file at the "
424 "start of this error message",
425 die.GetOffset(), tag, DW_TAG_value_to_name(tag));
430 DWARFDIE sc_parent_die =
431 SymbolFileDWARF::GetParentSymbolContextDIE(die);
432 dw_tag_t sc_parent_tag = sc_parent_die.Tag();
434 SymbolContextScope *symbol_context_scope = NULL;
435 if (sc_parent_tag == DW_TAG_compile_unit) {
436 symbol_context_scope = sc.comp_unit;
437 } else if (sc.function != NULL && sc_parent_die) {
438 symbol_context_scope =
439 sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
440 if (symbol_context_scope == NULL)
441 symbol_context_scope = sc.function;
444 if (symbol_context_scope != NULL) {
445 type_sp->SetSymbolContextScope(symbol_context_scope);
448 // We are ready to put this type into the uniqued list up at the module
450 type_list->Insert(type_sp);
452 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
454 } else if (type_ptr != DIE_IS_BEING_PARSED) {
455 type_sp = type_ptr->shared_from_this();
461 size_t DWARFASTParserGo::ParseChildParameters(
462 const SymbolContext &sc,
464 const DWARFDIE &parent_die, bool &is_variadic,
465 std::vector<CompilerType> &function_param_types) {
470 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
471 die = die.GetSibling()) {
473 dw_tag_t tag = die.Tag();
475 case DW_TAG_formal_parameter: {
476 DWARFAttributes attributes;
477 const size_t num_attributes = die.GetAttributes(attributes);
478 if (num_attributes > 0) {
480 DWARFFormValue param_type_die_offset;
483 for (i = 0; i < num_attributes; ++i) {
484 const dw_attr_t attr = attributes.AttributeAtIndex(i);
485 DWARFFormValue form_value;
486 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
489 // = form_value.AsCString();
492 param_type_die_offset = form_value;
495 // if (form_value.BlockData())
497 // const DWARFDataExtractor&
500 // uint32_t block_length =
501 // form_value.Unsigned();
502 // DWARFDataExtractor
503 // location(debug_info_data,
504 // form_value.BlockData() -
505 // debug_info_data.GetDataStart(),
518 Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
520 function_param_types.push_back(type->GetForwardCompilerType());
526 case DW_TAG_unspecified_parameters:
537 void DWARFASTParserGo::ParseChildArrayInfo(
538 const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
539 std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
540 uint32_t &bit_stride) {
544 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
545 die = die.GetSibling()) {
546 const dw_tag_t tag = die.Tag();
548 case DW_TAG_subrange_type: {
549 DWARFAttributes attributes;
550 const size_t num_child_attributes = die.GetAttributes(attributes);
551 if (num_child_attributes > 0) {
552 uint64_t num_elements = 0;
554 for (i = 0; i < num_child_attributes; ++i) {
555 const dw_attr_t attr = attributes.AttributeAtIndex(i);
556 DWARFFormValue form_value;
557 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
560 num_elements = form_value.Unsigned();
570 element_orders.push_back(num_elements);
577 bool DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die,
578 lldb_private::Type *type,
579 CompilerType &compiler_type) {
583 const dw_tag_t tag = die.Tag();
585 SymbolFileDWARF *dwarf = die.GetDWARF();
587 nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
589 dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
590 log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
591 die.GetID(), DW_TAG_value_to_name(tag), type->GetName().AsCString());
592 assert(compiler_type);
593 DWARFAttributes attributes;
596 case DW_TAG_structure_type: {
598 if (die.HasChildren()) {
599 SymbolContext sc(die.GetLLDBCompileUnit());
601 ParseChildMembers(sc, die, compiler_type);
604 m_ast.CompleteStructType(compiler_type);
605 return (bool)compiler_type;
609 assert(false && "not a forward go type decl!");
616 size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
617 const DWARFDIE &parent_die,
618 CompilerType &class_compiler_type) {
620 uint32_t member_idx = 0;
622 ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
624 llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem());
628 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
629 die = die.GetSibling()) {
630 dw_tag_t tag = die.Tag();
633 case DW_TAG_member: {
634 DWARFAttributes attributes;
635 const size_t num_attributes = die.GetAttributes(attributes);
636 if (num_attributes > 0) {
638 const char *name = NULL;
640 DWARFFormValue encoding_uid;
641 uint32_t member_byte_offset = UINT32_MAX;
643 for (i = 0; i < num_attributes; ++i) {
644 const dw_attr_t attr = attributes.AttributeAtIndex(i);
645 DWARFFormValue form_value;
646 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
649 name = form_value.AsCString();
652 encoding_uid = form_value;
654 case DW_AT_data_member_location:
655 if (form_value.BlockData()) {
656 Value initialValue(0);
657 Value memberOffset(0);
658 const DWARFDataExtractor &debug_info_data =
659 die.GetDWARF()->get_debug_info_data();
660 uint32_t block_length = form_value.Unsigned();
661 uint32_t block_offset =
662 form_value.BlockData() - debug_info_data.GetDataStart();
663 if (DWARFExpression::Evaluate(
664 NULL, // ExecutionContext *
665 NULL, // RegisterContext *
666 module_sp, debug_info_data, die.GetCU(), block_offset,
667 block_length, eRegisterKindDWARF, &initialValue, NULL,
668 memberOffset, NULL)) {
669 member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
672 // With DWARF 3 and later, if the value is an integer constant,
673 // this form value is the offset in bytes from the beginning
674 // of the containing entity.
675 member_byte_offset = form_value.Unsigned();
685 Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
687 CompilerType member_go_type = member_type->GetFullCompilerType();
688 ConstString name_const_str(name);
689 m_ast.AddFieldToStruct(class_compiler_type, name_const_str,
690 member_go_type, member_byte_offset);
704 Function *DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc,
705 const DWARFDIE &die) {
706 DWARFRangeList func_ranges;
707 const char *name = NULL;
708 const char *mangled = NULL;
715 DWARFExpression frame_base(die.GetCU());
717 assert(die.Tag() == DW_TAG_subprogram);
719 if (die.Tag() != DW_TAG_subprogram)
722 if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
723 decl_column, call_file, call_line, call_column,
725 // Union of all ranges in the function DIE (if the function is
727 AddressRange func_range;
728 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
729 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
730 if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
731 lowest_func_addr <= highest_func_addr) {
732 ModuleSP module_sp(die.GetModule());
733 func_range.GetBaseAddress().ResolveAddressUsingFileSections(
734 lowest_func_addr, module_sp->GetSectionList());
735 if (func_range.GetBaseAddress().IsValid())
736 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
739 if (func_range.GetBaseAddress().IsValid()) {
741 func_name.SetValue(ConstString(name), false);
744 std::unique_ptr<Declaration> decl_ap;
745 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
746 decl_ap.reset(new Declaration(
747 sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
748 decl_line, decl_column));
750 SymbolFileDWARF *dwarf = die.GetDWARF();
751 // Supply the type _only_ if it has already been parsed
752 Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
754 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
756 if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
757 const user_id_t func_user_id = die.GetID();
758 func_sp.reset(new Function(sc.comp_unit,
759 func_user_id, // UserID is the DIE offset
760 func_user_id, func_name, func_type,
761 func_range)); // first address range
763 if (func_sp.get() != NULL) {
764 if (frame_base.IsValid())
765 func_sp->GetFrameBaseExpression() = frame_base;
766 sc.comp_unit->AddFunction(func_sp);
767 return func_sp.get();