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-eagerly-assume -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-7/lib/clang/7.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D LLDB_USE_BUILTIN_DEMANGLER -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/source/Plugins/SymbolFile/DWARF -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/SymbolFile/DWARF -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.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-7~svn329677/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-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c++ /build/llvm-toolchain-snapshot-7~svn329677/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 "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 these.
161 dwarf->m_die_to_type[die.GetDIE()] = type;
162 return type->shared_from_this();
163 }
164 impl = type->GetForwardCompilerType();
165 compiler_type =
166 m_ast.CreateTypedefType(go_kind, type_name_const_str, impl);
167 }
168 break;
169 }
170
171 type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
172 byte_size, NULL__null, encoding_uid,
173 encoding_data_type, &decl, compiler_type,
174 resolve_state));
175
176 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
177 } break;
178
179 case DW_TAG_structure_type: {
180 // Set a bit that lets us know that we are currently parsing this
181 dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED((lldb_private::Type *)1);
182 bool byte_size_valid = false;
183
184 const size_t num_attributes = die.GetAttributes(attributes);
185 if (num_attributes > 0) {
186 uint32_t i;
187 for (i = 0; i < num_attributes; ++i) {
188 attr = attributes.AttributeAtIndex(i);
189 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
190 switch (attr) {
191 case DW_AT_name:
192 type_name_cstr = form_value.AsCString();
193 type_name_const_str.SetCString(type_name_cstr);
194 break;
195
196 case DW_AT_byte_size:
197 byte_size = form_value.Unsigned();
198 byte_size_valid = true;
199 break;
200
201 case DW_AT_go_kind0x2900:
202 go_kind = form_value.Unsigned();
203 break;
204
205 // TODO: Should we use SLICETYPE's DW_AT_go_elem?
206 default:
207 break;
208 }
209 }
210 }
211 }
212
213 // TODO(ribrdb): Do we need this?
214
215 // UniqueDWARFASTType is large, so don't create a local variables on the
216 // stack, put it on the heap. This function is often called recursively
217 // and clang isn't good and sharing the stack space for variables in
218 // different blocks.
219 std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(
220 new UniqueDWARFASTType());
221
222 // Only try and unique the type if it has a name.
223 if (type_name_const_str &&
224 dwarf->GetUniqueDWARFASTTypeMap().Find(
225 type_name_const_str, die, decl,
226 byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
227 // We have already parsed this type or from another
228 // compile unit. GCC loves to use the "one definition
229 // rule" which can result in multiple definitions
230 // of the same class over and over in each compile
231 // 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
258 // end up creating many copies of the same type over
259 // and over in the ASTContext for our 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
269 // if the class has child classes or types that require
270 // the class to be created for use as their decl contexts
271 // the class will be ready to accept 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
277 // to know the details of the type. lldb_private::Type
278 // will automatically call the SymbolFile virtual function
279 // "SymbolFileDWARF::CompleteType(Type *)"
280 // When the definition 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())(static_cast <bool> (type_sp.get()) ? void (0) : __assert_fail
("type_sp.get()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 349, __extension__ __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 symbol_context_scope = sc.comp_unit;
436 } else if (sc.function != NULL__null && sc_parent_die) {
437 symbol_context_scope =
438 sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
439 if (symbol_context_scope == NULL__null)
440 symbol_context_scope = sc.function;
441 }
442
443 if (symbol_context_scope != NULL__null) {
444 type_sp->SetSymbolContextScope(symbol_context_scope);
445 }
446
447 // We are ready to put this type into the uniqued list up at the module
448 // level
449 type_list->Insert(type_sp);
450
451 dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
452 }
453 } else if (type_ptr != DIE_IS_BEING_PARSED((lldb_private::Type *)1)) {
454 type_sp = type_ptr->shared_from_this();
455 }
456 }
457 return type_sp;
458}
459
460size_t DWARFASTParserGo::ParseChildParameters(
461 const SymbolContext &sc,
462
463 const DWARFDIE &parent_die, bool &is_variadic,
464 std::vector<CompilerType> &function_param_types) {
465 if (!parent_die)
466 return 0;
467
468 size_t arg_idx = 0;
469 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
470 die = die.GetSibling()) {
471
472 dw_tag_t tag = die.Tag();
473 switch (tag) {
474 case DW_TAG_formal_parameter: {
475 DWARFAttributes attributes;
476 const size_t num_attributes = die.GetAttributes(attributes);
477 if (num_attributes > 0) {
478 Declaration decl;
479 DWARFFormValue param_type_die_offset;
480
481 uint32_t i;
482 for (i = 0; i < num_attributes; ++i) {
483 const dw_attr_t attr = attributes.AttributeAtIndex(i);
484 DWARFFormValue form_value;
485 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
486 switch (attr) {
487 case DW_AT_name:
488 // = form_value.AsCString();
489 break;
490 case DW_AT_type:
491 param_type_die_offset = form_value;
492 break;
493 case DW_AT_location:
494 // if (form_value.BlockData())
495 // {
496 // const DWARFDataExtractor&
497 // debug_info_data =
498 // debug_info();
499 // uint32_t block_length =
500 // form_value.Unsigned();
501 // DWARFDataExtractor
502 // location(debug_info_data,
503 // form_value.BlockData() -
504 // debug_info_data.GetDataStart(),
505 // block_length);
506 // }
507 // else
508 // {
509 // }
510 // break;
511 default:
512 break;
513 }
514 }
515 }
516
517 Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
518 if (type) {
519 function_param_types.push_back(type->GetForwardCompilerType());
520 }
521 }
522 arg_idx++;
523 } break;
524
525 case DW_TAG_unspecified_parameters:
526 is_variadic = true;
527 break;
528
529 default:
530 break;
531 }
532 }
533 return arg_idx;
534}
535
536void DWARFASTParserGo::ParseChildArrayInfo(
537 const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
538 std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
539 uint32_t &bit_stride) {
540 if (!parent_die)
541 return;
542
543 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
544 die = die.GetSibling()) {
545 const dw_tag_t tag = die.Tag();
546 switch (tag) {
547 case DW_TAG_subrange_type: {
548 DWARFAttributes attributes;
549 const size_t num_child_attributes = die.GetAttributes(attributes);
550 if (num_child_attributes > 0) {
551 uint64_t num_elements = 0;
552 uint32_t i;
553 for (i = 0; i < num_child_attributes; ++i) {
554 const dw_attr_t attr = attributes.AttributeAtIndex(i);
555 DWARFFormValue form_value;
556 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
557 switch (attr) {
558 case DW_AT_count:
559 num_elements = form_value.Unsigned();
560 break;
561
562 default:
563 case DW_AT_type:
564 break;
565 }
566 }
567 }
568
569 element_orders.push_back(num_elements);
570 }
571 } break;
572 }
573 }
574}
575
576bool DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die,
577 lldb_private::Type *type,
578 CompilerType &compiler_type) {
579 if (!die)
580 return false;
581
582 const dw_tag_t tag = die.Tag();
583
584 SymbolFileDWARF *dwarf = die.GetDWARF();
585 Log *log =
586 nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
587 if (log)
588 dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
589 log, "0x%8.8" PRIx64"l" "x" ": %s '%s' resolving forward declaration...",
590 die.GetID(), DW_TAG_value_to_name(tag), type->GetName().AsCString());
591 assert(compiler_type)(static_cast <bool> (compiler_type) ? void (0) : __assert_fail
("compiler_type", "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 591, __extension__ __PRETTY_FUNCTION__))
;
592 DWARFAttributes attributes;
593
594 switch (tag) {
595 case DW_TAG_structure_type: {
596 {
597 if (die.HasChildren()) {
598 SymbolContext sc(die.GetLLDBCompileUnit());
599
600 ParseChildMembers(sc, die, compiler_type);
601 }
602 }
603 m_ast.CompleteStructType(compiler_type);
604 return (bool)compiler_type;
605 }
606
607 default:
608 assert(false && "not a forward go type decl!")(static_cast <bool> (false && "not a forward go type decl!"
) ? void (0) : __assert_fail ("false && \"not a forward go type decl!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 608, __extension__ __PRETTY_FUNCTION__))
;
609 break;
610 }
611
612 return false;
613}
614
615size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
616 const DWARFDIE &parent_die,
617 CompilerType &class_compiler_type) {
618 size_t count = 0;
619 uint32_t member_idx = 0;
620
621 ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
622 GoASTContext *ast =
623 llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem());
624 if (ast == nullptr)
625 return 0;
626
627 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
628 die = die.GetSibling()) {
629 dw_tag_t tag = die.Tag();
630
631 switch (tag) {
632 case DW_TAG_member: {
633 DWARFAttributes attributes;
634 const size_t num_attributes = die.GetAttributes(attributes);
635 if (num_attributes > 0) {
636 Declaration decl;
637 const char *name = NULL__null;
638
639 DWARFFormValue encoding_uid;
640 uint32_t member_byte_offset = UINT32_MAX(4294967295U);
641 uint32_t i;
642 for (i = 0; i < num_attributes; ++i) {
643 const dw_attr_t attr = attributes.AttributeAtIndex(i);
644 DWARFFormValue form_value;
645 if (attributes.ExtractFormValueAtIndex(i, form_value)) {
646 switch (attr) {
647 case DW_AT_name:
648 name = form_value.AsCString();
649 break;
650 case DW_AT_type:
651 encoding_uid = form_value;
652 break;
653 case DW_AT_data_member_location:
654 if (form_value.BlockData()) {
655 Value initialValue(0);
656 Value memberOffset(0);
657 const DWARFDataExtractor &debug_info_data =
658 die.GetDWARF()->get_debug_info_data();
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
673 // of 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)(static_cast <bool> (die.Tag() == DW_TAG_subprogram) ? void
(0) : __assert_fail ("die.Tag() == DW_TAG_subprogram", "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 716, __extension__ __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)(static_cast <bool> (func_type == __null || func_type !=
((lldb_private::Type *)1)) ? void (0) : __assert_fail ("func_type == NULL || func_type != DIE_IS_BEING_PARSED"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp"
, 753, __extension__ __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}