]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
MFV r313676: libpcap 1.8.1
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / DWARFASTParserGo.cpp
1 //===-- DWARFASTParserGo.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "DWARFASTParserGo.h"
11
12 #include "DWARFASTParserGo.h"
13 #include "DWARFCompileUnit.h"
14 #include "DWARFDebugInfo.h"
15 #include "DWARFDeclContext.h"
16 #include "DWARFDefines.h"
17 #include "DWARFDIE.h"
18 #include "DWARFDIECollection.h"
19 #include "SymbolFileDWARF.h"
20 #include "SymbolFileDWARFDebugMap.h"
21 #include "UniqueDWARFASTType.h"
22
23 #include "clang/Basic/Specifiers.h"
24
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"
31
32 //#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
33
34 #ifdef ENABLE_DEBUG_PRINTF
35 #include <stdio.h>
36 #define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
37 #else
38 #define DEBUG_PRINTF(fmt, ...)
39 #endif
40
41 #define DW_AT_go_kind 0x2900
42 #define DW_AT_go_key 0x2901
43 #define DW_AT_go_elem 0x2902
44
45 using namespace lldb;
46 using namespace lldb_private;
47 DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast)
48     : m_ast(ast)
49 {
50 }
51
52 DWARFASTParserGo::~DWARFASTParserGo()
53 {
54 }
55
56 TypeSP
57 DWARFASTParserGo::ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die, lldb_private::Log *log,
58                                      bool *type_is_new_ptr)
59 {
60     TypeSP type_sp;
61
62     if (type_is_new_ptr)
63         *type_is_new_ptr = false;
64
65     if (die)
66     {
67         SymbolFileDWARF *dwarf = die.GetDWARF();
68         if (log)
69         {
70             dwarf->GetObjectFile()->GetModule()->LogMessage(
71                 log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = '%s')", die.GetOffset(),
72                 DW_TAG_value_to_name(die.Tag()), die.GetName());
73         }
74
75         Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
76         TypeList *type_list = dwarf->GetTypeList();
77         if (type_ptr == NULL)
78         {
79             if (type_is_new_ptr)
80                 *type_is_new_ptr = true;
81
82             const dw_tag_t tag = die.Tag();
83
84             bool is_forward_declaration = false;
85             DWARFAttributes attributes;
86             const char *type_name_cstr = NULL;
87             ConstString type_name_const_str;
88             Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
89             uint64_t byte_size = 0;
90             uint64_t go_kind = 0;
91             Declaration decl;
92
93             Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
94             CompilerType compiler_type;
95             DWARFFormValue form_value;
96
97             dw_attr_t attr;
98
99             switch (tag)
100             {
101                 case DW_TAG_base_type:
102                 case DW_TAG_pointer_type:
103                 case DW_TAG_typedef:
104                 case DW_TAG_unspecified_type:
105                 {
106                     // Set a bit that lets us know that we are currently parsing this
107                     dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
108
109                     const size_t num_attributes = die.GetAttributes(attributes);
110                     lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
111
112                     if (num_attributes > 0)
113                     {
114                         uint32_t i;
115                         for (i = 0; i < num_attributes; ++i)
116                         {
117                             attr = attributes.AttributeAtIndex(i);
118                             if (attributes.ExtractFormValueAtIndex(i, form_value))
119                             {
120                                 switch (attr)
121                                 {
122                                     case DW_AT_name:
123                                         type_name_cstr = form_value.AsCString();
124                                         if (type_name_cstr)
125                                             type_name_const_str.SetCString(type_name_cstr);
126                                         break;
127                                     case DW_AT_byte_size:
128                                         byte_size = form_value.Unsigned();
129                                         break;
130                                     case DW_AT_encoding:
131                                         // = form_value.Unsigned();
132                                         break;
133                                     case DW_AT_type:
134                                         encoding_uid = form_value.Reference();
135                                         break;
136                                     case DW_AT_go_kind:
137                                         go_kind = form_value.Unsigned();
138                                         break;
139                                     default:
140                                         // Do we care about DW_AT_go_key or DW_AT_go_elem?
141                                         break;
142                                 }
143                             }
144                         }
145                     }
146
147                     DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(),
148                                  DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
149
150                     switch (tag)
151                     {
152                         default:
153                             break;
154
155                         case DW_TAG_unspecified_type:
156                             resolve_state = Type::eResolveStateFull;
157                             compiler_type = m_ast.CreateVoidType(type_name_const_str);
158                             break;
159
160                         case DW_TAG_base_type:
161                             resolve_state = Type::eResolveStateFull;
162                             compiler_type = m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size);
163                             break;
164
165                         case DW_TAG_pointer_type:
166                             encoding_data_type = Type::eEncodingIsPointerUID;
167                             break;
168                         case DW_TAG_typedef:
169                             encoding_data_type = Type::eEncodingIsTypedefUID;
170                             CompilerType impl;
171                             Type *type = dwarf->ResolveTypeUID(encoding_uid);
172                             if (type)
173                             {
174                                 if (go_kind == 0 && type->GetName() == type_name_const_str)
175                                 {
176                                     // Go emits extra typedefs as a forward declaration. Ignore these.
177                                     dwarf->m_die_to_type[die.GetDIE()] = type;
178                                     return type->shared_from_this();
179                                 }
180                                 impl = type->GetForwardCompilerType();
181                                 compiler_type = m_ast.CreateTypedefType (go_kind, type_name_const_str, impl);
182                             }
183                             break;
184                     }
185
186                     type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size,
187                                            NULL, encoding_uid, encoding_data_type, &decl, compiler_type, resolve_state));
188
189                     dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
190                 }
191                 break;
192
193                 case DW_TAG_structure_type:
194                 {
195                     // Set a bit that lets us know that we are currently parsing this
196                     dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
197                     bool byte_size_valid = false;
198
199                     const size_t num_attributes = die.GetAttributes(attributes);
200                     if (num_attributes > 0)
201                     {
202                         uint32_t i;
203                         for (i = 0; i < num_attributes; ++i)
204                         {
205                             attr = attributes.AttributeAtIndex(i);
206                             if (attributes.ExtractFormValueAtIndex(i, form_value))
207                             {
208                                 switch (attr)
209                                 {
210                                     case DW_AT_name:
211                                         type_name_cstr = form_value.AsCString();
212                                         type_name_const_str.SetCString(type_name_cstr);
213                                         break;
214
215                                     case DW_AT_byte_size:
216                                         byte_size = form_value.Unsigned();
217                                         byte_size_valid = true;
218                                         break;
219
220                                     case DW_AT_go_kind:
221                                         go_kind = form_value.Unsigned();
222                                         break;
223
224                                     // TODO: Should we use SLICETYPE's DW_AT_go_elem?
225                                     default:
226                                         break;
227                                 }
228                             }
229                         }
230                     }
231
232                     // TODO(ribrdb): Do we need this?
233
234                     // UniqueDWARFASTType is large, so don't create a local variables on the
235                     // stack, put it on the heap. This function is often called recursively
236                     // and clang isn't good and sharing the stack space for variables in different blocks.
237                     std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());
238
239                     // Only try and unique the type if it has a name.
240                     if (type_name_const_str &&
241                         dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl,
242                                                                byte_size_valid ? byte_size : -1, *unique_ast_entry_ap))
243                     {
244                         // We have already parsed this type or from another
245                         // compile unit. GCC loves to use the "one definition
246                         // rule" which can result in multiple definitions
247                         // of the same class over and over in each compile
248                         // unit.
249                         type_sp = unique_ast_entry_ap->m_type_sp;
250                         if (type_sp)
251                         {
252                             dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
253                             return type_sp;
254                         }
255                     }
256
257                     DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
258                                  DW_TAG_value_to_name(tag), type_name_cstr);
259
260                     bool compiler_type_was_created = false;
261                     compiler_type.SetCompilerType(&m_ast, dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
262                     if (!compiler_type)
263                     {
264                         compiler_type_was_created = true;
265                         compiler_type = m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
266                     }
267
268                     type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, byte_size,
269                                            NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
270                                            Type::eResolveStateForward));
271
272                     // Add our type to the unique type map so we don't
273                     // end up creating many copies of the same type over
274                     // and over in the ASTContext for our module
275                     unique_ast_entry_ap->m_type_sp = type_sp;
276                     unique_ast_entry_ap->m_die = die;
277                     unique_ast_entry_ap->m_declaration = decl;
278                     unique_ast_entry_ap->m_byte_size = byte_size;
279                     dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str, *unique_ast_entry_ap);
280
281                     if (!is_forward_declaration)
282                     {
283                         // Always start the definition for a class type so that
284                         // if the class has child classes or types that require
285                         // the class to be created for use as their decl contexts
286                         // the class will be ready to accept these child definitions.
287                         if (die.HasChildren() == false)
288                         {
289                             // No children for this struct/union/class, lets finish it
290                             m_ast.CompleteStructType(compiler_type);
291                         }
292                         else if (compiler_type_was_created)
293                         {
294                             // Leave this as a forward declaration until we need
295                             // to know the details of the type. lldb_private::Type
296                             // will automatically call the SymbolFile virtual function
297                             // "SymbolFileDWARF::CompleteType(Type *)"
298                             // When the definition needs to be defined.
299                             dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] = compiler_type.GetOpaqueQualType();
300                             dwarf->m_forward_decl_clang_type_to_die[compiler_type.GetOpaqueQualType()] = die.GetDIERef();
301                             // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
302                         }
303                     }
304                 }
305                 break;
306
307                 case DW_TAG_subprogram:
308                 case DW_TAG_subroutine_type:
309                 {
310                     // Set a bit that lets us know that we are currently parsing this
311                     dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
312
313                     bool is_variadic = false;
314                     clang::StorageClass storage = clang::SC_None; //, Extern, Static, PrivateExtern
315
316                     const size_t num_attributes = die.GetAttributes(attributes);
317                     if (num_attributes > 0)
318                     {
319                         uint32_t i;
320                         for (i = 0; i < num_attributes; ++i)
321                         {
322                             attr = attributes.AttributeAtIndex(i);
323                             if (attributes.ExtractFormValueAtIndex(i, form_value))
324                             {
325                                 switch (attr)
326                                 {
327                                     case DW_AT_name:
328                                         type_name_cstr = form_value.AsCString();
329                                         type_name_const_str.SetCString(type_name_cstr);
330                                         break;
331
332                                     case DW_AT_external:
333                                         if (form_value.Unsigned())
334                                         {
335                                             if (storage == clang::SC_None)
336                                                 storage = clang::SC_Extern;
337                                             else
338                                                 storage = clang::SC_PrivateExtern;
339                                         }
340                                         break;
341
342                                     case DW_AT_high_pc:
343                                     case DW_AT_low_pc:
344                                         break;
345                                 }
346                             }
347                         }
348                     }
349
350                     DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
351                                  DW_TAG_value_to_name(tag), type_name_cstr);
352
353                     std::vector<CompilerType> function_param_types;
354
355                     // Parse the function children for the parameters
356
357                     if (die.HasChildren())
358                     {
359                         ParseChildParameters(sc, die, is_variadic, function_param_types);
360                     }
361
362                     // compiler_type will get the function prototype clang type after this call
363                     compiler_type = m_ast.CreateFunctionType(type_name_const_str, function_param_types.data(),
364                                                           function_param_types.size(), is_variadic);
365
366                     type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
367                                            LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
368                                            Type::eResolveStateFull));
369                     assert(type_sp.get());
370                 }
371                 break;
372
373                 case DW_TAG_array_type:
374                 {
375                     // Set a bit that lets us know that we are currently parsing this
376                     dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
377
378                     lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
379                     int64_t first_index = 0;
380                     uint32_t byte_stride = 0;
381                     uint32_t bit_stride = 0;
382                     const size_t num_attributes = die.GetAttributes(attributes);
383
384                     if (num_attributes > 0)
385                     {
386                         uint32_t i;
387                         for (i = 0; i < num_attributes; ++i)
388                         {
389                             attr = attributes.AttributeAtIndex(i);
390                             if (attributes.ExtractFormValueAtIndex(i, form_value))
391                             {
392                                 switch (attr)
393                                 {
394                                     case DW_AT_name:
395                                         type_name_cstr = form_value.AsCString();
396                                         type_name_const_str.SetCString(type_name_cstr);
397                                         break;
398
399                                     case DW_AT_type:
400                                         type_die_offset = form_value.Reference();
401                                         break;
402                                     case DW_AT_byte_size:
403                                         break; // byte_size = form_value.Unsigned(); break;
404                                     case DW_AT_go_kind:
405                                         go_kind = form_value.Unsigned();
406                                         break;
407                                     default:
408                                         break;
409                                 }
410                             }
411                         }
412
413                         DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
414                                      DW_TAG_value_to_name(tag), type_name_cstr);
415
416                         Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
417
418                         if (element_type)
419                         {
420                             std::vector<uint64_t> element_orders;
421                             ParseChildArrayInfo(sc, die, first_index, element_orders, byte_stride, bit_stride);
422                             if (byte_stride == 0)
423                                 byte_stride = element_type->GetByteSize();
424                             CompilerType array_element_type = element_type->GetForwardCompilerType();
425                             if (element_orders.size() > 0)
426                             {
427                                 if (element_orders.size() > 1)
428                                     printf("golang: unsupported multi-dimensional array %s\n", type_name_cstr);
429                                 compiler_type =
430                                     m_ast.CreateArrayType(type_name_const_str, array_element_type, element_orders[0]);
431                             }
432                             else
433                             {
434                                 compiler_type = m_ast.CreateArrayType(type_name_const_str, array_element_type, 0);
435                             }
436                             type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
437                                                    byte_stride, NULL, type_die_offset, Type::eEncodingIsUID, &decl,
438                                                    compiler_type, Type::eResolveStateFull));
439                             type_sp->SetEncodingType(element_type);
440                         }
441                     }
442                 }
443                 break;
444
445                 default:
446                     dwarf->GetObjectFile()->GetModule()->ReportError("{0x%8.8x}: unhandled type tag 0x%4.4x (%s), "
447                                                                      "please file a bug and attach the file at the "
448                                                                      "start of this error message",
449                                                                      die.GetOffset(), tag, DW_TAG_value_to_name(tag));
450                     break;
451             }
452
453             if (type_sp.get())
454             {
455                 DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
456                 dw_tag_t sc_parent_tag = sc_parent_die.Tag();
457
458                 SymbolContextScope *symbol_context_scope = NULL;
459                 if (sc_parent_tag == DW_TAG_compile_unit)
460                 {
461                     symbol_context_scope = sc.comp_unit;
462                 }
463                 else if (sc.function != NULL && sc_parent_die)
464                 {
465                     symbol_context_scope =
466                         sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
467                     if (symbol_context_scope == NULL)
468                         symbol_context_scope = sc.function;
469                 }
470
471                 if (symbol_context_scope != NULL)
472                 {
473                     type_sp->SetSymbolContextScope(symbol_context_scope);
474                 }
475
476                 // We are ready to put this type into the uniqued list up at the module level
477                 type_list->Insert(type_sp);
478
479                 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
480             }
481         }
482         else if (type_ptr != DIE_IS_BEING_PARSED)
483         {
484             type_sp = type_ptr->shared_from_this();
485         }
486     }
487     return type_sp;
488 }
489
490 size_t
491 DWARFASTParserGo::ParseChildParameters(const SymbolContext &sc,
492
493                                        const DWARFDIE &parent_die, bool &is_variadic,
494                                        std::vector<CompilerType> &function_param_types)
495 {
496     if (!parent_die)
497         return 0;
498
499     size_t arg_idx = 0;
500     for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
501     {
502
503         dw_tag_t tag = die.Tag();
504         switch (tag)
505         {
506             case DW_TAG_formal_parameter:
507             {
508                 DWARFAttributes attributes;
509                 const size_t num_attributes = die.GetAttributes(attributes);
510                 if (num_attributes > 0)
511                 {
512                     Declaration decl;
513                     DWARFFormValue param_type_die_offset;
514
515                     uint32_t i;
516                     for (i = 0; i < num_attributes; ++i)
517                     {
518                         const dw_attr_t attr = attributes.AttributeAtIndex(i);
519                         DWARFFormValue form_value;
520                         if (attributes.ExtractFormValueAtIndex(i, form_value))
521                         {
522                             switch (attr)
523                             {
524                                 case DW_AT_name:
525                                     // = form_value.AsCString();
526                                     break;
527                                 case DW_AT_type:
528                                     param_type_die_offset = form_value;
529                                     break;
530                                 case DW_AT_location:
531                                 //                          if (form_value.BlockData())
532                                 //                          {
533                                 //                              const DWARFDataExtractor& debug_info_data =
534                                 //                              debug_info();
535                                 //                              uint32_t block_length = form_value.Unsigned();
536                                 //                              DWARFDataExtractor location(debug_info_data,
537                                 //                              form_value.BlockData() - debug_info_data.GetDataStart(),
538                                 //                              block_length);
539                                 //                          }
540                                 //                          else
541                                 //                          {
542                                 //                          }
543                                 //                          break;
544                                 default:
545                                     break;
546                             }
547                         }
548                     }
549
550                     Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
551                     if (type)
552                     {
553                         function_param_types.push_back(type->GetForwardCompilerType());
554                     }
555                 }
556                 arg_idx++;
557             }
558             break;
559
560             case DW_TAG_unspecified_parameters:
561                 is_variadic = true;
562                 break;
563
564             default:
565                 break;
566         }
567     }
568     return arg_idx;
569 }
570
571 void
572 DWARFASTParserGo::ParseChildArrayInfo(const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
573                                       std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
574                                       uint32_t &bit_stride)
575 {
576     if (!parent_die)
577         return;
578
579     for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
580     {
581         const dw_tag_t tag = die.Tag();
582         switch (tag)
583         {
584             case DW_TAG_subrange_type:
585             {
586                 DWARFAttributes attributes;
587                 const size_t num_child_attributes = die.GetAttributes(attributes);
588                 if (num_child_attributes > 0)
589                 {
590                     uint64_t num_elements = 0;
591                     uint32_t i;
592                     for (i = 0; i < num_child_attributes; ++i)
593                     {
594                         const dw_attr_t attr = attributes.AttributeAtIndex(i);
595                         DWARFFormValue form_value;
596                         if (attributes.ExtractFormValueAtIndex(i, form_value))
597                         {
598                             switch (attr)
599                             {
600                                 case DW_AT_count:
601                                     num_elements = form_value.Unsigned();
602                                     break;
603
604                                 default:
605                                 case DW_AT_type:
606                                     break;
607                             }
608                         }
609                     }
610
611                     element_orders.push_back(num_elements);
612                 }
613             }
614             break;
615         }
616     }
617 }
618
619 bool
620 DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &compiler_type)
621 {
622     if (!die)
623         return false;
624
625     const dw_tag_t tag = die.Tag();
626
627     SymbolFileDWARF *dwarf = die.GetDWARF();
628     Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
629     if (log)
630         dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
631             log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", die.GetID(),
632             DW_TAG_value_to_name(tag), type->GetName().AsCString());
633     assert(compiler_type);
634     DWARFAttributes attributes;
635
636     switch (tag)
637     {
638         case DW_TAG_structure_type:
639         {
640             {
641                 if (die.HasChildren())
642                 {
643                     SymbolContext sc(die.GetLLDBCompileUnit());
644
645                     ParseChildMembers(sc, die, compiler_type);
646                 }
647             }
648             m_ast.CompleteStructType(compiler_type);
649             return (bool)compiler_type;
650         }
651
652         default:
653             assert(false && "not a forward go type decl!");
654             break;
655     }
656
657     return false;
658 }
659
660 size_t
661 DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &parent_die, CompilerType &class_compiler_type)
662 {
663     size_t count = 0;
664     uint32_t member_idx = 0;
665
666     ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
667     GoASTContext *ast = llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem());
668     if (ast == nullptr)
669         return 0;
670
671     for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
672     {
673         dw_tag_t tag = die.Tag();
674
675         switch (tag)
676         {
677             case DW_TAG_member:
678             {
679                 DWARFAttributes attributes;
680                 const size_t num_attributes = die.GetAttributes(attributes);
681                 if (num_attributes > 0)
682                 {
683                     Declaration decl;
684                     const char *name = NULL;
685
686                     DWARFFormValue encoding_uid;
687                     uint32_t member_byte_offset = UINT32_MAX;
688                     uint32_t i;
689                     for (i = 0; i < num_attributes; ++i)
690                     {
691                         const dw_attr_t attr = attributes.AttributeAtIndex(i);
692                         DWARFFormValue form_value;
693                         if (attributes.ExtractFormValueAtIndex(i, form_value))
694                         {
695                             switch (attr)
696                             {
697                                 case DW_AT_name:
698                                     name = form_value.AsCString();
699                                     break;
700                                 case DW_AT_type:
701                                     encoding_uid = form_value;
702                                     break;
703                                 case DW_AT_data_member_location:
704                                     if (form_value.BlockData())
705                                     {
706                                         Value initialValue(0);
707                                         Value memberOffset(0);
708                                         const DWARFDataExtractor &debug_info_data =
709                                             die.GetDWARF()->get_debug_info_data();
710                                         uint32_t block_length = form_value.Unsigned();
711                                         uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
712                                         if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
713                                                                       NULL, // ClangExpressionVariableList *
714                                                                       NULL, // ClangExpressionDeclMap *
715                                                                       NULL, // RegisterContext *
716                                                                       module_sp, debug_info_data, die.GetCU(),
717                                                                       block_offset, block_length, eRegisterKindDWARF,
718                                                                       &initialValue, NULL, memberOffset, NULL))
719                                         {
720                                             member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
721                                         }
722                                     }
723                                     else
724                                     {
725                                         // With DWARF 3 and later, if the value is an integer constant,
726                                         // this form value is the offset in bytes from the beginning
727                                         // of the containing entity.
728                                         member_byte_offset = form_value.Unsigned();
729                                     }
730                                     break;
731
732                                 default:
733                                     break;
734                             }
735                         }
736                     }
737
738                     Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
739                     if (member_type)
740                     {
741                         CompilerType member_go_type = member_type->GetFullCompilerType();
742                         ConstString name_const_str(name);
743                         m_ast.AddFieldToStruct(class_compiler_type, name_const_str, member_go_type, member_byte_offset);
744                     }
745                 }
746                 ++member_idx;
747             }
748             break;
749
750             default:
751                 break;
752         }
753     }
754
755     return count;
756 }
757
758 Function *
759 DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc, const DWARFDIE &die)
760 {
761     DWARFRangeList func_ranges;
762     const char *name = NULL;
763     const char *mangled = NULL;
764     int decl_file = 0;
765     int decl_line = 0;
766     int decl_column = 0;
767     int call_file = 0;
768     int call_line = 0;
769     int call_column = 0;
770     DWARFExpression frame_base(die.GetCU());
771
772     assert(die.Tag() == DW_TAG_subprogram);
773
774     if (die.Tag() != DW_TAG_subprogram)
775         return NULL;
776
777     if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line,
778                                  call_column, &frame_base))
779     {
780         // Union of all ranges in the function DIE (if the function is discontiguous)
781         AddressRange func_range;
782         lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
783         lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
784         if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
785         {
786             ModuleSP module_sp(die.GetModule());
787             func_range.GetBaseAddress().ResolveAddressUsingFileSections(lowest_func_addr, module_sp->GetSectionList());
788             if (func_range.GetBaseAddress().IsValid())
789                 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
790         }
791
792         if (func_range.GetBaseAddress().IsValid())
793         {
794             Mangled func_name;
795             func_name.SetValue(ConstString(name), false);
796
797             FunctionSP func_sp;
798             std::unique_ptr<Declaration> decl_ap;
799             if (decl_file != 0 || decl_line != 0 || decl_column != 0)
800                 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line,
801                                               decl_column));
802
803             SymbolFileDWARF *dwarf = die.GetDWARF();
804             // Supply the type _only_ if it has already been parsed
805             Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
806
807             assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
808
809             if (dwarf->FixupAddress(func_range.GetBaseAddress()))
810             {
811                 const user_id_t func_user_id = die.GetID();
812                 func_sp.reset(new Function(sc.comp_unit,
813                                            func_user_id, // UserID is the DIE offset
814                                            func_user_id,
815                                            func_name,
816                                            func_type,
817                                            func_range)); // first address range
818
819                 if (func_sp.get() != NULL)
820                 {
821                     if (frame_base.IsValid())
822                         func_sp->GetFrameBaseExpression() = frame_base;
823                     sc.comp_unit->AddFunction(func_sp);
824                     return func_sp.get();
825                 }
826             }
827         }
828     }
829     return NULL;
830 }