]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / DWARFASTParserJava.cpp
1 //===-- DWARFASTParserJava.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 "DWARFASTParserJava.h"
11 #include "DWARFAttribute.h"
12 #include "DWARFUnit.h"
13 #include "DWARFDebugInfoEntry.h"
14 #include "DWARFDebugInfoEntry.h"
15 #include "DWARFDeclContext.h"
16 #include "SymbolFileDWARF.h"
17
18 #include "lldb/Core/Module.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/SymbolContextScope.h"
21 #include "lldb/Symbol/TypeList.h"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast) {}
27
28 DWARFASTParserJava::~DWARFASTParserJava() {}
29
30 TypeSP DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die) {
31   SymbolFileDWARF *dwarf = die.GetDWARF();
32   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
33
34   ConstString type_name;
35   uint64_t byte_size = 0;
36
37   DWARFAttributes attributes;
38   const size_t num_attributes = die.GetAttributes(attributes);
39   for (uint32_t i = 0; i < num_attributes; ++i) {
40     DWARFFormValue form_value;
41     dw_attr_t attr = attributes.AttributeAtIndex(i);
42     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
43       switch (attr) {
44       case DW_AT_name:
45         type_name.SetCString(form_value.AsCString());
46         break;
47       case DW_AT_byte_size:
48         byte_size = form_value.Unsigned();
49         break;
50       case DW_AT_encoding:
51         break;
52       default:
53         assert(false && "Unsupported attribute for DW_TAG_base_type");
54       }
55     }
56   }
57
58   Declaration decl;
59   CompilerType compiler_type = m_ast.CreateBaseType(type_name);
60   return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
61                                 nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
62                                 decl, compiler_type, Type::eResolveStateFull);
63 }
64
65 TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) {
66   SymbolFileDWARF *dwarf = die.GetDWARF();
67   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
68
69   ConstString linkage_name;
70   DWARFFormValue type_attr_value;
71   lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
72   DWARFExpression length_expression(die.GetCU());
73
74   DWARFAttributes attributes;
75   const size_t num_attributes = die.GetAttributes(attributes);
76   for (uint32_t i = 0; i < num_attributes; ++i) {
77     DWARFFormValue form_value;
78     dw_attr_t attr = attributes.AttributeAtIndex(i);
79     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
80       switch (attr) {
81       case DW_AT_linkage_name:
82         linkage_name.SetCString(form_value.AsCString());
83         break;
84       case DW_AT_type:
85         type_attr_value = form_value;
86         break;
87       case DW_AT_data_member_location:
88         data_offset = form_value.Unsigned();
89         break;
90       case DW_AT_declaration:
91         break;
92       default:
93         assert(false && "Unsupported attribute for DW_TAG_array_type");
94       }
95     }
96   }
97
98   for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
99        child_die = child_die.GetSibling()) {
100     if (child_die.Tag() == DW_TAG_subrange_type) {
101       DWARFAttributes attributes;
102       const size_t num_attributes = child_die.GetAttributes(attributes);
103       for (uint32_t i = 0; i < num_attributes; ++i) {
104         DWARFFormValue form_value;
105         dw_attr_t attr = attributes.AttributeAtIndex(i);
106         if (attributes.ExtractFormValueAtIndex(i, form_value)) {
107           switch (attr) {
108           case DW_AT_count:
109             if (form_value.BlockData())
110               length_expression.CopyOpcodeData(
111                   form_value.BlockData(), form_value.Unsigned(),
112                   child_die.GetCU()->GetByteOrder(),
113                   child_die.GetCU()->GetAddressByteSize());
114             break;
115           default:
116             assert(false && "Unsupported attribute for DW_TAG_subrange_type");
117           }
118         }
119       }
120     } else {
121       assert(false && "Unsupported child for DW_TAG_array_type");
122     }
123   }
124
125   DIERef type_die_ref(type_attr_value);
126   Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
127   if (!element_type)
128     return nullptr;
129
130   CompilerType element_compiler_type = element_type->GetForwardCompilerType();
131   CompilerType array_compiler_type = m_ast.CreateArrayType(
132       linkage_name, element_compiler_type, length_expression, data_offset);
133
134   Declaration decl;
135   TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(),
136                           -1, nullptr, type_die_ref.GetUID(dwarf),
137                           Type::eEncodingIsUID, &decl, array_compiler_type,
138                           Type::eResolveStateFull));
139   type_sp->SetEncodingType(element_type);
140   return type_sp;
141 }
142
143 TypeSP DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die) {
144   SymbolFileDWARF *dwarf = die.GetDWARF();
145   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
146
147   Declaration decl;
148   DWARFFormValue type_attr_value;
149
150   DWARFAttributes attributes;
151   const size_t num_attributes = die.GetAttributes(attributes);
152   for (uint32_t i = 0; i < num_attributes; ++i) {
153     DWARFFormValue form_value;
154     dw_attr_t attr = attributes.AttributeAtIndex(i);
155     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
156       switch (attr) {
157       case DW_AT_type:
158         type_attr_value = form_value;
159         break;
160       default:
161         assert(false && "Unsupported attribute for DW_TAG_array_type");
162       }
163     }
164   }
165
166   DIERef type_die_ref(type_attr_value);
167   Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
168   if (!pointee_type)
169     return nullptr;
170
171   CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
172   CompilerType reference_compiler_type =
173       m_ast.CreateReferenceType(pointee_compiler_type);
174   TypeSP type_sp(
175       new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1,
176                nullptr, type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
177                reference_compiler_type, Type::eResolveStateFull));
178   type_sp->SetEncodingType(pointee_type);
179   return type_sp;
180 }
181
182 lldb::TypeSP DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die,
183                                                        bool &is_new_type) {
184   SymbolFileDWARF *dwarf = die.GetDWARF();
185   dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
186
187   Declaration decl;
188   ConstString name;
189   ConstString linkage_name;
190   bool is_forward_declaration = false;
191   uint32_t byte_size = 0;
192
193   DWARFAttributes attributes;
194   const size_t num_attributes = die.GetAttributes(attributes);
195   for (uint32_t i = 0; i < num_attributes; ++i) {
196     DWARFFormValue form_value;
197     dw_attr_t attr = attributes.AttributeAtIndex(i);
198     if (attributes.ExtractFormValueAtIndex(i, form_value)) {
199       switch (attr) {
200       case DW_AT_name:
201         name.SetCString(form_value.AsCString());
202         break;
203       case DW_AT_declaration:
204         is_forward_declaration = form_value.Boolean();
205         break;
206       case DW_AT_byte_size:
207         byte_size = form_value.Unsigned();
208         break;
209       case DW_AT_linkage_name:
210         linkage_name.SetCString(form_value.AsCString());
211         break;
212       default:
213         assert(false && "Unsupported attribute for DW_TAG_class_type");
214       }
215     }
216   }
217
218   UniqueDWARFASTType unique_ast_entry;
219   if (name) {
220     std::string qualified_name;
221     if (die.GetQualifiedName(qualified_name)) {
222       name.SetCString(qualified_name.c_str());
223       if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1,
224                                                  unique_ast_entry)) {
225         if (unique_ast_entry.m_type_sp) {
226           dwarf->GetDIEToType()[die.GetDIE()] =
227               unique_ast_entry.m_type_sp.get();
228           is_new_type = false;
229           return unique_ast_entry.m_type_sp;
230         }
231       }
232     }
233   }
234
235   if (is_forward_declaration) {
236     DWARFDeclContext die_decl_ctx;
237     die.GetDWARFDeclContext(die_decl_ctx);
238
239     TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
240     if (type_sp) {
241       // We found a real definition for this type elsewhere so lets use it
242       dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
243       is_new_type = false;
244       return type_sp;
245     }
246   }
247
248   CompilerType compiler_type(
249       &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
250   if (!compiler_type)
251     compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);
252
253   is_new_type = true;
254   TypeSP type_sp(new Type(die.GetID(), dwarf, name,
255                           -1, // byte size isn't specified
256                           nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
257                           &decl, compiler_type, Type::eResolveStateForward));
258
259   // Add our type to the unique type map
260   unique_ast_entry.m_type_sp = type_sp;
261   unique_ast_entry.m_die = die;
262   unique_ast_entry.m_declaration = decl;
263   unique_ast_entry.m_byte_size = -1;
264   dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);
265
266   if (!is_forward_declaration) {
267     // Leave this as a forward declaration until we need to know the details of
268     // the type
269     dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
270         compiler_type.GetOpaqueQualType();
271     dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] =
272         die.GetDIERef();
273   }
274   return type_sp;
275 }
276
277 lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF(
278     const lldb_private::SymbolContext &sc, const DWARFDIE &die,
279     lldb_private::Log *log, bool *type_is_new_ptr) {
280   if (type_is_new_ptr)
281     *type_is_new_ptr = false;
282
283   if (!die)
284     return nullptr;
285
286   SymbolFileDWARF *dwarf = die.GetDWARF();
287
288   Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
289   if (type_ptr == DIE_IS_BEING_PARSED)
290     return nullptr;
291   if (type_ptr != nullptr)
292     return type_ptr->shared_from_this();
293
294   TypeSP type_sp;
295   if (type_is_new_ptr)
296     *type_is_new_ptr = true;
297
298   switch (die.Tag()) {
299   case DW_TAG_base_type: {
300     type_sp = ParseBaseTypeFromDIE(die);
301     break;
302   }
303   case DW_TAG_array_type: {
304     type_sp = ParseArrayTypeFromDIE(die);
305     break;
306   }
307   case DW_TAG_class_type: {
308     bool is_new_type = false;
309     type_sp = ParseClassTypeFromDIE(die, is_new_type);
310     if (!is_new_type)
311       return type_sp;
312     break;
313   }
314   case DW_TAG_reference_type: {
315     type_sp = ParseReferenceTypeFromDIE(die);
316     break;
317   }
318   }
319
320   if (!type_sp)
321     return nullptr;
322
323   DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
324   dw_tag_t sc_parent_tag = sc_parent_die.Tag();
325
326   SymbolContextScope *symbol_context_scope = nullptr;
327   if (sc_parent_tag == DW_TAG_compile_unit ||
328       sc_parent_tag == DW_TAG_partial_unit) {
329     symbol_context_scope = sc.comp_unit;
330   } else if (sc.function != nullptr && sc_parent_die) {
331     symbol_context_scope =
332         sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
333     if (symbol_context_scope == nullptr)
334       symbol_context_scope = sc.function;
335   }
336
337   if (symbol_context_scope != nullptr)
338     type_sp->SetSymbolContextScope(symbol_context_scope);
339
340   dwarf->GetTypeList()->Insert(type_sp);
341   dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
342
343   return type_sp;
344 }
345
346 lldb_private::Function *DWARFASTParserJava::ParseFunctionFromDWARF(
347     const lldb_private::SymbolContext &sc, const DWARFDIE &die) {
348   assert(die.Tag() == DW_TAG_subprogram);
349
350   const char *name = nullptr;
351   const char *mangled = nullptr;
352   int decl_file = 0;
353   int decl_line = 0;
354   int decl_column = 0;
355   int call_file = 0;
356   int call_line = 0;
357   int call_column = 0;
358   DWARFRangeList func_ranges;
359   DWARFExpression frame_base(die.GetCU());
360
361   if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
362                                decl_column, call_file, call_line, call_column,
363                                &frame_base)) {
364     // Union of all ranges in the function DIE (if the function is
365     // discontiguous)
366     AddressRange func_range;
367     lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
368     lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
369     if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
370         lowest_func_addr <= highest_func_addr) {
371       ModuleSP module_sp(die.GetModule());
372       func_range.GetBaseAddress().ResolveAddressUsingFileSections(
373           lowest_func_addr, module_sp->GetSectionList());
374       if (func_range.GetBaseAddress().IsValid())
375         func_range.SetByteSize(highest_func_addr - lowest_func_addr);
376     }
377
378     if (func_range.GetBaseAddress().IsValid()) {
379       std::unique_ptr<Declaration> decl_ap;
380       if (decl_file != 0 || decl_line != 0 || decl_column != 0)
381         decl_ap.reset(new Declaration(
382             sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
383             decl_line, decl_column));
384
385       if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress())) {
386         FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(),
387                                         Mangled(ConstString(name), false),
388                                         nullptr, // No function types in java
389                                         func_range));
390         if (frame_base.IsValid())
391           func_sp->GetFrameBaseExpression() = frame_base;
392         sc.comp_unit->AddFunction(func_sp);
393
394         return func_sp.get();
395       }
396     }
397   }
398   return nullptr;
399 }
400
401 bool DWARFASTParserJava::CompleteTypeFromDWARF(
402     const DWARFDIE &die, lldb_private::Type *type,
403     lldb_private::CompilerType &java_type) {
404   switch (die.Tag()) {
405   case DW_TAG_class_type: {
406     if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0) {
407       if (die.HasChildren())
408         ParseChildMembers(die, java_type);
409       m_ast.CompleteObjectType(java_type);
410       return java_type.IsValid();
411     }
412   } break;
413   default:
414     assert(false && "Not a forward java type declaration!");
415     break;
416   }
417   return false;
418 }
419
420 void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die,
421                                            CompilerType &compiler_type) {
422   DWARFUnit *dwarf_cu = parent_die.GetCU();
423   for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
424        die = die.GetSibling()) {
425     switch (die.Tag()) {
426     case DW_TAG_member: {
427       const char *name = nullptr;
428       DWARFFormValue encoding_uid;
429       uint32_t member_byte_offset = UINT32_MAX;
430       DWARFExpression member_location_expression(dwarf_cu);
431
432       DWARFAttributes attributes;
433       size_t num_attributes = die.GetAttributes(attributes);
434       for (size_t i = 0; i < num_attributes; ++i) {
435         DWARFFormValue form_value;
436         if (attributes.ExtractFormValueAtIndex(i, form_value)) {
437           switch (attributes.AttributeAtIndex(i)) {
438           case DW_AT_name:
439             name = form_value.AsCString();
440             break;
441           case DW_AT_type:
442             encoding_uid = form_value;
443             break;
444           case DW_AT_data_member_location:
445             if (form_value.BlockData())
446               member_location_expression.CopyOpcodeData(
447                   form_value.BlockData(), form_value.Unsigned(),
448                   dwarf_cu->GetByteOrder(), dwarf_cu->GetAddressByteSize());
449             else
450               member_byte_offset = form_value.Unsigned();
451             break;
452           case DW_AT_artificial:
453             static_cast<void>(form_value.Boolean());
454             break;
455           case DW_AT_accessibility:
456             // TODO: Handle when needed
457             break;
458           default:
459             assert(false && "Unhandled attribute for DW_TAG_member");
460             break;
461           }
462         }
463       }
464
465       if (strcmp(name, ".dynamic_type") == 0)
466         m_ast.SetDynamicTypeId(compiler_type, member_location_expression);
467       else {
468         if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)))
469           m_ast.AddMemberToObject(compiler_type, ConstString(name),
470                                   member_type->GetFullCompilerType(),
471                                   member_byte_offset);
472       }
473       break;
474     }
475     case DW_TAG_inheritance: {
476       DWARFFormValue encoding_uid;
477       uint32_t member_byte_offset = UINT32_MAX;
478
479       DWARFAttributes attributes;
480       size_t num_attributes = die.GetAttributes(attributes);
481       for (size_t i = 0; i < num_attributes; ++i) {
482         DWARFFormValue form_value;
483         if (attributes.ExtractFormValueAtIndex(i, form_value)) {
484           switch (attributes.AttributeAtIndex(i)) {
485           case DW_AT_type:
486             encoding_uid = form_value;
487             break;
488           case DW_AT_data_member_location:
489             member_byte_offset = form_value.Unsigned();
490             break;
491           case DW_AT_accessibility:
492             // In java all base class is public so we can ignore this attribute
493             break;
494           default:
495             assert(false && "Unhandled attribute for DW_TAG_member");
496             break;
497           }
498         }
499       }
500       if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid)))
501         m_ast.AddBaseClassToObject(compiler_type,
502                                    base_type->GetFullCompilerType(),
503                                    member_byte_offset);
504       break;
505     }
506     default:
507       break;
508     }
509   }
510 }