File: | tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp |
Warning: | line 379, column 17 Value stored to 'go_kind' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
44 | using namespace lldb; |
45 | using namespace lldb_private; |
46 | DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {} |
47 | |
48 | DWARFASTParserGo::~DWARFASTParserGo() {} |
49 | |
50 | TypeSP 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 | |
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"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 | |
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__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 | |
703 | Function *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 | } |