Bug Summary

File:tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
Warning:line 379, column 17
Value stored to 'go_kind' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DWARFASTParserGo.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/SymbolFile/DWARF -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Plugins/SymbolFile/DWARF -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp -faddrsig
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 "DWARFDIE.h"
14#include "DWARFDIECollection.h"
15#include "DWARFDebugInfo.h"
16#include "DWARFDeclContext.h"
17#include "DWARFDefines.h"
18#include "SymbolFileDWARF.h"
19#include "SymbolFileDWARFDebugMap.h"
20#include "UniqueDWARFASTType.h"
21
22#include "clang/Basic/Specifiers.h"
23
24#include "lldb/Core/Module.h"
25#include "lldb/Core/Value.h"
26#include "lldb/Symbol/CompileUnit.h"
27#include "lldb/Symbol/Function.h"
28#include "lldb/Symbol/ObjectFile.h"
29#include "lldb/Symbol/TypeList.h"
30
31//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
32
33#ifdef ENABLE_DEBUG_PRINTF
34#include <stdio.h>
35#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
36#else
37#define DEBUG_PRINTF(fmt, ...)
38#endif
39
40#define DW_AT_go_kind0x2900 0x2900
41#define DW_AT_go_key0x2901 0x2901
42#define DW_AT_go_elem0x2902 0x2902
43
44using namespace lldb;
45using namespace lldb_private;
46DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {}
47
48DWARFASTParserGo::~DWARFASTParserGo() {}
49
50TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
51 const lldb_private::SymbolContext &sc, const DWARFDIE &die,
52 lldb_private::Log *log, bool *type_is_new_ptr) {
53 TypeSP type_sp;
54
55 if (type_is_new_ptr)
56 *type_is_new_ptr = false;
57
58 if (die) {
59 SymbolFileDWARF *dwarf = die.GetDWARF();
60 if (log) {
61 dwarf->GetObjectFile()->GetModule()->LogMessage(
62 log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = "
63 "'%s')",
64 die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
65 }
66
67 Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
68 TypeList *type_list = dwarf->GetTypeList();
69 if (type_ptr == NULL__null) {
70 if (type_is_new_ptr)
71 *type_is_new_ptr = true;
72
73 const dw_tag_t tag = die.Tag();
74
75 bool is_forward_declaration = false;
76 DWARFAttributes attributes;
77 const char *type_name_cstr = NULL__null;
78 ConstString type_name_const_str;
79 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
80 uint64_t byte_size = 0;
81 uint64_t go_kind = 0;
82 Declaration decl;
83
84 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
85 CompilerType compiler_type;
86 DWARFFormValue form_value;
87
88 dw_attr_t attr;
89
90 switch (tag) {
91 case DW_TAG_base_type:
92 case DW_TAG_pointer_type:
93 case DW_TAG_typedef:
94 case DW_TAG_unspecified_type: {
95 // Set a bit that lets us know that we are currently parsing this
96 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED((lldb_private::Type *)1);
97
98 const size_t num_attributes = die.GetAttributes(attributes);
99 lldb::user_id_t encoding_uid = LLDB_INVALID_UID(18446744073709551615UL);
100
101 if (num_attributes > 0) {
102 uint32_t i;
103 for (i = 0; i < num_attributes; ++i) {
104 attr = attributes.AttributeAtIndex(i);
105 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
106 switch (attr) {
107 case DW_AT_name:
108 type_name_cstr = form_value.AsCString();
109 if (type_name_cstr)
110 type_name_const_str.SetCString(type_name_cstr);
111 break;
112 case DW_AT_byte_size:
113 byte_size = form_value.Unsigned();
114 break;
115 case DW_AT_encoding:
116 // = form_value.Unsigned();
117 break;
118 case DW_AT_type:
119 encoding_uid = form_value.Reference();
120 break;
121 case DW_AT_go_kind0x2900:
122 go_kind = form_value.Unsigned();
123 break;
124 default:
125 // Do we care about DW_AT_go_key or DW_AT_go_elem?
126 break;
127 }
128 }
129 }
130 }
131
132 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n",
133 die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr,
134 encoding_uid);
135
136 switch (tag) {
137 default:
138 break;
139
140 case DW_TAG_unspecified_type:
141 resolve_state = Type::eResolveStateFull;
142 compiler_type = m_ast.CreateVoidType(type_name_const_str);
143 break;
144
145 case DW_TAG_base_type:
146 resolve_state = Type::eResolveStateFull;
147 compiler_type =
148 m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size);
149 break;
150
151 case DW_TAG_pointer_type:
152 encoding_data_type = Type::eEncodingIsPointerUID;
153 break;
154 case DW_TAG_typedef:
155 encoding_data_type = Type::eEncodingIsTypedefUID;
156 CompilerType impl;
157 Type *type = dwarf->ResolveTypeUID(encoding_uid);
158 if (type) {
159 if (go_kind == 0 && type->GetName() == type_name_const_str) {
160 // Go emits extra typedefs as a forward declaration. Ignore
161 // 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__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((lldb_private::Type *)1);
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_kind0x2900:
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
217 // the stack, put it on the heap. This function is often called
218 // recursively and clang isn't good and sharing the stack space for
219 // variables in 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 compile unit. GCC
229 // loves to use the "one definition rule" which can result in
230 // multiple definitions of the same class over and over in each
231 // compile unit.
232 type_sp = unique_ast_entry_ap->m_type_sp;
233 if (type_sp) {
234 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
235 return type_sp;
236 }
237 }
238
239 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
240 DW_TAG_value_to_name(tag), type_name_cstr);
241
242 bool compiler_type_was_created = false;
243 compiler_type.SetCompilerType(
244 &m_ast,
245 dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
246 if (!compiler_type) {
247 compiler_type_was_created = true;
248 compiler_type =
249 m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
250 }
251
252 type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
253 byte_size, NULL__null, LLDB_INVALID_UID(18446744073709551615UL),
254 Type::eEncodingIsUID, &decl, compiler_type,
255 Type::eResolveStateForward));
256
257 // Add our type to the unique type map so we don't end up creating many
258 // copies of the same type over and over in the ASTContext for our
259 // module
260 unique_ast_entry_ap->m_type_sp = type_sp;
261 unique_ast_entry_ap->m_die = die;
262 unique_ast_entry_ap->m_declaration = decl;
263 unique_ast_entry_ap->m_byte_size = byte_size;
264 dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str,
265 *unique_ast_entry_ap);
266
267 if (!is_forward_declaration) {
268 // Always start the definition for a class type so that if the class
269 // has child classes or types that require the class to be created
270 // for use as their decl contexts the class will be ready to accept
271 // these child definitions.
272 if (die.HasChildren() == false) {
273 // No children for this struct/union/class, lets finish it
274 m_ast.CompleteStructType(compiler_type);
275 } else if (compiler_type_was_created) {
276 // Leave this as a forward declaration until we need to know the
277 // details of the type. lldb_private::Type will automatically call
278 // the SymbolFile virtual function
279 // "SymbolFileDWARF::CompleteType(Type *)" When the definition
280 // needs to be defined.
281 dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] =
282 compiler_type.GetOpaqueQualType();
283 dwarf->m_forward_decl_clang_type_to_die[compiler_type
284 .GetOpaqueQualType()] =
285 die.GetDIERef();
286 // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
287 }
288 }
289 } break;
290
291 case DW_TAG_subprogram:
292 case DW_TAG_subroutine_type: {
293 // Set a bit that lets us know that we are currently parsing this
294 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED((lldb_private::Type *)1);
295
296 bool is_variadic = false;
297 clang::StorageClass storage =
298 clang::SC_None; //, Extern, Static, PrivateExtern
299
300 const size_t num_attributes = die.GetAttributes(attributes);
301 if (num_attributes > 0) {
302 uint32_t i;
303 for (i = 0; i < num_attributes; ++i) {
304 attr = attributes.AttributeAtIndex(i);
305 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
306 switch (attr) {
307 case DW_AT_name:
308 type_name_cstr = form_value.AsCString();
309 type_name_const_str.SetCString(type_name_cstr);
310 break;
311
312 case DW_AT_external:
313 if (form_value.Unsigned()) {
314 if (storage == clang::SC_None)
315 storage = clang::SC_Extern;
316 else
317 storage = clang::SC_PrivateExtern;
318 }
319 break;
320
321 case DW_AT_high_pc:
322 case DW_AT_low_pc:
323 break;
324 }
325 }
326 }
327 }
328
329 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
330 DW_TAG_value_to_name(tag), type_name_cstr);
331
332 std::vector<CompilerType> function_param_types;
333
334 // Parse the function children for the parameters
335
336 if (die.HasChildren()) {
337 ParseChildParameters(sc, die, is_variadic, function_param_types);
338 }
339
340 // compiler_type will get the function prototype clang type after this
341 // call
342 compiler_type = m_ast.CreateFunctionType(
343 type_name_const_str, function_param_types.data(),
344 function_param_types.size(), is_variadic);
345
346 type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL__null,
347 LLDB_INVALID_UID(18446744073709551615UL), Type::eEncodingIsUID, &decl,
348 compiler_type, Type::eResolveStateFull));
349 assert(type_sp.get())((type_sp.get()) ? static_cast<void> (0) : __assert_fail
("type_sp.get()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 349, __PRETTY_FUNCTION__))
;
350 } break;
351
352 case DW_TAG_array_type: {
353 // Set a bit that lets us know that we are currently parsing this
354 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED((lldb_private::Type *)1);
355
356 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET(~(dw_offset_t)0);
357 int64_t first_index = 0;
358 uint32_t byte_stride = 0;
359 uint32_t bit_stride = 0;
360 const size_t num_attributes = die.GetAttributes(attributes);
361
362 if (num_attributes > 0) {
363 uint32_t i;
364 for (i = 0; i < num_attributes; ++i) {
365 attr = attributes.AttributeAtIndex(i);
366 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
367 switch (attr) {
368 case DW_AT_name:
369 type_name_cstr = form_value.AsCString();
370 type_name_const_str.SetCString(type_name_cstr);
371 break;
372
373 case DW_AT_type:
374 type_die_offset = form_value.Reference();
375 break;
376 case DW_AT_byte_size:
377 break; // byte_size = form_value.Unsigned(); break;
378 case DW_AT_go_kind0x2900:
379 go_kind = form_value.Unsigned();
Value stored to 'go_kind' is never read
380 break;
381 default:
382 break;
383 }
384 }
385 }
386
387 DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
388 DW_TAG_value_to_name(tag), type_name_cstr);
389
390 Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
391
392 if (element_type) {
393 std::vector<uint64_t> element_orders;
394 ParseChildArrayInfo(sc, die, first_index, element_orders,
395 byte_stride, bit_stride);
396 if (byte_stride == 0)
397 byte_stride = element_type->GetByteSize();
398 CompilerType array_element_type =
399 element_type->GetForwardCompilerType();
400 if (element_orders.size() > 0) {
401 if (element_orders.size() > 1)
402 printf("golang: unsupported multi-dimensional array %s\n",
403 type_name_cstr);
404 compiler_type = m_ast.CreateArrayType(
405 type_name_const_str, array_element_type, element_orders[0]);
406 } else {
407 compiler_type = m_ast.CreateArrayType(type_name_const_str,
408 array_element_type, 0);
409 }
410 type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
411 byte_stride, NULL__null, type_die_offset,
412 Type::eEncodingIsUID, &decl, compiler_type,
413 Type::eResolveStateFull));
414 type_sp->SetEncodingType(element_type);
415 }
416 }
417 } break;
418
419 default:
420 dwarf->GetObjectFile()->GetModule()->ReportError(
421 "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), "
422 "please file a bug and attach the file at the "
423 "start of this error message",
424 die.GetOffset(), tag, DW_TAG_value_to_name(tag));
425 break;
426 }
427
428 if (type_sp.get()) {
429 DWARFDIE sc_parent_die =
430 SymbolFileDWARF::GetParentSymbolContextDIE(die);
431 dw_tag_t sc_parent_tag = sc_parent_die.Tag();
432
433 SymbolContextScope *symbol_context_scope = NULL__null;
434 if (sc_parent_tag == DW_TAG_compile_unit ||
435 sc_parent_tag == DW_TAG_partial_unit) {
436 symbol_context_scope = sc.comp_unit;
437 } else if (sc.function != NULL__null && sc_parent_die) {
438 symbol_context_scope =
439 sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
440 if (symbol_context_scope == NULL__null)
441 symbol_context_scope = sc.function;
442 }
443
444 if (symbol_context_scope != NULL__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((lldb_private::Type *)1)) {
455 type_sp = type_ptr->shared_from_this();
456 }
457 }
458 return type_sp;
459}
460
461size_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
537void 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
577bool 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"l" "x" ": %s '%s' resolving forward declaration...",
591 die.GetID(), DW_TAG_value_to_name(tag), type->GetName().AsCString());
592 assert(compiler_type)((compiler_type) ? static_cast<void> (0) : __assert_fail
("compiler_type", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 592, __PRETTY_FUNCTION__))
;
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!")((false && "not a forward go type decl!") ? static_cast
<void> (0) : __assert_fail ("false && \"not a forward go type decl!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 609, __PRETTY_FUNCTION__))
;
610 break;
611 }
612
613 return false;
614}
615
616size_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__null;
639
640 DWARFFormValue encoding_uid;
641 uint32_t member_byte_offset = UINT32_MAX(4294967295U);
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 = die.GetData();
659 uint32_t block_length = form_value.Unsigned();
660 uint32_t block_offset =
661 form_value.BlockData() - debug_info_data.GetDataStart();
662 if (DWARFExpression::Evaluate(
663 NULL__null, // ExecutionContext *
664 NULL__null, // RegisterContext *
665 module_sp, debug_info_data, die.GetCU(), block_offset,
666 block_length, eRegisterKindDWARF, &initialValue, NULL__null,
667 memberOffset, NULL__null)) {
668 member_byte_offset = memberOffset.ResolveValue(NULL__null).UInt();
669 }
670 } else {
671 // With DWARF 3 and later, if the value is an integer constant,
672 // this form value is the offset in bytes from the beginning of
673 // the containing entity.
674 member_byte_offset = form_value.Unsigned();
675 }
676 break;
677
678 default:
679 break;
680 }
681 }
682 }
683
684 Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
685 if (member_type) {
686 CompilerType member_go_type = member_type->GetFullCompilerType();
687 ConstString name_const_str(name);
688 m_ast.AddFieldToStruct(class_compiler_type, name_const_str,
689 member_go_type, member_byte_offset);
690 }
691 }
692 ++member_idx;
693 } break;
694
695 default:
696 break;
697 }
698 }
699
700 return count;
701}
702
703Function *DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc,
704 const DWARFDIE &die) {
705 DWARFRangeList func_ranges;
706 const char *name = NULL__null;
707 const char *mangled = NULL__null;
708 int decl_file = 0;
709 int decl_line = 0;
710 int decl_column = 0;
711 int call_file = 0;
712 int call_line = 0;
713 int call_column = 0;
714 DWARFExpression frame_base(die.GetCU());
715
716 assert(die.Tag() == DW_TAG_subprogram)((die.Tag() == DW_TAG_subprogram) ? static_cast<void> (
0) : __assert_fail ("die.Tag() == DW_TAG_subprogram", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 716, __PRETTY_FUNCTION__))
;
717
718 if (die.Tag() != DW_TAG_subprogram)
719 return NULL__null;
720
721 if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
722 decl_column, call_file, call_line, call_column,
723 &frame_base)) {
724 // Union of all ranges in the function DIE (if the function is
725 // discontiguous)
726 AddressRange func_range;
727 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
728 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
729 if (lowest_func_addr != LLDB_INVALID_ADDRESS(18446744073709551615UL) &&
730 lowest_func_addr <= highest_func_addr) {
731 ModuleSP module_sp(die.GetModule());
732 func_range.GetBaseAddress().ResolveAddressUsingFileSections(
733 lowest_func_addr, module_sp->GetSectionList());
734 if (func_range.GetBaseAddress().IsValid())
735 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
736 }
737
738 if (func_range.GetBaseAddress().IsValid()) {
739 Mangled func_name;
740 func_name.SetValue(ConstString(name), false);
741
742 FunctionSP func_sp;
743 std::unique_ptr<Declaration> decl_ap;
744 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
745 decl_ap.reset(new Declaration(
746 sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
747 decl_line, decl_column));
748
749 SymbolFileDWARF *dwarf = die.GetDWARF();
750 // Supply the type _only_ if it has already been parsed
751 Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
752
753 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED)((func_type == __null || func_type != ((lldb_private::Type *)
1)) ? static_cast<void> (0) : __assert_fail ("func_type == NULL || func_type != DIE_IS_BEING_PARSED"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 753, __PRETTY_FUNCTION__))
;
754
755 if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
756 const user_id_t func_user_id = die.GetID();
757 func_sp.reset(new Function(sc.comp_unit,
758 func_user_id, // UserID is the DIE offset
759 func_user_id, func_name, func_type,
760 func_range)); // first address range
761
762 if (func_sp.get() != NULL__null) {
763 if (frame_base.IsValid())
764 func_sp->GetFrameBaseExpression() = frame_base;
765 sc.comp_unit->AddFunction(func_sp);
766 return func_sp.get();
767 }
768 }
769 }
770 }
771 return NULL__null;
772}