]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
MFV r323111: 8569 problem with inline functions in abd.h
[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 "DWARFDIE.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"
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) : m_ast(ast) {}
48
49 DWARFASTParserGo::~DWARFASTParserGo() {}
50
51 TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
52     const lldb_private::SymbolContext &sc, const DWARFDIE &die,
53     lldb_private::Log *log, bool *type_is_new_ptr) {
54   TypeSP type_sp;
55
56   if (type_is_new_ptr)
57     *type_is_new_ptr = false;
58
59   if (die) {
60     SymbolFileDWARF *dwarf = die.GetDWARF();
61     if (log) {
62       dwarf->GetObjectFile()->GetModule()->LogMessage(
63           log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = "
64                "'%s')",
65           die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
66     }
67
68     Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
69     TypeList *type_list = dwarf->GetTypeList();
70     if (type_ptr == NULL) {
71       if (type_is_new_ptr)
72         *type_is_new_ptr = true;
73
74       const dw_tag_t tag = die.Tag();
75
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;
82       uint64_t go_kind = 0;
83       Declaration decl;
84
85       Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
86       CompilerType compiler_type;
87       DWARFFormValue form_value;
88
89       dw_attr_t attr;
90
91       switch (tag) {
92       case DW_TAG_base_type:
93       case DW_TAG_pointer_type:
94       case DW_TAG_typedef:
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;
98
99         const size_t num_attributes = die.GetAttributes(attributes);
100         lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
101
102         if (num_attributes > 0) {
103           uint32_t i;
104           for (i = 0; i < num_attributes; ++i) {
105             attr = attributes.AttributeAtIndex(i);
106             if (attributes.ExtractFormValueAtIndex(i, form_value)) {
107               switch (attr) {
108               case DW_AT_name:
109                 type_name_cstr = form_value.AsCString();
110                 if (type_name_cstr)
111                   type_name_const_str.SetCString(type_name_cstr);
112                 break;
113               case DW_AT_byte_size:
114                 byte_size = form_value.Unsigned();
115                 break;
116               case DW_AT_encoding:
117                 // = form_value.Unsigned();
118                 break;
119               case DW_AT_type:
120                 encoding_uid = form_value.Reference();
121                 break;
122               case DW_AT_go_kind:
123                 go_kind = form_value.Unsigned();
124                 break;
125               default:
126                 // Do we care about DW_AT_go_key or DW_AT_go_elem?
127                 break;
128               }
129             }
130           }
131         }
132
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,
135                      encoding_uid);
136
137         switch (tag) {
138         default:
139           break;
140
141         case DW_TAG_unspecified_type:
142           resolve_state = Type::eResolveStateFull;
143           compiler_type = m_ast.CreateVoidType(type_name_const_str);
144           break;
145
146         case DW_TAG_base_type:
147           resolve_state = Type::eResolveStateFull;
148           compiler_type =
149               m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size);
150           break;
151
152         case DW_TAG_pointer_type:
153           encoding_data_type = Type::eEncodingIsPointerUID;
154           break;
155         case DW_TAG_typedef:
156           encoding_data_type = Type::eEncodingIsTypedefUID;
157           CompilerType impl;
158           Type *type = dwarf->ResolveTypeUID(encoding_uid);
159           if (type) {
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();
164             }
165             impl = type->GetForwardCompilerType();
166             compiler_type =
167                 m_ast.CreateTypedefType(go_kind, type_name_const_str, impl);
168           }
169           break;
170         }
171
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,
175                                resolve_state));
176
177         dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
178       } break;
179
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;
184
185         const size_t num_attributes = die.GetAttributes(attributes);
186         if (num_attributes > 0) {
187           uint32_t i;
188           for (i = 0; i < num_attributes; ++i) {
189             attr = attributes.AttributeAtIndex(i);
190             if (attributes.ExtractFormValueAtIndex(i, form_value)) {
191               switch (attr) {
192               case DW_AT_name:
193                 type_name_cstr = form_value.AsCString();
194                 type_name_const_str.SetCString(type_name_cstr);
195                 break;
196
197               case DW_AT_byte_size:
198                 byte_size = form_value.Unsigned();
199                 byte_size_valid = true;
200                 break;
201
202               case DW_AT_go_kind:
203                 go_kind = form_value.Unsigned();
204                 break;
205
206               // TODO: Should we use SLICETYPE's DW_AT_go_elem?
207               default:
208                 break;
209               }
210             }
211           }
212         }
213
214         // TODO(ribrdb): Do we need this?
215
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
219         // different blocks.
220         std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(
221             new UniqueDWARFASTType());
222
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
232           // unit.
233           type_sp = unique_ast_entry_ap->m_type_sp;
234           if (type_sp) {
235             dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
236             return type_sp;
237           }
238         }
239
240         DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
241                      DW_TAG_value_to_name(tag), type_name_cstr);
242
243         bool compiler_type_was_created = false;
244         compiler_type.SetCompilerType(
245             &m_ast,
246             dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
247         if (!compiler_type) {
248           compiler_type_was_created = true;
249           compiler_type =
250               m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
251         }
252
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));
257
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);
267
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()] =
286                 die.GetDIERef();
287             // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
288           }
289         }
290       } break;
291
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;
296
297         bool is_variadic = false;
298         clang::StorageClass storage =
299             clang::SC_None; //, Extern, Static, PrivateExtern
300
301         const size_t num_attributes = die.GetAttributes(attributes);
302         if (num_attributes > 0) {
303           uint32_t i;
304           for (i = 0; i < num_attributes; ++i) {
305             attr = attributes.AttributeAtIndex(i);
306             if (attributes.ExtractFormValueAtIndex(i, form_value)) {
307               switch (attr) {
308               case DW_AT_name:
309                 type_name_cstr = form_value.AsCString();
310                 type_name_const_str.SetCString(type_name_cstr);
311                 break;
312
313               case DW_AT_external:
314                 if (form_value.Unsigned()) {
315                   if (storage == clang::SC_None)
316                     storage = clang::SC_Extern;
317                   else
318                     storage = clang::SC_PrivateExtern;
319                 }
320                 break;
321
322               case DW_AT_high_pc:
323               case DW_AT_low_pc:
324                 break;
325               }
326             }
327           }
328         }
329
330         DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
331                      DW_TAG_value_to_name(tag), type_name_cstr);
332
333         std::vector<CompilerType> function_param_types;
334
335         // Parse the function children for the parameters
336
337         if (die.HasChildren()) {
338           ParseChildParameters(sc, die, is_variadic, function_param_types);
339         }
340
341         // compiler_type will get the function prototype clang type after this
342         // call
343         compiler_type = m_ast.CreateFunctionType(
344             type_name_const_str, function_param_types.data(),
345             function_param_types.size(), is_variadic);
346
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());
351       } break;
352
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;
356
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);
362
363         if (num_attributes > 0) {
364           uint32_t i;
365           for (i = 0; i < num_attributes; ++i) {
366             attr = attributes.AttributeAtIndex(i);
367             if (attributes.ExtractFormValueAtIndex(i, form_value)) {
368               switch (attr) {
369               case DW_AT_name:
370                 type_name_cstr = form_value.AsCString();
371                 type_name_const_str.SetCString(type_name_cstr);
372                 break;
373
374               case DW_AT_type:
375                 type_die_offset = form_value.Reference();
376                 break;
377               case DW_AT_byte_size:
378                 break; // byte_size = form_value.Unsigned(); break;
379               case DW_AT_go_kind:
380                 go_kind = form_value.Unsigned();
381                 break;
382               default:
383                 break;
384               }
385             }
386           }
387
388           DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
389                        DW_TAG_value_to_name(tag), type_name_cstr);
390
391           Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
392
393           if (element_type) {
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",
404                        type_name_cstr);
405               compiler_type = m_ast.CreateArrayType(
406                   type_name_const_str, array_element_type, element_orders[0]);
407             } else {
408               compiler_type = m_ast.CreateArrayType(type_name_const_str,
409                                                     array_element_type, 0);
410             }
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);
416           }
417         }
418       } break;
419
420       default:
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));
426         break;
427       }
428
429       if (type_sp.get()) {
430         DWARFDIE sc_parent_die =
431             SymbolFileDWARF::GetParentSymbolContextDIE(die);
432         dw_tag_t sc_parent_tag = sc_parent_die.Tag();
433
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;
442         }
443
444         if (symbol_context_scope != NULL) {
445           type_sp->SetSymbolContextScope(symbol_context_scope);
446         }
447
448         // We are ready to put this type into the uniqued list up at the module
449         // level
450         type_list->Insert(type_sp);
451
452         dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
453       }
454     } else if (type_ptr != DIE_IS_BEING_PARSED) {
455       type_sp = type_ptr->shared_from_this();
456     }
457   }
458   return type_sp;
459 }
460
461 size_t DWARFASTParserGo::ParseChildParameters(
462     const SymbolContext &sc,
463
464     const DWARFDIE &parent_die, bool &is_variadic,
465     std::vector<CompilerType> &function_param_types) {
466   if (!parent_die)
467     return 0;
468
469   size_t arg_idx = 0;
470   for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
471        die = die.GetSibling()) {
472
473     dw_tag_t tag = die.Tag();
474     switch (tag) {
475     case DW_TAG_formal_parameter: {
476       DWARFAttributes attributes;
477       const size_t num_attributes = die.GetAttributes(attributes);
478       if (num_attributes > 0) {
479         Declaration decl;
480         DWARFFormValue param_type_die_offset;
481
482         uint32_t i;
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)) {
487             switch (attr) {
488             case DW_AT_name:
489               // = form_value.AsCString();
490               break;
491             case DW_AT_type:
492               param_type_die_offset = form_value;
493               break;
494             case DW_AT_location:
495             //                          if (form_value.BlockData())
496             //                          {
497             //                              const DWARFDataExtractor&
498             //                              debug_info_data =
499             //                              debug_info();
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(),
506             //                              block_length);
507             //                          }
508             //                          else
509             //                          {
510             //                          }
511             //                          break;
512             default:
513               break;
514             }
515           }
516         }
517
518         Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
519         if (type) {
520           function_param_types.push_back(type->GetForwardCompilerType());
521         }
522       }
523       arg_idx++;
524     } break;
525
526     case DW_TAG_unspecified_parameters:
527       is_variadic = true;
528       break;
529
530     default:
531       break;
532     }
533   }
534   return arg_idx;
535 }
536
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) {
541   if (!parent_die)
542     return;
543
544   for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
545        die = die.GetSibling()) {
546     const dw_tag_t tag = die.Tag();
547     switch (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;
553         uint32_t i;
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)) {
558             switch (attr) {
559             case DW_AT_count:
560               num_elements = form_value.Unsigned();
561               break;
562
563             default:
564             case DW_AT_type:
565               break;
566             }
567           }
568         }
569
570         element_orders.push_back(num_elements);
571       }
572     } break;
573     }
574   }
575 }
576
577 bool DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die,
578                                              lldb_private::Type *type,
579                                              CompilerType &compiler_type) {
580   if (!die)
581     return false;
582
583   const dw_tag_t tag = die.Tag();
584
585   SymbolFileDWARF *dwarf = die.GetDWARF();
586   Log *log =
587       nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
588   if (log)
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;
594
595   switch (tag) {
596   case DW_TAG_structure_type: {
597     {
598       if (die.HasChildren()) {
599         SymbolContext sc(die.GetLLDBCompileUnit());
600
601         ParseChildMembers(sc, die, compiler_type);
602       }
603     }
604     m_ast.CompleteStructType(compiler_type);
605     return (bool)compiler_type;
606   }
607
608   default:
609     assert(false && "not a forward go type decl!");
610     break;
611   }
612
613   return false;
614 }
615
616 size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
617                                            const DWARFDIE &parent_die,
618                                            CompilerType &class_compiler_type) {
619   size_t count = 0;
620   uint32_t member_idx = 0;
621
622   ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
623   GoASTContext *ast =
624       llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem());
625   if (ast == nullptr)
626     return 0;
627
628   for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
629        die = die.GetSibling()) {
630     dw_tag_t tag = die.Tag();
631
632     switch (tag) {
633     case DW_TAG_member: {
634       DWARFAttributes attributes;
635       const size_t num_attributes = die.GetAttributes(attributes);
636       if (num_attributes > 0) {
637         Declaration decl;
638         const char *name = NULL;
639
640         DWARFFormValue encoding_uid;
641         uint32_t member_byte_offset = UINT32_MAX;
642         uint32_t i;
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)) {
647             switch (attr) {
648             case DW_AT_name:
649               name = form_value.AsCString();
650               break;
651             case DW_AT_type:
652               encoding_uid = form_value;
653               break;
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, // ClangExpressionVariableList *
666                         NULL, // ClangExpressionDeclMap *
667                         NULL, // RegisterContext *
668                         module_sp, debug_info_data, die.GetCU(), block_offset,
669                         block_length, eRegisterKindDWARF, &initialValue, NULL,
670                         memberOffset, NULL)) {
671                   member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
672                 }
673               } else {
674                 // With DWARF 3 and later, if the value is an integer constant,
675                 // this form value is the offset in bytes from the beginning
676                 // of the containing entity.
677                 member_byte_offset = form_value.Unsigned();
678               }
679               break;
680
681             default:
682               break;
683             }
684           }
685         }
686
687         Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
688         if (member_type) {
689           CompilerType member_go_type = member_type->GetFullCompilerType();
690           ConstString name_const_str(name);
691           m_ast.AddFieldToStruct(class_compiler_type, name_const_str,
692                                  member_go_type, member_byte_offset);
693         }
694       }
695       ++member_idx;
696     } break;
697
698     default:
699       break;
700     }
701   }
702
703   return count;
704 }
705
706 Function *DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc,
707                                                    const DWARFDIE &die) {
708   DWARFRangeList func_ranges;
709   const char *name = NULL;
710   const char *mangled = NULL;
711   int decl_file = 0;
712   int decl_line = 0;
713   int decl_column = 0;
714   int call_file = 0;
715   int call_line = 0;
716   int call_column = 0;
717   DWARFExpression frame_base(die.GetCU());
718
719   assert(die.Tag() == DW_TAG_subprogram);
720
721   if (die.Tag() != DW_TAG_subprogram)
722     return NULL;
723
724   if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
725                                decl_column, call_file, call_line, call_column,
726                                &frame_base)) {
727     // Union of all ranges in the function DIE (if the function is
728     // discontiguous)
729     AddressRange func_range;
730     lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
731     lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
732     if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
733         lowest_func_addr <= highest_func_addr) {
734       ModuleSP module_sp(die.GetModule());
735       func_range.GetBaseAddress().ResolveAddressUsingFileSections(
736           lowest_func_addr, module_sp->GetSectionList());
737       if (func_range.GetBaseAddress().IsValid())
738         func_range.SetByteSize(highest_func_addr - lowest_func_addr);
739     }
740
741     if (func_range.GetBaseAddress().IsValid()) {
742       Mangled func_name;
743       func_name.SetValue(ConstString(name), false);
744
745       FunctionSP func_sp;
746       std::unique_ptr<Declaration> decl_ap;
747       if (decl_file != 0 || decl_line != 0 || decl_column != 0)
748         decl_ap.reset(new Declaration(
749             sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
750             decl_line, decl_column));
751
752       SymbolFileDWARF *dwarf = die.GetDWARF();
753       // Supply the type _only_ if it has already been parsed
754       Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
755
756       assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
757
758       if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
759         const user_id_t func_user_id = die.GetID();
760         func_sp.reset(new Function(sc.comp_unit,
761                                    func_user_id, // UserID is the DIE offset
762                                    func_user_id, func_name, func_type,
763                                    func_range)); // first address range
764
765         if (func_sp.get() != NULL) {
766           if (frame_base.IsValid())
767             func_sp->GetFrameBaseExpression() = frame_base;
768           sc.comp_unit->AddFunction(func_sp);
769           return func_sp.get();
770         }
771       }
772     }
773   }
774   return NULL;
775 }