blob: 8fbe50bd7cc8c879a27f54b364eb812709cc7ec3 [file] [log] [blame]
Greg Clayton261ac3f2015-08-28 01:01:03 +00001//===-- DWARFASTParserClang.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 "DWARFASTParserClang.h"
11#include "DWARFCompileUnit.h"
12#include "DWARFDebugInfo.h"
13#include "DWARFDeclContext.h"
14#include "DWARFDefines.h"
15#include "DWARFDIE.h"
16#include "DWARFDIECollection.h"
17#include "SymbolFileDWARF.h"
18#include "SymbolFileDWARFDebugMap.h"
19#include "UniqueDWARFASTType.h"
20
Jim Inghamaa816b82015-09-02 01:59:14 +000021#include "lldb/Interpreter/Args.h"
Greg Clayton261ac3f2015-08-28 01:01:03 +000022#include "lldb/Core/Log.h"
23#include "lldb/Core/Module.h"
Jim Inghamaa816b82015-09-02 01:59:14 +000024#include "lldb/Core/StreamString.h"
25#include "lldb/Core/Value.h"
26#include "lldb/Host/Host.h"
Greg Clayton261ac3f2015-08-28 01:01:03 +000027#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
28#include "lldb/Symbol/CompileUnit.h"
29#include "lldb/Symbol/Function.h"
30#include "lldb/Symbol/ObjectFile.h"
31#include "lldb/Symbol/TypeList.h"
Jim Ingham0e0984e2015-09-02 01:06:46 +000032#include "lldb/Target/Language.h"
Jim Inghamaa816b82015-09-02 01:59:14 +000033#include "Plugins/Language/ObjC/ObjCLanguage.h"
Greg Clayton261ac3f2015-08-28 01:01:03 +000034
35#include "clang/AST/DeclCXX.h"
36#include "clang/AST/DeclObjC.h"
37
Paul Hermanea188fc2015-09-16 18:48:30 +000038#include <map>
39#include <vector>
40
Greg Clayton261ac3f2015-08-28 01:01:03 +000041//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
42
43#ifdef ENABLE_DEBUG_PRINTF
44#include <stdio.h>
45#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
46#else
47#define DEBUG_PRINTF(fmt, ...)
48#endif
49
50
51using namespace lldb;
52using namespace lldb_private;
53DWARFASTParserClang::DWARFASTParserClang (ClangASTContext &ast) :
54 m_ast (ast),
55 m_die_to_decl_ctx (),
56 m_decl_ctx_to_die ()
57{
58}
59
60DWARFASTParserClang::~DWARFASTParserClang ()
61{
62}
63
64
65static AccessType
66DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
67{
68 switch (dwarf_accessibility)
69 {
70 case DW_ACCESS_public: return eAccessPublic;
71 case DW_ACCESS_private: return eAccessPrivate;
72 case DW_ACCESS_protected: return eAccessProtected;
73 default: break;
74 }
75 return eAccessNone;
76}
77
78static bool
79DeclKindIsCXXClass (clang::Decl::Kind decl_kind)
80{
81 switch (decl_kind)
82 {
83 case clang::Decl::CXXRecord:
84 case clang::Decl::ClassTemplateSpecialization:
85 return true;
86 default:
87 break;
88 }
89 return false;
90}
91
92struct BitfieldInfo
93{
94 uint64_t bit_size;
95 uint64_t bit_offset;
96
97 BitfieldInfo () :
98 bit_size (LLDB_INVALID_ADDRESS),
99 bit_offset (LLDB_INVALID_ADDRESS)
100 {
101 }
102
103 void
104 Clear()
105 {
106 bit_size = LLDB_INVALID_ADDRESS;
107 bit_offset = LLDB_INVALID_ADDRESS;
108 }
109
110 bool IsValid ()
111 {
112 return (bit_size != LLDB_INVALID_ADDRESS) &&
113 (bit_offset != LLDB_INVALID_ADDRESS);
114 }
115};
116
Greg Clayton261ac3f2015-08-28 01:01:03 +0000117TypeSP
118DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
119 const DWARFDIE &die,
120 Log *log,
121 bool *type_is_new_ptr)
122{
123 TypeSP type_sp;
124
125 if (type_is_new_ptr)
126 *type_is_new_ptr = false;
127
128 AccessType accessibility = eAccessNone;
129 if (die)
130 {
131 SymbolFileDWARF *dwarf = die.GetDWARF();
132 if (log)
133 {
134 DWARFDIE context_die;
135 clang::DeclContext *context = GetClangDeclContextContainingDIE (die, &context_die);
136
137 dwarf->GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
138 die.GetOffset(),
139 static_cast<void*>(context),
140 context_die.GetOffset(),
141 die.GetTagAsCString(),
142 die.GetName());
143
144 }
145 //
146 // Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
147 // if (log && dwarf_cu)
148 // {
149 // StreamString s;
150 // die->DumpLocation (this, dwarf_cu, s);
151 // dwarf->GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
152 //
153 // }
154
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000155 Type *type_ptr = dwarf->GetDIEToType().lookup (die.GetDIE());
Greg Clayton261ac3f2015-08-28 01:01:03 +0000156 TypeList* type_list = dwarf->GetTypeList();
157 if (type_ptr == NULL)
158 {
159 if (type_is_new_ptr)
160 *type_is_new_ptr = true;
161
162 const dw_tag_t tag = die.Tag();
163
164 bool is_forward_declaration = false;
165 DWARFAttributes attributes;
166 const char *type_name_cstr = NULL;
167 ConstString type_name_const_str;
168 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
169 uint64_t byte_size = 0;
170 Declaration decl;
171
172 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
173 CompilerType clang_type;
174 DWARFFormValue form_value;
175
176 dw_attr_t attr;
177
178 switch (tag)
179 {
180 case DW_TAG_base_type:
181 case DW_TAG_pointer_type:
182 case DW_TAG_reference_type:
183 case DW_TAG_rvalue_reference_type:
184 case DW_TAG_typedef:
185 case DW_TAG_const_type:
186 case DW_TAG_restrict_type:
187 case DW_TAG_volatile_type:
188 case DW_TAG_unspecified_type:
189 {
190 // Set a bit that lets us know that we are currently parsing this
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000191 dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000192
193 const size_t num_attributes = die.GetAttributes (attributes);
194 uint32_t encoding = 0;
195 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
196
197 if (num_attributes > 0)
198 {
199 uint32_t i;
200 for (i=0; i<num_attributes; ++i)
201 {
202 attr = attributes.AttributeAtIndex(i);
203 if (attributes.ExtractFormValueAtIndex(i, form_value))
204 {
205 switch (attr)
206 {
207 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
208 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
209 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
210 case DW_AT_name:
211
212 type_name_cstr = form_value.AsCString();
213 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
214 // include the "&"...
215 if (tag == DW_TAG_reference_type)
216 {
217 if (strchr (type_name_cstr, '&') == NULL)
218 type_name_cstr = NULL;
219 }
220 if (type_name_cstr)
221 type_name_const_str.SetCString(type_name_cstr);
222 break;
223 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
224 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000225 case DW_AT_type: encoding_uid = DIERef(form_value).GetUID(); break;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000226 default:
227 case DW_AT_sibling:
228 break;
229 }
230 }
231 }
232 }
233
234 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
235
236 switch (tag)
237 {
238 default:
239 break;
240
241 case DW_TAG_unspecified_type:
242 if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
243 strcmp(type_name_cstr, "decltype(nullptr)") == 0 )
244 {
245 resolve_state = Type::eResolveStateFull;
246 clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
247 break;
248 }
249 // Fall through to base type below in case we can handle the type there...
250
251 case DW_TAG_base_type:
252 resolve_state = Type::eResolveStateFull;
253 clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
254 encoding,
255 byte_size * 8);
256 break;
257
258 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
259 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
260 case DW_TAG_rvalue_reference_type: encoding_data_type = Type::eEncodingIsRValueReferenceUID; break;
261 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
262 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
263 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
264 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
265 }
266
267 if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
268 {
269 bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
270
271 if (translation_unit_is_objc)
272 {
273 if (type_name_cstr != NULL)
274 {
275 static ConstString g_objc_type_name_id("id");
276 static ConstString g_objc_type_name_Class("Class");
277 static ConstString g_objc_type_name_selector("SEL");
278
279 if (type_name_const_str == g_objc_type_name_id)
280 {
281 if (log)
282 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
283 "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
284 die.GetOffset(),
285 die.GetTagAsCString(),
286 die.GetName());
287 clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
288 encoding_data_type = Type::eEncodingIsUID;
289 encoding_uid = LLDB_INVALID_UID;
290 resolve_state = Type::eResolveStateFull;
291
292 }
293 else if (type_name_const_str == g_objc_type_name_Class)
294 {
295 if (log)
296 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
297 "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
298 die.GetOffset(),
299 die.GetTagAsCString(),
300 die.GetName());
301 clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
302 encoding_data_type = Type::eEncodingIsUID;
303 encoding_uid = LLDB_INVALID_UID;
304 resolve_state = Type::eResolveStateFull;
305 }
306 else if (type_name_const_str == g_objc_type_name_selector)
307 {
308 if (log)
309 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
310 "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
311 die.GetOffset(),
312 die.GetTagAsCString(),
313 die.GetName());
314 clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
315 encoding_data_type = Type::eEncodingIsUID;
316 encoding_uid = LLDB_INVALID_UID;
317 resolve_state = Type::eResolveStateFull;
318 }
319 }
320 else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
321 {
322 // Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id".
323
324 const DWARFDIE encoding_die = die.GetDIE(encoding_uid);
325
326 if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type)
327 {
328 if (const char *struct_name = encoding_die.GetName())
329 {
330 if (!strcmp(struct_name, "objc_object"))
331 {
332 if (log)
333 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
334 "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.",
335 die.GetOffset(),
336 die.GetTagAsCString(),
337 die.GetName());
338 clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
339 encoding_data_type = Type::eEncodingIsUID;
340 encoding_uid = LLDB_INVALID_UID;
341 resolve_state = Type::eResolveStateFull;
342 }
343 }
344 }
345 }
346 }
347 }
348
349 type_sp.reset( new Type (die.GetID(),
350 dwarf,
351 type_name_const_str,
352 byte_size,
353 NULL,
354 encoding_uid,
355 encoding_data_type,
356 &decl,
357 clang_type,
358 resolve_state));
359
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000360 dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
Greg Clayton261ac3f2015-08-28 01:01:03 +0000361
362 // Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
363 // if (encoding_type != NULL)
364 // {
365 // if (encoding_type != DIE_IS_BEING_PARSED)
366 // type_sp->SetEncodingType(encoding_type);
367 // else
368 // m_indirect_fixups.push_back(type_sp.get());
369 // }
370 }
371 break;
372
373 case DW_TAG_structure_type:
374 case DW_TAG_union_type:
375 case DW_TAG_class_type:
376 {
377 // Set a bit that lets us know that we are currently parsing this
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000378 dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000379 bool byte_size_valid = false;
380
381 LanguageType class_language = eLanguageTypeUnknown;
382 bool is_complete_objc_class = false;
383 //bool struct_is_class = false;
384 const size_t num_attributes = die.GetAttributes (attributes);
385 if (num_attributes > 0)
386 {
387 uint32_t i;
388 for (i=0; i<num_attributes; ++i)
389 {
390 attr = attributes.AttributeAtIndex(i);
391 if (attributes.ExtractFormValueAtIndex(i, form_value))
392 {
393 switch (attr)
394 {
395 case DW_AT_decl_file:
396 if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid())
397 {
398 // llvm-gcc outputs invalid DW_AT_decl_file attributes that always
399 // point to the compile unit file, so we clear this invalid value
400 // so that we can still unique types efficiently.
401 decl.SetFile(FileSpec ("<invalid>", false));
402 }
403 else
404 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
405 break;
406
407 case DW_AT_decl_line:
408 decl.SetLine(form_value.Unsigned());
409 break;
410
411 case DW_AT_decl_column:
412 decl.SetColumn(form_value.Unsigned());
413 break;
414
415 case DW_AT_name:
416 type_name_cstr = form_value.AsCString();
417 type_name_const_str.SetCString(type_name_cstr);
418 break;
419
420 case DW_AT_byte_size:
421 byte_size = form_value.Unsigned();
422 byte_size_valid = true;
423 break;
424
425 case DW_AT_accessibility:
426 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
427 break;
428
429 case DW_AT_declaration:
430 is_forward_declaration = form_value.Boolean();
431 break;
432
433 case DW_AT_APPLE_runtime_class:
434 class_language = (LanguageType)form_value.Signed();
435 break;
436
437 case DW_AT_APPLE_objc_complete_type:
438 is_complete_objc_class = form_value.Signed();
439 break;
440
441 case DW_AT_allocated:
442 case DW_AT_associated:
443 case DW_AT_data_location:
444 case DW_AT_description:
445 case DW_AT_start_scope:
446 case DW_AT_visibility:
447 default:
448 case DW_AT_sibling:
449 break;
450 }
451 }
452 }
453 }
454
455 // UniqueDWARFASTType is large, so don't create a local variables on the
456 // stack, put it on the heap. This function is often called recursively
457 // and clang isn't good and sharing the stack space for variables in different blocks.
458 std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());
459
460 // Only try and unique the type if it has a name.
461 if (type_name_const_str &&
462 dwarf->GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
463 die,
464 decl,
465 byte_size_valid ? byte_size : -1,
466 *unique_ast_entry_ap))
467 {
468 // We have already parsed this type or from another
469 // compile unit. GCC loves to use the "one definition
470 // rule" which can result in multiple definitions
471 // of the same class over and over in each compile
472 // unit.
473 type_sp = unique_ast_entry_ap->m_type_sp;
474 if (type_sp)
475 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000476 dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
Greg Clayton261ac3f2015-08-28 01:01:03 +0000477 return type_sp;
478 }
479 }
480
481 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
482
483 int tag_decl_kind = -1;
484 AccessType default_accessibility = eAccessNone;
485 if (tag == DW_TAG_structure_type)
486 {
487 tag_decl_kind = clang::TTK_Struct;
488 default_accessibility = eAccessPublic;
489 }
490 else if (tag == DW_TAG_union_type)
491 {
492 tag_decl_kind = clang::TTK_Union;
493 default_accessibility = eAccessPublic;
494 }
495 else if (tag == DW_TAG_class_type)
496 {
497 tag_decl_kind = clang::TTK_Class;
498 default_accessibility = eAccessPrivate;
499 }
500
501 if (byte_size_valid && byte_size == 0 && type_name_cstr &&
502 die.HasChildren() == false &&
503 sc.comp_unit->GetLanguage() == eLanguageTypeObjC)
504 {
505 // Work around an issue with clang at the moment where
506 // forward declarations for objective C classes are emitted
507 // as:
508 // DW_TAG_structure_type [2]
509 // DW_AT_name( "ForwardObjcClass" )
510 // DW_AT_byte_size( 0x00 )
511 // DW_AT_decl_file( "..." )
512 // DW_AT_decl_line( 1 )
513 //
514 // Note that there is no DW_AT_declaration and there are
515 // no children, and the byte size is zero.
516 is_forward_declaration = true;
517 }
518
519 if (class_language == eLanguageTypeObjC ||
520 class_language == eLanguageTypeObjC_plus_plus)
521 {
522 if (!is_complete_objc_class && die.Supports_DW_AT_APPLE_objc_complete_type())
523 {
524 // We have a valid eSymbolTypeObjCClass class symbol whose
525 // name matches the current objective C class that we
526 // are trying to find and this DIE isn't the complete
527 // definition (we checked is_complete_objc_class above and
528 // know it is false), so the real definition is in here somewhere
529 type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
530
531 if (!type_sp)
532 {
533 SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
534 if (debug_map_symfile)
535 {
536 // We weren't able to find a full declaration in
537 // this DWARF, see if we have a declaration anywhere
538 // else...
539 type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
540 }
541 }
542
543 if (type_sp)
544 {
545 if (log)
546 {
547 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
548 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8" PRIx64,
549 static_cast<void*>(this),
550 die.GetOffset(),
551 DW_TAG_value_to_name(tag),
552 type_name_cstr,
553 type_sp->GetID());
554 }
555
556 // We found a real definition for this type elsewhere
557 // so lets use it and cache the fact that we found
558 // a complete type for this die
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000559 dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
Greg Clayton261ac3f2015-08-28 01:01:03 +0000560 return type_sp;
561 }
562 }
563 }
564
565
566 if (is_forward_declaration)
567 {
568 // We have a forward declaration to a type and we need
569 // to try and find a full declaration. We look in the
570 // current type index just in case we have a forward
571 // declaration followed by an actual declarations in the
572 // DWARF. If this fails, we need to look elsewhere...
573 if (log)
574 {
575 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
576 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type",
577 static_cast<void*>(this),
578 die.GetOffset(),
579 DW_TAG_value_to_name(tag),
580 type_name_cstr);
581 }
582
583 DWARFDeclContext die_decl_ctx;
584 die.GetDWARFDeclContext(die_decl_ctx);
585
586 //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
587 type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
588
589 if (!type_sp)
590 {
591 SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
592 if (debug_map_symfile)
593 {
594 // We weren't able to find a full declaration in
595 // this DWARF, see if we have a declaration anywhere
596 // else...
597 type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
598 }
599 }
600
601 if (type_sp)
602 {
603 if (log)
604 {
605 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
606 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
607 static_cast<void*>(this),
608 die.GetOffset(),
609 DW_TAG_value_to_name(tag),
610 type_name_cstr,
611 type_sp->GetID());
612 }
613
614 // We found a real definition for this type elsewhere
615 // so lets use it and cache the fact that we found
616 // a complete type for this die
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000617 dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
Greg Clayton261ac3f2015-08-28 01:01:03 +0000618 return type_sp;
619 }
620 }
621 assert (tag_decl_kind != -1);
622 bool clang_type_was_created = false;
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000623 clang_type.SetCompilerType(&m_ast, dwarf->GetForwardDeclDieToClangType().lookup (die.GetDIE()));
Greg Clayton261ac3f2015-08-28 01:01:03 +0000624 if (!clang_type)
625 {
626 clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (die, nullptr);
627 if (accessibility == eAccessNone && decl_ctx)
628 {
629 // Check the decl context that contains this class/struct/union.
630 // If it is a class we must give it an accessibility.
631 const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
632 if (DeclKindIsCXXClass (containing_decl_kind))
633 accessibility = default_accessibility;
634 }
635
636 ClangASTMetadata metadata;
637 metadata.SetUserID(die.GetID());
638 metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual (die));
639
640 if (type_name_cstr && strchr (type_name_cstr, '<'))
641 {
642 ClangASTContext::TemplateParameterInfos template_param_infos;
643 if (ParseTemplateParameterInfos (die, template_param_infos))
644 {
645 clang::ClassTemplateDecl *class_template_decl = m_ast.ParseClassTemplateDecl (decl_ctx,
646 accessibility,
647 type_name_cstr,
648 tag_decl_kind,
649 template_param_infos);
650
651 clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl (decl_ctx,
652 class_template_decl,
653 tag_decl_kind,
654 template_param_infos);
655 clang_type = m_ast.CreateClassTemplateSpecializationType (class_specialization_decl);
656 clang_type_was_created = true;
657
658 m_ast.SetMetadata (class_template_decl, metadata);
659 m_ast.SetMetadata (class_specialization_decl, metadata);
660 }
661 }
662
663 if (!clang_type_was_created)
664 {
665 clang_type_was_created = true;
666 clang_type = m_ast.CreateRecordType (decl_ctx,
667 accessibility,
668 type_name_cstr,
669 tag_decl_kind,
670 class_language,
671 &metadata);
672 }
673 }
674
675 // Store a forward declaration to this class type in case any
676 // parameters in any class methods need it for the clang
677 // types for function prototypes.
678 LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
679 type_sp.reset (new Type (die.GetID(),
680 dwarf,
681 type_name_const_str,
682 byte_size,
683 NULL,
684 LLDB_INVALID_UID,
685 Type::eEncodingIsUID,
686 &decl,
687 clang_type,
688 Type::eResolveStateForward));
689
690 type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
691
692
693 // Add our type to the unique type map so we don't
694 // end up creating many copies of the same type over
695 // and over in the ASTContext for our module
696 unique_ast_entry_ap->m_type_sp = type_sp;
697 unique_ast_entry_ap->m_die = die;
698 unique_ast_entry_ap->m_declaration = decl;
699 unique_ast_entry_ap->m_byte_size = byte_size;
700 dwarf->GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
701 *unique_ast_entry_ap);
702
703 if (is_forward_declaration && die.HasChildren())
704 {
705 // Check to see if the DIE actually has a definition, some version of GCC will
706 // emit DIEs with DW_AT_declaration set to true, but yet still have subprogram,
707 // members, or inheritance, so we can't trust it
708 DWARFDIE child_die = die.GetFirstChild();
709 while (child_die)
710 {
711 switch (child_die.Tag())
712 {
713 case DW_TAG_inheritance:
714 case DW_TAG_subprogram:
715 case DW_TAG_member:
716 case DW_TAG_APPLE_property:
717 case DW_TAG_class_type:
718 case DW_TAG_structure_type:
719 case DW_TAG_enumeration_type:
720 case DW_TAG_typedef:
721 case DW_TAG_union_type:
722 child_die.Clear();
723 is_forward_declaration = false;
724 break;
725 default:
726 child_die = child_die.GetSibling();
727 break;
728 }
729 }
730 }
731
732 if (!is_forward_declaration)
733 {
734 // Always start the definition for a class type so that
735 // if the class has child classes or types that require
736 // the class to be created for use as their decl contexts
737 // the class will be ready to accept these child definitions.
738 if (die.HasChildren() == false)
739 {
740 // No children for this struct/union/class, lets finish it
741 ClangASTContext::StartTagDeclarationDefinition (clang_type);
742 ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
743
744 if (tag == DW_TAG_structure_type) // this only applies in C
745 {
746 clang::RecordDecl *record_decl = ClangASTContext::GetAsRecordDecl(clang_type);
747
748 if (record_decl)
749 m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
750 }
751 }
752 else if (clang_type_was_created)
753 {
754 // Start the definition if the class is not objective C since
755 // the underlying decls respond to isCompleteDefinition(). Objective
756 // C decls don't respond to isCompleteDefinition() so we can't
757 // start the declaration definition right away. For C++ class/union/structs
758 // we want to start the definition in case the class is needed as the
759 // declaration context for a contained class or type without the need
760 // to complete that type..
761
762 if (class_language != eLanguageTypeObjC &&
763 class_language != eLanguageTypeObjC_plus_plus)
764 ClangASTContext::StartTagDeclarationDefinition (clang_type);
765
766 // Leave this as a forward declaration until we need
767 // to know the details of the type. lldb_private::Type
768 // will automatically call the SymbolFile virtual function
769 // "SymbolFileDWARF::CompleteType(Type *)"
770 // When the definition needs to be defined.
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000771 dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = clang_type.GetOpaqueQualType();
772 dwarf->GetForwardDeclClangTypeToDie()[ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = die.GetDIERef();
Greg Clayton261ac3f2015-08-28 01:01:03 +0000773 m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true);
774 }
775 }
Greg Clayton261ac3f2015-08-28 01:01:03 +0000776 }
777 break;
778
779 case DW_TAG_enumeration_type:
780 {
781 // Set a bit that lets us know that we are currently parsing this
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000782 dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000783
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000784 DWARFFormValue encoding_form;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000785
786 const size_t num_attributes = die.GetAttributes (attributes);
787 if (num_attributes > 0)
788 {
789 uint32_t i;
790
791 for (i=0; i<num_attributes; ++i)
792 {
793 attr = attributes.AttributeAtIndex(i);
794 if (attributes.ExtractFormValueAtIndex(i, form_value))
795 {
796 switch (attr)
797 {
798 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
799 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
800 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
801 case DW_AT_name:
802 type_name_cstr = form_value.AsCString();
803 type_name_const_str.SetCString(type_name_cstr);
804 break;
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000805 case DW_AT_type: encoding_form = form_value; break;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000806 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
807 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
808 case DW_AT_declaration: break; //is_forward_declaration = form_value.Boolean(); break;
809 case DW_AT_allocated:
810 case DW_AT_associated:
811 case DW_AT_bit_stride:
812 case DW_AT_byte_stride:
813 case DW_AT_data_location:
814 case DW_AT_description:
815 case DW_AT_start_scope:
816 case DW_AT_visibility:
817 case DW_AT_specification:
818 case DW_AT_abstract_origin:
819 case DW_AT_sibling:
820 break;
821 }
822 }
823 }
824
825 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
826
827 CompilerType enumerator_clang_type;
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000828 clang_type.SetCompilerType (&m_ast, dwarf->GetForwardDeclDieToClangType().lookup (die.GetDIE()));
Greg Clayton261ac3f2015-08-28 01:01:03 +0000829 if (!clang_type)
830 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000831 if (encoding_form.IsValid())
Greg Clayton261ac3f2015-08-28 01:01:03 +0000832 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000833 Type *enumerator_type = dwarf->ResolveTypeUID(DIERef(encoding_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +0000834 if (enumerator_type)
835 enumerator_clang_type = enumerator_type->GetFullCompilerType ();
836 }
837
838 if (!enumerator_clang_type)
839 enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
840 DW_ATE_signed,
841 byte_size * 8);
842
843 clang_type = m_ast.CreateEnumerationType (type_name_cstr,
844 GetClangDeclContextContainingDIE (die, nullptr),
845 decl,
846 enumerator_clang_type);
847 }
848 else
849 {
850 enumerator_clang_type = m_ast.GetEnumerationIntegerType (clang_type.GetOpaqueQualType());
851 }
852
853 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
854
855 type_sp.reset( new Type (die.GetID(),
856 dwarf,
857 type_name_const_str,
858 byte_size,
859 NULL,
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000860 DIERef(encoding_form).GetUID(),
Greg Clayton261ac3f2015-08-28 01:01:03 +0000861 Type::eEncodingIsUID,
862 &decl,
863 clang_type,
864 Type::eResolveStateForward));
865
866 ClangASTContext::StartTagDeclarationDefinition (clang_type);
867 if (die.HasChildren())
868 {
869 SymbolContext cu_sc(die.GetLLDBCompileUnit());
870 bool is_signed = false;
871 enumerator_clang_type.IsIntegerType(is_signed);
872 ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die);
873 }
874 ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
875 }
876 }
877 break;
878
879 case DW_TAG_inlined_subroutine:
880 case DW_TAG_subprogram:
881 case DW_TAG_subroutine_type:
882 {
883 // Set a bit that lets us know that we are currently parsing this
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000884 dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000885
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000886 DWARFFormValue type_die_form;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000887 bool is_variadic = false;
888 bool is_inline = false;
889 bool is_static = false;
890 bool is_virtual = false;
891 bool is_explicit = false;
892 bool is_artificial = false;
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000893 DWARFFormValue specification_die_form;
894 DWARFFormValue abstract_origin_die_form;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000895 dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
896
897 unsigned type_quals = 0;
898 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
899
900
901 const size_t num_attributes = die.GetAttributes (attributes);
902 if (num_attributes > 0)
903 {
904 uint32_t i;
905 for (i=0; i<num_attributes; ++i)
906 {
907 attr = attributes.AttributeAtIndex(i);
908 if (attributes.ExtractFormValueAtIndex(i, form_value))
909 {
910 switch (attr)
911 {
912 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
913 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
914 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
915 case DW_AT_name:
916 type_name_cstr = form_value.AsCString();
917 type_name_const_str.SetCString(type_name_cstr);
918 break;
919
920 case DW_AT_linkage_name:
921 case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&dwarf->get_debug_str_data()); break;
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000922 case DW_AT_type: type_die_form = form_value; break;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000923 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
924 case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
925 case DW_AT_inline: is_inline = form_value.Boolean(); break;
926 case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
927 case DW_AT_explicit: is_explicit = form_value.Boolean(); break;
928 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
929
930
931 case DW_AT_external:
932 if (form_value.Unsigned())
933 {
934 if (storage == clang::SC_None)
935 storage = clang::SC_Extern;
936 else
937 storage = clang::SC_PrivateExtern;
938 }
939 break;
940
941 case DW_AT_specification:
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000942 specification_die_form = form_value;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000943 break;
944
945 case DW_AT_abstract_origin:
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000946 abstract_origin_die_form = form_value;
Greg Clayton261ac3f2015-08-28 01:01:03 +0000947 break;
948
949 case DW_AT_object_pointer:
950 object_pointer_die_offset = form_value.Reference();
951 break;
952
953 case DW_AT_allocated:
954 case DW_AT_associated:
955 case DW_AT_address_class:
956 case DW_AT_calling_convention:
957 case DW_AT_data_location:
958 case DW_AT_elemental:
959 case DW_AT_entry_pc:
960 case DW_AT_frame_base:
961 case DW_AT_high_pc:
962 case DW_AT_low_pc:
963 case DW_AT_prototyped:
964 case DW_AT_pure:
965 case DW_AT_ranges:
966 case DW_AT_recursive:
967 case DW_AT_return_addr:
968 case DW_AT_segment:
969 case DW_AT_start_scope:
970 case DW_AT_static_link:
971 case DW_AT_trampoline:
972 case DW_AT_visibility:
973 case DW_AT_vtable_elem_location:
974 case DW_AT_description:
975 case DW_AT_sibling:
976 break;
977 }
978 }
979 }
980 }
981
982 std::string object_pointer_name;
983 if (object_pointer_die_offset != DW_INVALID_OFFSET)
984 {
985 DWARFDIE object_pointer_die = die.GetDIE (object_pointer_die_offset);
986 if (object_pointer_die)
987 {
988 const char *object_pointer_name_cstr = object_pointer_die.GetName();
989 if (object_pointer_name_cstr)
990 object_pointer_name = object_pointer_name_cstr;
991 }
992 }
993
994 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
995
996 CompilerType return_clang_type;
997 Type *func_type = NULL;
998
Tamas Berghammereb882fc2015-09-09 10:20:48 +0000999 if (type_die_form.IsValid())
1000 func_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00001001
1002 if (func_type)
1003 return_clang_type = func_type->GetForwardCompilerType ();
1004 else
1005 return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
1006
1007
1008 std::vector<CompilerType> function_param_types;
1009 std::vector<clang::ParmVarDecl*> function_param_decls;
1010
1011 // Parse the function children for the parameters
1012
1013 DWARFDIE decl_ctx_die;
1014 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, &decl_ctx_die);
1015 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
1016
1017 const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
1018 // Start off static. This will be set to false in ParseChildParameters(...)
1019 // if we find a "this" parameters as the first parameter
1020 if (is_cxx_method)
1021 is_static = true;
1022
1023 if (die.HasChildren())
1024 {
1025 bool skip_artificial = true;
1026 ParseChildParameters (sc,
1027 containing_decl_ctx,
1028 die,
1029 skip_artificial,
1030 is_static,
1031 is_variadic,
1032 function_param_types,
1033 function_param_decls,
1034 type_quals);
1035 }
1036
1037 // clang_type will get the function prototype clang type after this call
1038 clang_type = m_ast.CreateFunctionType (return_clang_type,
1039 function_param_types.data(),
1040 function_param_types.size(),
1041 is_variadic,
1042 type_quals);
1043
1044 bool ignore_containing_context = false;
1045
1046 if (type_name_cstr)
1047 {
1048 bool type_handled = false;
1049 if (tag == DW_TAG_subprogram ||
1050 tag == DW_TAG_inlined_subroutine)
1051 {
Jim Inghamaa816b82015-09-02 01:59:14 +00001052 ObjCLanguage::MethodName objc_method (type_name_cstr, true);
Greg Clayton261ac3f2015-08-28 01:01:03 +00001053 if (objc_method.IsValid(true))
1054 {
1055 CompilerType class_opaque_type;
1056 ConstString class_name(objc_method.GetClassName());
1057 if (class_name)
1058 {
1059 TypeSP complete_objc_class_type_sp (dwarf->FindCompleteObjCDefinitionTypeForDIE (DWARFDIE(), class_name, false));
1060
1061 if (complete_objc_class_type_sp)
1062 {
1063 CompilerType type_clang_forward_type = complete_objc_class_type_sp->GetForwardCompilerType ();
1064 if (ClangASTContext::IsObjCObjectOrInterfaceType(type_clang_forward_type))
1065 class_opaque_type = type_clang_forward_type;
1066 }
1067 }
1068
1069 if (class_opaque_type)
1070 {
1071 // If accessibility isn't set to anything valid, assume public for
1072 // now...
1073 if (accessibility == eAccessNone)
1074 accessibility = eAccessPublic;
1075
1076 clang::ObjCMethodDecl *objc_method_decl = m_ast.AddMethodToObjCObjectType (class_opaque_type,
1077 type_name_cstr,
1078 clang_type,
1079 accessibility,
1080 is_artificial);
1081 type_handled = objc_method_decl != NULL;
1082 if (type_handled)
1083 {
1084 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
1085 m_ast.SetMetadataAsUserID (objc_method_decl, die.GetID());
1086 }
1087 else
1088 {
1089 dwarf->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
1090 die.GetOffset(),
1091 tag,
1092 DW_TAG_value_to_name(tag));
1093 }
1094 }
1095 }
1096 else if (is_cxx_method)
1097 {
1098 // Look at the parent of this DIE and see if is is
1099 // a class or struct and see if this is actually a
1100 // C++ method
1101 Type *class_type = dwarf->ResolveType (decl_ctx_die);
1102 if (class_type)
1103 {
1104 if (class_type->GetID() != decl_ctx_die.GetID())
1105 {
1106 // We uniqued the parent class of this function to another class
1107 // so we now need to associate all dies under "decl_ctx_die" to
1108 // DIEs in the DIE for "class_type"...
1109 SymbolFileDWARF *class_symfile = NULL;
1110 DWARFDIE class_type_die;
1111
1112 SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
1113 if (debug_map_symfile)
1114 {
1115 class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001116 class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID()));
Greg Clayton261ac3f2015-08-28 01:01:03 +00001117 }
1118 else
1119 {
1120 class_symfile = dwarf;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001121 class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID()));
Greg Clayton261ac3f2015-08-28 01:01:03 +00001122 }
1123 if (class_type_die)
1124 {
1125 DWARFDIECollection failures;
1126
1127 CopyUniqueClassMethodTypes (decl_ctx_die,
1128 class_type_die,
1129 class_type,
1130 failures);
1131
1132 // FIXME do something with these failures that's smarter than
1133 // just dropping them on the ground. Unfortunately classes don't
1134 // like having stuff added to them after their definitions are
1135 // complete...
1136
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001137 type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
Greg Clayton261ac3f2015-08-28 01:01:03 +00001138 if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
1139 {
1140 type_sp = type_ptr->shared_from_this();
1141 break;
1142 }
1143 }
1144 }
1145
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001146 if (specification_die_form.IsValid())
Greg Clayton261ac3f2015-08-28 01:01:03 +00001147 {
1148 // We have a specification which we are going to base our function
1149 // prototype off of, so we need this type to be completed so that the
1150 // m_die_to_decl_ctx for the method in the specification has a valid
1151 // clang decl context.
1152 class_type->GetForwardCompilerType ();
1153 // If we have a specification, then the function type should have been
1154 // made with the specification and not with this die.
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001155 DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(DIERef(specification_die_form));
Greg Clayton261ac3f2015-08-28 01:01:03 +00001156 clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (spec_die);
1157 if (spec_clang_decl_ctx)
1158 {
1159 LinkDeclContextToDIE(spec_clang_decl_ctx, die);
1160 }
1161 else
1162 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001163 dwarf->GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64 ") has no decl\n",
Greg Clayton261ac3f2015-08-28 01:01:03 +00001164 die.GetID(),
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001165 specification_die_form.Reference());
Greg Clayton261ac3f2015-08-28 01:01:03 +00001166 }
1167 type_handled = true;
1168 }
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001169 else if (abstract_origin_die_form.IsValid())
Greg Clayton261ac3f2015-08-28 01:01:03 +00001170 {
1171 // We have a specification which we are going to base our function
1172 // prototype off of, so we need this type to be completed so that the
1173 // m_die_to_decl_ctx for the method in the abstract origin has a valid
1174 // clang decl context.
1175 class_type->GetForwardCompilerType ();
1176
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001177 DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(abstract_origin_die_form));
Greg Clayton261ac3f2015-08-28 01:01:03 +00001178 clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (abs_die);
1179 if (abs_clang_decl_ctx)
1180 {
1181 LinkDeclContextToDIE (abs_clang_decl_ctx, die);
1182 }
1183 else
1184 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001185 dwarf->GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64 ") has no decl\n",
Greg Clayton261ac3f2015-08-28 01:01:03 +00001186 die.GetID(),
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001187 abstract_origin_die_form.Reference());
Greg Clayton261ac3f2015-08-28 01:01:03 +00001188 }
1189 type_handled = true;
1190 }
1191 else
1192 {
1193 CompilerType class_opaque_type = class_type->GetForwardCompilerType ();
1194 if (ClangASTContext::IsCXXClassType(class_opaque_type))
1195 {
1196 if (class_opaque_type.IsBeingDefined ())
1197 {
1198 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
1199 // in the DWARF for C++ methods... Default to public for now...
1200 if (accessibility == eAccessNone)
1201 accessibility = eAccessPublic;
1202
1203 if (!is_static && !die.HasChildren())
1204 {
1205 // We have a C++ member function with no children (this pointer!)
1206 // and clang will get mad if we try and make a function that isn't
1207 // well formed in the DWARF, so we will just skip it...
1208 type_handled = true;
1209 }
1210 else
1211 {
1212 clang::CXXMethodDecl *cxx_method_decl;
1213 // REMOVE THE CRASH DESCRIPTION BELOW
1214 Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s",
1215 type_name_cstr,
1216 class_type->GetName().GetCString(),
1217 die.GetID(),
1218 dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str());
1219
1220 const bool is_attr_used = false;
1221
1222 cxx_method_decl = m_ast.AddMethodToCXXRecordType (class_opaque_type.GetOpaqueQualType(),
1223 type_name_cstr,
1224 clang_type,
1225 accessibility,
1226 is_virtual,
1227 is_static,
1228 is_inline,
1229 is_explicit,
1230 is_attr_used,
1231 is_artificial);
1232
1233 type_handled = cxx_method_decl != NULL;
1234
1235 if (type_handled)
1236 {
1237 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
1238
1239 Host::SetCrashDescription (NULL);
1240
1241
1242 ClangASTMetadata metadata;
1243 metadata.SetUserID(die.GetID());
1244
1245 if (!object_pointer_name.empty())
1246 {
1247 metadata.SetObjectPtrName(object_pointer_name.c_str());
1248 if (log)
1249 log->Printf ("Setting object pointer name: %s on method object %p.\n",
1250 object_pointer_name.c_str(),
1251 static_cast<void*>(cxx_method_decl));
1252 }
1253 m_ast.SetMetadata (cxx_method_decl, metadata);
1254 }
1255 else
1256 {
1257 ignore_containing_context = true;
1258 }
1259 }
1260 }
1261 else
1262 {
1263 // We were asked to parse the type for a method in a class, yet the
1264 // class hasn't been asked to complete itself through the
1265 // clang::ExternalASTSource protocol, so we need to just have the
1266 // class complete itself and do things the right way, then our
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001267 // DIE should then have an entry in the dwarf->GetDIEToType() map. First
1268 // we need to modify the dwarf->GetDIEToType() so it doesn't think we are
Greg Clayton261ac3f2015-08-28 01:01:03 +00001269 // trying to parse this DIE anymore...
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001270 dwarf->GetDIEToType()[die.GetDIE()] = NULL;
Greg Clayton261ac3f2015-08-28 01:01:03 +00001271
1272 // Now we get the full type to force our class type to complete itself
1273 // using the clang::ExternalASTSource protocol which will parse all
1274 // base classes and all methods (including the method for this DIE).
1275 class_type->GetFullCompilerType ();
1276
1277 // The type for this DIE should have been filled in the function call above
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001278 type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
Greg Clayton261ac3f2015-08-28 01:01:03 +00001279 if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
1280 {
1281 type_sp = type_ptr->shared_from_this();
1282 break;
1283 }
1284
1285 // FIXME This is fixing some even uglier behavior but we really need to
1286 // uniq the methods of each class as well as the class itself.
1287 // <rdar://problem/11240464>
1288 type_handled = true;
1289 }
1290 }
1291 }
1292 }
1293 }
1294 }
1295
1296 if (!type_handled)
1297 {
1298 // We just have a function that isn't part of a class
1299 clang::FunctionDecl *function_decl = m_ast.CreateFunctionDeclaration (ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx,
1300 type_name_cstr,
1301 clang_type,
1302 storage,
1303 is_inline);
1304
1305 // if (template_param_infos.GetSize() > 0)
1306 // {
1307 // clang::FunctionTemplateDecl *func_template_decl = CreateFunctionTemplateDecl (containing_decl_ctx,
1308 // function_decl,
1309 // type_name_cstr,
1310 // template_param_infos);
1311 //
1312 // CreateFunctionTemplateSpecializationInfo (function_decl,
1313 // func_template_decl,
1314 // template_param_infos);
1315 // }
1316 // Add the decl to our DIE to decl context map
1317 assert (function_decl);
1318 LinkDeclContextToDIE(function_decl, die);
1319 if (!function_param_decls.empty())
1320 m_ast.SetFunctionParameters (function_decl,
1321 &function_param_decls.front(),
1322 function_param_decls.size());
1323
1324 ClangASTMetadata metadata;
1325 metadata.SetUserID(die.GetID());
1326
1327 if (!object_pointer_name.empty())
1328 {
1329 metadata.SetObjectPtrName(object_pointer_name.c_str());
1330 if (log)
1331 log->Printf ("Setting object pointer name: %s on function object %p.",
1332 object_pointer_name.c_str(),
1333 static_cast<void*>(function_decl));
1334 }
1335 m_ast.SetMetadata (function_decl, metadata);
1336 }
1337 }
1338 type_sp.reset( new Type (die.GetID(),
1339 dwarf,
1340 type_name_const_str,
1341 0,
1342 NULL,
1343 LLDB_INVALID_UID,
1344 Type::eEncodingIsUID,
1345 &decl,
1346 clang_type,
1347 Type::eResolveStateFull));
1348 assert(type_sp.get());
1349 }
1350 break;
1351
1352 case DW_TAG_array_type:
1353 {
1354 // Set a bit that lets us know that we are currently parsing this
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001355 dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
Greg Clayton261ac3f2015-08-28 01:01:03 +00001356
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001357 DWARFFormValue type_die_form;
Greg Clayton261ac3f2015-08-28 01:01:03 +00001358 int64_t first_index = 0;
1359 uint32_t byte_stride = 0;
1360 uint32_t bit_stride = 0;
1361 bool is_vector = false;
1362 const size_t num_attributes = die.GetAttributes (attributes);
1363
1364 if (num_attributes > 0)
1365 {
1366 uint32_t i;
1367 for (i=0; i<num_attributes; ++i)
1368 {
1369 attr = attributes.AttributeAtIndex(i);
1370 if (attributes.ExtractFormValueAtIndex(i, form_value))
1371 {
1372 switch (attr)
1373 {
1374 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1375 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1376 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1377 case DW_AT_name:
1378 type_name_cstr = form_value.AsCString();
1379 type_name_const_str.SetCString(type_name_cstr);
1380 break;
1381
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001382 case DW_AT_type: type_die_form = form_value; break;
Greg Clayton261ac3f2015-08-28 01:01:03 +00001383 case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break;
1384 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
1385 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
1386 case DW_AT_GNU_vector: is_vector = form_value.Boolean(); break;
1387 case DW_AT_accessibility: break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
1388 case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
1389 case DW_AT_allocated:
1390 case DW_AT_associated:
1391 case DW_AT_data_location:
1392 case DW_AT_description:
1393 case DW_AT_ordering:
1394 case DW_AT_start_scope:
1395 case DW_AT_visibility:
1396 case DW_AT_specification:
1397 case DW_AT_abstract_origin:
1398 case DW_AT_sibling:
1399 break;
1400 }
1401 }
1402 }
1403
1404 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr);
1405
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001406 Type *element_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00001407
1408 if (element_type)
1409 {
1410 std::vector<uint64_t> element_orders;
1411 ParseChildArrayInfo(sc, die, first_index, element_orders, byte_stride, bit_stride);
1412 if (byte_stride == 0 && bit_stride == 0)
1413 byte_stride = element_type->GetByteSize();
1414 CompilerType array_element_type = element_type->GetForwardCompilerType ();
1415 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
1416 if (element_orders.size() > 0)
1417 {
1418 uint64_t num_elements = 0;
1419 std::vector<uint64_t>::const_reverse_iterator pos;
1420 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
1421 for (pos = element_orders.rbegin(); pos != end; ++pos)
1422 {
1423 num_elements = *pos;
1424 clang_type = m_ast.CreateArrayType (array_element_type,
1425 num_elements,
1426 is_vector);
1427 array_element_type = clang_type;
1428 array_element_bit_stride = num_elements ?
1429 array_element_bit_stride * num_elements :
1430 array_element_bit_stride;
1431 }
1432 }
1433 else
1434 {
1435 clang_type = m_ast.CreateArrayType (array_element_type, 0, is_vector);
1436 }
1437 ConstString empty_name;
1438 type_sp.reset( new Type (die.GetID(),
1439 dwarf,
1440 empty_name,
1441 array_element_bit_stride / 8,
1442 NULL,
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001443 DIERef(type_die_form).GetUID(),
Greg Clayton261ac3f2015-08-28 01:01:03 +00001444 Type::eEncodingIsUID,
1445 &decl,
1446 clang_type,
1447 Type::eResolveStateFull));
1448 type_sp->SetEncodingType (element_type);
1449 }
1450 }
1451 }
1452 break;
1453
1454 case DW_TAG_ptr_to_member_type:
1455 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001456 DWARFFormValue type_die_form;
1457 DWARFFormValue containing_type_die_form;
Greg Clayton261ac3f2015-08-28 01:01:03 +00001458
1459 const size_t num_attributes = die.GetAttributes (attributes);
1460
1461 if (num_attributes > 0) {
1462 uint32_t i;
1463 for (i=0; i<num_attributes; ++i)
1464 {
1465 attr = attributes.AttributeAtIndex(i);
1466 if (attributes.ExtractFormValueAtIndex(i, form_value))
1467 {
1468 switch (attr)
1469 {
1470 case DW_AT_type:
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001471 type_die_form = form_value; break;
Greg Clayton261ac3f2015-08-28 01:01:03 +00001472 case DW_AT_containing_type:
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001473 containing_type_die_form = form_value; break;
Greg Clayton261ac3f2015-08-28 01:01:03 +00001474 }
1475 }
1476 }
1477
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001478 Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form).GetUID());
1479 Type *class_type = dwarf->ResolveTypeUID(DIERef(containing_type_die_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00001480
1481 CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType ();
1482 CompilerType class_clang_type = class_type->GetLayoutCompilerType ();
1483
1484 clang_type = ClangASTContext::CreateMemberPointerType(pointee_clang_type, class_clang_type);
1485
1486 byte_size = clang_type.GetByteSize(nullptr);
1487
1488 type_sp.reset( new Type (die.GetID(),
1489 dwarf,
1490 type_name_const_str,
1491 byte_size,
1492 NULL,
1493 LLDB_INVALID_UID,
1494 Type::eEncodingIsUID,
1495 NULL,
1496 clang_type,
1497 Type::eResolveStateForward));
1498 }
1499
1500 break;
1501 }
1502 default:
1503 dwarf->GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
1504 die.GetOffset(),
1505 tag,
1506 DW_TAG_value_to_name(tag));
1507 break;
1508 }
1509
1510 if (type_sp.get())
1511 {
1512 DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
1513 dw_tag_t sc_parent_tag = sc_parent_die.Tag();
1514
1515 SymbolContextScope * symbol_context_scope = NULL;
1516 if (sc_parent_tag == DW_TAG_compile_unit)
1517 {
1518 symbol_context_scope = sc.comp_unit;
1519 }
1520 else if (sc.function != NULL && sc_parent_die)
1521 {
1522 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
1523 if (symbol_context_scope == NULL)
1524 symbol_context_scope = sc.function;
1525 }
1526
1527 if (symbol_context_scope != NULL)
1528 {
1529 type_sp->SetSymbolContextScope(symbol_context_scope);
1530 }
1531
1532 // We are ready to put this type into the uniqued list up at the module level
1533 type_list->Insert (type_sp);
1534
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001535 dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
Greg Clayton261ac3f2015-08-28 01:01:03 +00001536 }
1537 }
1538 else if (type_ptr != DIE_IS_BEING_PARSED)
1539 {
1540 type_sp = type_ptr->shared_from_this();
1541 }
1542 }
1543 return type_sp;
1544}
1545
1546// DWARF parsing functions
1547
1548class DWARFASTParserClang::DelayedAddObjCClassProperty
1549{
1550public:
1551 DelayedAddObjCClassProperty(const CompilerType &class_opaque_type,
1552 const char *property_name,
1553 const CompilerType &property_opaque_type, // The property type is only required if you don't have an ivar decl
1554 clang::ObjCIvarDecl *ivar_decl,
1555 const char *property_setter_name,
1556 const char *property_getter_name,
1557 uint32_t property_attributes,
1558 const ClangASTMetadata *metadata) :
1559 m_class_opaque_type (class_opaque_type),
1560 m_property_name (property_name),
1561 m_property_opaque_type (property_opaque_type),
1562 m_ivar_decl (ivar_decl),
1563 m_property_setter_name (property_setter_name),
1564 m_property_getter_name (property_getter_name),
1565 m_property_attributes (property_attributes)
1566 {
1567 if (metadata != NULL)
1568 {
1569 m_metadata_ap.reset(new ClangASTMetadata());
1570 *m_metadata_ap = *metadata;
1571 }
1572 }
1573
1574 DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
1575 {
1576 *this = rhs;
1577 }
1578
1579 DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
1580 {
1581 m_class_opaque_type = rhs.m_class_opaque_type;
1582 m_property_name = rhs.m_property_name;
1583 m_property_opaque_type = rhs.m_property_opaque_type;
1584 m_ivar_decl = rhs.m_ivar_decl;
1585 m_property_setter_name = rhs.m_property_setter_name;
1586 m_property_getter_name = rhs.m_property_getter_name;
1587 m_property_attributes = rhs.m_property_attributes;
1588
1589 if (rhs.m_metadata_ap.get())
1590 {
1591 m_metadata_ap.reset (new ClangASTMetadata());
1592 *m_metadata_ap = *rhs.m_metadata_ap;
1593 }
1594 return *this;
1595 }
1596
1597 bool
1598 Finalize()
1599 {
Greg Claytonf73034f2015-09-08 18:15:05 +00001600 ClangASTContext *ast = llvm::cast<ClangASTContext>(m_class_opaque_type.GetTypeSystem());
Greg Clayton261ac3f2015-08-28 01:01:03 +00001601 return ast->AddObjCClassProperty (m_class_opaque_type,
1602 m_property_name,
1603 m_property_opaque_type,
1604 m_ivar_decl,
1605 m_property_setter_name,
1606 m_property_getter_name,
1607 m_property_attributes,
1608 m_metadata_ap.get());
1609 }
1610
1611private:
1612 CompilerType m_class_opaque_type;
1613 const char *m_property_name;
1614 CompilerType m_property_opaque_type;
1615 clang::ObjCIvarDecl *m_ivar_decl;
1616 const char *m_property_setter_name;
1617 const char *m_property_getter_name;
1618 uint32_t m_property_attributes;
1619 std::unique_ptr<ClangASTMetadata> m_metadata_ap;
1620};
1621
1622bool
1623DWARFASTParserClang::ParseTemplateDIE (const DWARFDIE &die,
1624 ClangASTContext::TemplateParameterInfos &template_param_infos)
1625{
1626 const dw_tag_t tag = die.Tag();
1627
1628 switch (tag)
1629 {
1630 case DW_TAG_template_type_parameter:
1631 case DW_TAG_template_value_parameter:
1632 {
1633 DWARFAttributes attributes;
1634 const size_t num_attributes = die.GetAttributes (attributes);
1635 const char *name = NULL;
1636 Type *lldb_type = NULL;
1637 CompilerType clang_type;
1638 uint64_t uval64 = 0;
1639 bool uval64_valid = false;
1640 if (num_attributes > 0)
1641 {
1642 DWARFFormValue form_value;
1643 for (size_t i=0; i<num_attributes; ++i)
1644 {
1645 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1646
1647 switch (attr)
1648 {
1649 case DW_AT_name:
1650 if (attributes.ExtractFormValueAtIndex(i, form_value))
1651 name = form_value.AsCString();
1652 break;
1653
1654 case DW_AT_type:
1655 if (attributes.ExtractFormValueAtIndex(i, form_value))
1656 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001657 lldb_type = die.ResolveTypeUID(DIERef(form_value).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00001658 if (lldb_type)
1659 clang_type = lldb_type->GetForwardCompilerType ();
1660 }
1661 break;
1662
1663 case DW_AT_const_value:
1664 if (attributes.ExtractFormValueAtIndex(i, form_value))
1665 {
1666 uval64_valid = true;
1667 uval64 = form_value.Unsigned();
1668 }
1669 break;
1670 default:
1671 break;
1672 }
1673 }
1674
1675 clang::ASTContext *ast = m_ast.getASTContext();
1676 if (!clang_type)
1677 clang_type = m_ast.GetBasicType(eBasicTypeVoid);
1678
1679 if (clang_type)
1680 {
1681 bool is_signed = false;
1682 if (name && name[0])
1683 template_param_infos.names.push_back(name);
1684 else
1685 template_param_infos.names.push_back(NULL);
1686
1687 if (tag == DW_TAG_template_value_parameter &&
1688 lldb_type != NULL &&
1689 clang_type.IsIntegerType (is_signed) &&
1690 uval64_valid)
1691 {
1692 llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
1693 template_param_infos.args.push_back (clang::TemplateArgument (*ast,
1694 llvm::APSInt(apint),
1695 ClangASTContext::GetQualType(clang_type)));
1696 }
1697 else
1698 {
1699 template_param_infos.args.push_back (clang::TemplateArgument (ClangASTContext::GetQualType(clang_type)));
1700 }
1701 }
1702 else
1703 {
1704 return false;
1705 }
1706
1707 }
1708 }
1709 return true;
1710
1711 default:
1712 break;
1713 }
1714 return false;
1715}
1716
1717bool
1718DWARFASTParserClang::ParseTemplateParameterInfos (const DWARFDIE &parent_die,
1719 ClangASTContext::TemplateParameterInfos &template_param_infos)
1720{
1721
1722 if (!parent_die)
1723 return false;
1724
1725 Args template_parameter_names;
1726 for (DWARFDIE die = parent_die.GetFirstChild();
1727 die.IsValid();
1728 die = die.GetSibling())
1729 {
1730 const dw_tag_t tag = die.Tag();
1731
1732 switch (tag)
1733 {
1734 case DW_TAG_template_type_parameter:
1735 case DW_TAG_template_value_parameter:
1736 ParseTemplateDIE (die, template_param_infos);
1737 break;
1738
1739 default:
1740 break;
1741 }
1742 }
1743 if (template_param_infos.args.empty())
1744 return false;
1745 return template_param_infos.args.size() == template_param_infos.names.size();
1746}
1747
1748bool
1749DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
1750 lldb_private::Type *type,
1751 CompilerType &clang_type)
1752{
1753 // Disable external storage for this type so we don't get anymore
1754 // clang::ExternalASTSource queries for this type.
1755 m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), false);
1756
1757 if (!die)
1758 return false;
1759
1760 const dw_tag_t tag = die.Tag();
1761
1762 SymbolFileDWARF *dwarf = die.GetDWARF();
1763
1764 Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
1765 if (log)
1766 dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
1767 "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
1768 die.GetID(),
1769 die.GetTagAsCString(),
1770 type->GetName().AsCString());
1771 assert (clang_type);
1772 DWARFAttributes attributes;
1773
1774 switch (tag)
1775 {
1776 case DW_TAG_structure_type:
1777 case DW_TAG_union_type:
1778 case DW_TAG_class_type:
1779 {
1780 LayoutInfo layout_info;
1781
1782 {
1783 if (die.HasChildren())
1784 {
1785 LanguageType class_language = eLanguageTypeUnknown;
1786 if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type))
1787 {
1788 class_language = eLanguageTypeObjC;
1789 // For objective C we don't start the definition when
1790 // the class is created.
1791 ClangASTContext::StartTagDeclarationDefinition (clang_type);
1792 }
1793
1794 int tag_decl_kind = -1;
1795 AccessType default_accessibility = eAccessNone;
1796 if (tag == DW_TAG_structure_type)
1797 {
1798 tag_decl_kind = clang::TTK_Struct;
1799 default_accessibility = eAccessPublic;
1800 }
1801 else if (tag == DW_TAG_union_type)
1802 {
1803 tag_decl_kind = clang::TTK_Union;
1804 default_accessibility = eAccessPublic;
1805 }
1806 else if (tag == DW_TAG_class_type)
1807 {
1808 tag_decl_kind = clang::TTK_Class;
1809 default_accessibility = eAccessPrivate;
1810 }
1811
1812 SymbolContext sc(die.GetLLDBCompileUnit());
1813 std::vector<clang::CXXBaseSpecifier *> base_classes;
1814 std::vector<int> member_accessibilities;
1815 bool is_a_class = false;
1816 // Parse members and base classes first
1817 DWARFDIECollection member_function_dies;
1818
1819 DelayedPropertyList delayed_properties;
1820 ParseChildMembers (sc,
1821 die,
1822 clang_type,
1823 class_language,
1824 base_classes,
1825 member_accessibilities,
1826 member_function_dies,
1827 delayed_properties,
1828 default_accessibility,
1829 is_a_class,
1830 layout_info);
1831
1832 // Now parse any methods if there were any...
1833 size_t num_functions = member_function_dies.Size();
1834 if (num_functions > 0)
1835 {
1836 for (size_t i=0; i<num_functions; ++i)
1837 {
1838 dwarf->ResolveType(member_function_dies.GetDIEAtIndex(i));
1839 }
1840 }
1841
1842 if (class_language == eLanguageTypeObjC)
1843 {
1844 ConstString class_name (clang_type.GetTypeName());
1845 if (class_name)
1846 {
1847 DIEArray method_die_offsets;
1848 dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets);
1849
1850 if (!method_die_offsets.empty())
1851 {
1852 DWARFDebugInfo* debug_info = dwarf->DebugInfo();
1853
1854 const size_t num_matches = method_die_offsets.size();
1855 for (size_t i=0; i<num_matches; ++i)
1856 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00001857 const DIERef& die_ref = method_die_offsets[i];
1858 DWARFDIE method_die = debug_info->GetDIE (die_ref);
Greg Clayton261ac3f2015-08-28 01:01:03 +00001859
1860 if (method_die)
1861 method_die.ResolveType ();
1862 }
1863 }
1864
1865 for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
1866 pi != pe;
1867 ++pi)
1868 pi->Finalize();
1869 }
1870 }
1871
1872 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1873 // need to tell the clang type it is actually a class.
1874 if (class_language != eLanguageTypeObjC)
1875 {
1876 if (is_a_class && tag_decl_kind != clang::TTK_Class)
1877 m_ast.SetTagTypeKind (ClangASTContext::GetQualType(clang_type), clang::TTK_Class);
1878 }
1879
1880 // Since DW_TAG_structure_type gets used for both classes
1881 // and structures, we may need to set any DW_TAG_member
1882 // fields to have a "private" access if none was specified.
1883 // When we parsed the child members we tracked that actual
1884 // accessibility value for each DW_TAG_member in the
1885 // "member_accessibilities" array. If the value for the
1886 // member is zero, then it was set to the "default_accessibility"
1887 // which for structs was "public". Below we correct this
1888 // by setting any fields to "private" that weren't correctly
1889 // set.
1890 if (is_a_class && !member_accessibilities.empty())
1891 {
1892 // This is a class and all members that didn't have
1893 // their access specified are private.
1894 m_ast.SetDefaultAccessForRecordFields (m_ast.GetAsRecordDecl(clang_type),
1895 eAccessPrivate,
1896 &member_accessibilities.front(),
1897 member_accessibilities.size());
1898 }
1899
1900 if (!base_classes.empty())
1901 {
1902 // Make sure all base classes refer to complete types and not
1903 // forward declarations. If we don't do this, clang will crash
1904 // with an assertion in the call to clang_type.SetBaseClassesForClassType()
1905 bool base_class_error = false;
1906 for (auto &base_class : base_classes)
1907 {
1908 clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo();
1909 if (type_source_info)
1910 {
1911 CompilerType base_class_type (&m_ast, type_source_info->getType().getAsOpaquePtr());
1912 if (base_class_type.GetCompleteType() == false)
1913 {
1914 if (!base_class_error)
1915 {
1916 dwarf->GetObjectFile()->GetModule()->ReportError ("DWARF DIE at 0x%8.8x for class '%s' has a base class '%s' that is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
1917 die.GetOffset(),
1918 die.GetName(),
1919 base_class_type.GetTypeName().GetCString(),
1920 sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
1921 }
1922 // We have no choice other than to pretend that the base class
1923 // is complete. If we don't do this, clang will crash when we
1924 // call setBases() inside of "clang_type.SetBaseClassesForClassType()"
1925 // below. Since we provide layout assistance, all ivars in this
1926 // class and other classes will be fine, this is the best we can do
1927 // short of crashing.
1928
1929 ClangASTContext::StartTagDeclarationDefinition (base_class_type);
1930 ClangASTContext::CompleteTagDeclarationDefinition (base_class_type);
1931 }
1932 }
1933 }
1934 m_ast.SetBaseClassesForClassType (clang_type.GetOpaqueQualType(),
1935 &base_classes.front(),
1936 base_classes.size());
1937
1938 // Clang will copy each CXXBaseSpecifier in "base_classes"
1939 // so we have to free them all.
1940 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1941 base_classes.size());
1942 }
1943 }
1944 }
1945
1946 ClangASTContext::BuildIndirectFields (clang_type);
1947 ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
1948
1949 if (!layout_info.field_offsets.empty() ||
1950 !layout_info.base_offsets.empty() ||
1951 !layout_info.vbase_offsets.empty() )
1952 {
1953 if (type)
1954 layout_info.bit_size = type->GetByteSize() * 8;
1955 if (layout_info.bit_size == 0)
1956 layout_info.bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
1957
1958 clang::CXXRecordDecl *record_decl = m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
1959 if (record_decl)
1960 {
1961 if (log)
1962 {
1963 ModuleSP module_sp = dwarf->GetObjectFile()->GetModule();
1964
1965 if (module_sp)
1966 {
1967 module_sp->LogMessage (log,
1968 "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
1969 static_cast<void*>(clang_type.GetOpaqueQualType()),
1970 static_cast<void*>(record_decl),
1971 layout_info.bit_size,
1972 layout_info.alignment,
1973 static_cast<uint32_t>(layout_info.field_offsets.size()),
1974 static_cast<uint32_t>(layout_info.base_offsets.size()),
1975 static_cast<uint32_t>(layout_info.vbase_offsets.size()));
1976
1977 uint32_t idx;
1978 {
1979 llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos,
1980 end = layout_info.field_offsets.end();
1981 for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx)
1982 {
1983 module_sp->LogMessage(log,
1984 "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }",
1985 static_cast<void *>(clang_type.GetOpaqueQualType()),
1986 idx,
1987 static_cast<uint32_t>(pos->second),
1988 pos->first->getNameAsString().c_str());
1989 }
1990 }
1991
1992 {
1993 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos,
1994 base_end = layout_info.base_offsets.end();
1995 for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; ++base_pos, ++idx)
1996 {
1997 module_sp->LogMessage(log,
1998 "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }",
1999 clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(),
2000 base_pos->first->getNameAsString().c_str());
2001 }
2002 }
2003 {
2004 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos,
2005 vbase_end = layout_info.vbase_offsets.end();
2006 for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; ++vbase_pos, ++idx)
2007 {
2008 module_sp->LogMessage(log,
2009 "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }",
2010 static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
2011 static_cast<uint32_t>(vbase_pos->second.getQuantity()),
2012 vbase_pos->first->getNameAsString().c_str());
2013 }
2014 }
2015
2016 }
2017 }
2018 m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
2019 }
2020 }
2021 }
2022
2023 return (bool)clang_type;
2024
2025 case DW_TAG_enumeration_type:
2026 ClangASTContext::StartTagDeclarationDefinition (clang_type);
2027 if (die.HasChildren())
2028 {
2029 SymbolContext sc(die.GetLLDBCompileUnit());
2030 bool is_signed = false;
2031 clang_type.IsIntegerType(is_signed);
2032 ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die);
2033 }
2034 ClangASTContext::CompleteTagDeclarationDefinition (clang_type);
2035 return (bool)clang_type;
2036
2037 default:
2038 assert(false && "not a forward clang type decl!");
2039 break;
2040 }
2041
2042 return false;
2043}
2044
Paul Hermanea188fc2015-09-16 18:48:30 +00002045std::vector<DWARFDIE>
2046DWARFASTParserClang::GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context)
2047{
2048 std::vector<DWARFDIE> result;
2049 for (auto it = m_decl_ctx_to_die.find((clang::DeclContext *)decl_context.GetOpaqueDeclContext()); it != m_decl_ctx_to_die.end(); it++)
2050 result.push_back(it->second);
2051 return result;
2052}
2053
Paul Hermand628cbb2015-09-15 23:44:17 +00002054CompilerDecl
2055DWARFASTParserClang::GetDeclForUIDFromDWARF (const DWARFDIE &die)
2056{
2057 clang::Decl *clang_decl = GetClangDeclForDIE(die);
2058 if (clang_decl != nullptr)
2059 return CompilerDecl(&m_ast, clang_decl);
2060 return CompilerDecl();
2061}
2062
Greg Clayton261ac3f2015-08-28 01:01:03 +00002063CompilerDeclContext
2064DWARFASTParserClang::GetDeclContextForUIDFromDWARF (const DWARFDIE &die)
2065{
2066 clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE (die);
2067 if (clang_decl_ctx)
2068 return CompilerDeclContext(&m_ast, clang_decl_ctx);
2069 return CompilerDeclContext();
2070}
2071
2072CompilerDeclContext
2073DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die)
2074{
2075 clang::DeclContext *clang_decl_ctx = GetClangDeclContextContainingDIE (die, nullptr);
2076 if (clang_decl_ctx)
2077 return CompilerDeclContext(&m_ast, clang_decl_ctx);
2078 return CompilerDeclContext();
2079}
2080
2081size_t
2082DWARFASTParserClang::ParseChildEnumerators (const SymbolContext& sc,
2083 lldb_private::CompilerType &clang_type,
2084 bool is_signed,
2085 uint32_t enumerator_byte_size,
2086 const DWARFDIE &parent_die)
2087{
2088 if (!parent_die)
2089 return 0;
2090
2091 size_t enumerators_added = 0;
2092
2093 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
2094 {
2095 const dw_tag_t tag = die.Tag();
2096 if (tag == DW_TAG_enumerator)
2097 {
2098 DWARFAttributes attributes;
2099 const size_t num_child_attributes = die.GetAttributes(attributes);
2100 if (num_child_attributes > 0)
2101 {
2102 const char *name = NULL;
2103 bool got_value = false;
2104 int64_t enum_value = 0;
2105 Declaration decl;
2106
2107 uint32_t i;
2108 for (i=0; i<num_child_attributes; ++i)
2109 {
2110 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2111 DWARFFormValue form_value;
2112 if (attributes.ExtractFormValueAtIndex(i, form_value))
2113 {
2114 switch (attr)
2115 {
2116 case DW_AT_const_value:
2117 got_value = true;
2118 if (is_signed)
2119 enum_value = form_value.Signed();
2120 else
2121 enum_value = form_value.Unsigned();
2122 break;
2123
2124 case DW_AT_name:
2125 name = form_value.AsCString();
2126 break;
2127
2128 case DW_AT_description:
2129 default:
2130 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2131 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2132 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2133 case DW_AT_sibling:
2134 break;
2135 }
2136 }
2137 }
2138
2139 if (name && name[0] && got_value)
2140 {
2141 m_ast.AddEnumerationValueToEnumerationType (clang_type.GetOpaqueQualType(),
2142 m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()),
2143 decl,
2144 name,
2145 enum_value,
2146 enumerator_byte_size * 8);
2147 ++enumerators_added;
2148 }
2149 }
2150 }
2151 }
2152 return enumerators_added;
2153}
2154
2155#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
2156
2157class DIEStack
2158{
2159public:
2160
2161 void Push (const DWARFDIE &die)
2162 {
2163 m_dies.push_back (die);
2164 }
2165
2166
2167 void LogDIEs (Log *log)
2168 {
2169 StreamString log_strm;
2170 const size_t n = m_dies.size();
2171 log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
2172 for (size_t i=0; i<n; i++)
2173 {
2174 std::string qualified_name;
2175 const DWARFDIE &die = m_dies[i];
2176 die.GetQualifiedName(qualified_name);
2177 log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n",
2178 (uint64_t)i,
2179 die.GetOffset(),
2180 die.GetTagAsCString(),
2181 qualified_name.c_str());
2182 }
2183 log->PutCString(log_strm.GetData());
2184 }
2185 void Pop ()
2186 {
2187 m_dies.pop_back();
2188 }
2189
2190 class ScopedPopper
2191 {
2192 public:
2193 ScopedPopper (DIEStack &die_stack) :
2194 m_die_stack (die_stack),
2195 m_valid (false)
2196 {
2197 }
2198
2199 void
2200 Push (const DWARFDIE &die)
2201 {
2202 m_valid = true;
2203 m_die_stack.Push (die);
2204 }
2205
2206 ~ScopedPopper ()
2207 {
2208 if (m_valid)
2209 m_die_stack.Pop();
2210 }
2211
2212
2213
2214 protected:
2215 DIEStack &m_die_stack;
2216 bool m_valid;
2217 };
2218
2219protected:
2220 typedef std::vector<DWARFDIE> Stack;
2221 Stack m_dies;
2222};
2223#endif
2224
Greg Clayton261ac3f2015-08-28 01:01:03 +00002225Function *
2226DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc,
2227 const DWARFDIE &die)
2228{
2229 DWARFRangeList func_ranges;
2230 const char *name = NULL;
2231 const char *mangled = NULL;
2232 int decl_file = 0;
2233 int decl_line = 0;
2234 int decl_column = 0;
2235 int call_file = 0;
2236 int call_line = 0;
2237 int call_column = 0;
2238 DWARFExpression frame_base(die.GetCU());
2239
2240 const dw_tag_t tag = die.Tag();
2241
2242 if (tag != DW_TAG_subprogram)
2243 return NULL;
2244
2245 if (die.GetDIENamesAndRanges (name,
2246 mangled,
2247 func_ranges,
2248 decl_file,
2249 decl_line,
2250 decl_column,
2251 call_file,
2252 call_line,
2253 call_column,
2254 &frame_base))
2255 {
2256
2257 // Union of all ranges in the function DIE (if the function is discontiguous)
2258 AddressRange func_range;
2259 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
2260 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
2261 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
2262 {
2263 ModuleSP module_sp (die.GetModule());
2264 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetSectionList());
2265 if (func_range.GetBaseAddress().IsValid())
2266 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
2267 }
2268
2269 if (func_range.GetBaseAddress().IsValid())
2270 {
2271 Mangled func_name;
2272 if (mangled)
2273 func_name.SetValue(ConstString(mangled), true);
2274 else if (die.GetParent().Tag() == DW_TAG_compile_unit &&
Jim Ingham0e0984e2015-09-02 01:06:46 +00002275 Language::LanguageIsCPlusPlus(die.GetLanguage()) &&
Greg Clayton261ac3f2015-08-28 01:01:03 +00002276 name && strcmp(name, "main") != 0)
2277 {
2278 // If the mangled name is not present in the DWARF, generate the demangled name
2279 // using the decl context. We skip if the function is "main" as its name is
2280 // never mangled.
2281 bool is_static = false;
2282 bool is_variadic = false;
2283 unsigned type_quals = 0;
2284 std::vector<CompilerType> param_types;
2285 std::vector<clang::ParmVarDecl*> param_decls;
2286 DWARFDeclContext decl_ctx;
2287 StreamString sstr;
2288
2289 die.GetDWARFDeclContext(decl_ctx);
2290 sstr << decl_ctx.GetQualifiedName();
2291
2292 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(die, nullptr);
2293 ParseChildParameters(sc,
2294 containing_decl_ctx,
2295 die,
2296 true,
2297 is_static,
2298 is_variadic,
2299 param_types,
2300 param_decls,
2301 type_quals);
2302 sstr << "(";
2303 for (size_t i = 0; i < param_types.size(); i++)
2304 {
2305 if (i > 0)
2306 sstr << ", ";
2307 sstr << param_types[i].GetTypeName();
2308 }
2309 if (is_variadic)
2310 sstr << ", ...";
2311 sstr << ")";
2312 if (type_quals & clang::Qualifiers::Const)
2313 sstr << " const";
2314
2315 func_name.SetValue(ConstString(sstr.GetData()), false);
2316 }
2317 else
2318 func_name.SetValue(ConstString(name), false);
2319
2320 FunctionSP func_sp;
2321 std::unique_ptr<Declaration> decl_ap;
2322 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
2323 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
2324 decl_line,
2325 decl_column));
2326
2327 SymbolFileDWARF *dwarf = die.GetDWARF();
2328 // Supply the type _only_ if it has already been parsed
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002329 Type *func_type = dwarf->GetDIEToType().lookup (die.GetDIE());
Greg Clayton261ac3f2015-08-28 01:01:03 +00002330
2331 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
2332
2333 if (dwarf->FixupAddress (func_range.GetBaseAddress()))
2334 {
2335 const user_id_t func_user_id = die.GetID();
2336 func_sp.reset(new Function (sc.comp_unit,
2337 func_user_id, // UserID is the DIE offset
2338 func_user_id,
2339 func_name,
2340 func_type,
2341 func_range)); // first address range
2342
2343 if (func_sp.get() != NULL)
2344 {
2345 if (frame_base.IsValid())
2346 func_sp->GetFrameBaseExpression() = frame_base;
2347 sc.comp_unit->AddFunction(func_sp);
2348 return func_sp.get();
2349 }
2350 }
2351 }
2352 }
2353 return NULL;
2354}
2355
2356
2357size_t
2358DWARFASTParserClang::ParseChildMembers (const SymbolContext& sc,
2359 const DWARFDIE &parent_die,
2360 CompilerType &class_clang_type,
2361 const LanguageType class_language,
2362 std::vector<clang::CXXBaseSpecifier *>& base_classes,
2363 std::vector<int>& member_accessibilities,
2364 DWARFDIECollection& member_function_dies,
2365 DelayedPropertyList& delayed_properties,
2366 AccessType& default_accessibility,
2367 bool &is_a_class,
2368 LayoutInfo &layout_info)
2369{
2370 if (!parent_die)
2371 return 0;
2372
2373 size_t count = 0;
2374 uint32_t member_idx = 0;
2375 BitfieldInfo last_field_info;
2376
2377 ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
Greg Claytonf73034f2015-09-08 18:15:05 +00002378 ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem());
Greg Clayton261ac3f2015-08-28 01:01:03 +00002379 if (ast == nullptr)
2380 return 0;
2381
2382 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
2383 {
2384 dw_tag_t tag = die.Tag();
2385
2386 switch (tag)
2387 {
2388 case DW_TAG_member:
2389 case DW_TAG_APPLE_property:
2390 {
2391 DWARFAttributes attributes;
2392 const size_t num_attributes = die.GetAttributes (attributes);
2393 if (num_attributes > 0)
2394 {
2395 Declaration decl;
2396 //DWARFExpression location;
2397 const char *name = NULL;
2398 const char *prop_name = NULL;
2399 const char *prop_getter_name = NULL;
2400 const char *prop_setter_name = NULL;
2401 uint32_t prop_attributes = 0;
2402
2403
2404 bool is_artificial = false;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002405 DWARFFormValue encoding_form;
Greg Clayton261ac3f2015-08-28 01:01:03 +00002406 AccessType accessibility = eAccessNone;
2407 uint32_t member_byte_offset = UINT32_MAX;
2408 size_t byte_size = 0;
2409 size_t bit_offset = 0;
2410 size_t bit_size = 0;
2411 bool is_external = false; // On DW_TAG_members, this means the member is static
2412 uint32_t i;
2413 for (i=0; i<num_attributes && !is_artificial; ++i)
2414 {
2415 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2416 DWARFFormValue form_value;
2417 if (attributes.ExtractFormValueAtIndex(i, form_value))
2418 {
2419 switch (attr)
2420 {
2421 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2422 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2423 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2424 case DW_AT_name: name = form_value.AsCString(); break;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002425 case DW_AT_type: encoding_form = form_value; break;
Greg Clayton261ac3f2015-08-28 01:01:03 +00002426 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
2427 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
2428 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2429 case DW_AT_data_member_location:
2430 if (form_value.BlockData())
2431 {
2432 Value initialValue(0);
2433 Value memberOffset(0);
2434 const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data();
2435 uint32_t block_length = form_value.Unsigned();
2436 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
2437 if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
2438 NULL, // ClangExpressionVariableList *
2439 NULL, // ClangExpressionDeclMap *
2440 NULL, // RegisterContext *
2441 module_sp,
2442 debug_info_data,
2443 die.GetCU(),
2444 block_offset,
2445 block_length,
2446 eRegisterKindDWARF,
2447 &initialValue,
2448 memberOffset,
2449 NULL))
2450 {
2451 member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
2452 }
2453 }
2454 else
2455 {
2456 // With DWARF 3 and later, if the value is an integer constant,
2457 // this form value is the offset in bytes from the beginning
2458 // of the containing entity.
2459 member_byte_offset = form_value.Unsigned();
2460 }
2461 break;
2462
2463 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
2464 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
2465 case DW_AT_APPLE_property_name: prop_name = form_value.AsCString();
2466 break;
2467 case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString();
2468 break;
2469 case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString();
2470 break;
2471 case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
2472 case DW_AT_external: is_external = form_value.Boolean(); break;
2473
2474 default:
2475 case DW_AT_declaration:
2476 case DW_AT_description:
2477 case DW_AT_mutable:
2478 case DW_AT_visibility:
2479 case DW_AT_sibling:
2480 break;
2481 }
2482 }
2483 }
2484
2485 if (prop_name)
2486 {
2487 ConstString fixed_getter;
2488 ConstString fixed_setter;
2489
2490 // Check if the property getter/setter were provided as full
2491 // names. We want basenames, so we extract them.
2492
2493 if (prop_getter_name && prop_getter_name[0] == '-')
2494 {
Jim Inghamaa816b82015-09-02 01:59:14 +00002495 ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
Greg Clayton261ac3f2015-08-28 01:01:03 +00002496 prop_getter_name = prop_getter_method.GetSelector().GetCString();
2497 }
2498
2499 if (prop_setter_name && prop_setter_name[0] == '-')
2500 {
Jim Inghamaa816b82015-09-02 01:59:14 +00002501 ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
Greg Clayton261ac3f2015-08-28 01:01:03 +00002502 prop_setter_name = prop_setter_method.GetSelector().GetCString();
2503 }
2504
2505 // If the names haven't been provided, they need to be
2506 // filled in.
2507
2508 if (!prop_getter_name)
2509 {
2510 prop_getter_name = prop_name;
2511 }
2512 if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly))
2513 {
2514 StreamString ss;
2515
2516 ss.Printf("set%c%s:",
2517 toupper(prop_name[0]),
2518 &prop_name[1]);
2519
2520 fixed_setter.SetCString(ss.GetData());
2521 prop_setter_name = fixed_setter.GetCString();
2522 }
2523 }
2524
2525 // Clang has a DWARF generation bug where sometimes it
2526 // represents fields that are references with bad byte size
2527 // and bit size/offset information such as:
2528 //
2529 // DW_AT_byte_size( 0x00 )
2530 // DW_AT_bit_size( 0x40 )
2531 // DW_AT_bit_offset( 0xffffffffffffffc0 )
2532 //
2533 // So check the bit offset to make sure it is sane, and if
2534 // the values are not sane, remove them. If we don't do this
2535 // then we will end up with a crash if we try to use this
2536 // type in an expression when clang becomes unhappy with its
2537 // recycled debug info.
2538
2539 if (bit_offset > 128)
2540 {
2541 bit_size = 0;
2542 bit_offset = 0;
2543 }
2544
2545 // FIXME: Make Clang ignore Objective-C accessibility for expressions
2546 if (class_language == eLanguageTypeObjC ||
2547 class_language == eLanguageTypeObjC_plus_plus)
2548 accessibility = eAccessNone;
2549
2550 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
2551 {
2552 // Not all compilers will mark the vtable pointer
2553 // member as artificial (llvm-gcc). We can't have
2554 // the virtual members in our classes otherwise it
2555 // throws off all child offsets since we end up
2556 // having and extra pointer sized member in our
2557 // class layouts.
2558 is_artificial = true;
2559 }
2560
2561 // Handle static members
2562 if (is_external && member_byte_offset == UINT32_MAX)
2563 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002564 Type *var_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00002565
2566 if (var_type)
2567 {
2568 if (accessibility == eAccessNone)
2569 accessibility = eAccessPublic;
2570 ClangASTContext::AddVariableToRecordType (class_clang_type,
2571 name,
2572 var_type->GetLayoutCompilerType (),
2573 accessibility);
2574 }
2575 break;
2576 }
2577
2578 if (is_artificial == false)
2579 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002580 Type *member_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00002581
2582 clang::FieldDecl *field_decl = NULL;
2583 if (tag == DW_TAG_member)
2584 {
2585 if (member_type)
2586 {
2587 if (accessibility == eAccessNone)
2588 accessibility = default_accessibility;
2589 member_accessibilities.push_back(accessibility);
2590
2591 uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
2592 if (bit_size > 0)
2593 {
2594
2595 BitfieldInfo this_field_info;
2596 this_field_info.bit_offset = field_bit_offset;
2597 this_field_info.bit_size = bit_size;
2598
2599 /////////////////////////////////////////////////////////////
2600 // How to locate a field given the DWARF debug information
2601 //
2602 // AT_byte_size indicates the size of the word in which the
2603 // bit offset must be interpreted.
2604 //
2605 // AT_data_member_location indicates the byte offset of the
2606 // word from the base address of the structure.
2607 //
2608 // AT_bit_offset indicates how many bits into the word
2609 // (according to the host endianness) the low-order bit of
2610 // the field starts. AT_bit_offset can be negative.
2611 //
2612 // AT_bit_size indicates the size of the field in bits.
2613 /////////////////////////////////////////////////////////////
2614
2615 if (byte_size == 0)
2616 byte_size = member_type->GetByteSize();
2617
2618 if (die.GetDWARF()->GetObjectFile()->GetByteOrder() == eByteOrderLittle)
2619 {
2620 this_field_info.bit_offset += byte_size * 8;
2621 this_field_info.bit_offset -= (bit_offset + bit_size);
2622 }
2623 else
2624 {
2625 this_field_info.bit_offset += bit_offset;
2626 }
2627
2628 // Update the field bit offset we will report for layout
2629 field_bit_offset = this_field_info.bit_offset;
2630
2631 // If the member to be emitted did not start on a character boundary and there is
2632 // empty space between the last field and this one, then we need to emit an
2633 // anonymous member filling up the space up to its start. There are three cases
2634 // here:
2635 //
2636 // 1 If the previous member ended on a character boundary, then we can emit an
2637 // anonymous member starting at the most recent character boundary.
2638 //
2639 // 2 If the previous member did not end on a character boundary and the distance
2640 // from the end of the previous member to the current member is less than a
2641 // word width, then we can emit an anonymous member starting right after the
2642 // previous member and right before this member.
2643 //
2644 // 3 If the previous member did not end on a character boundary and the distance
2645 // from the end of the previous member to the current member is greater than
2646 // or equal a word width, then we act as in Case 1.
2647
2648 const uint64_t character_width = 8;
2649 const uint64_t word_width = 32;
2650
2651 // Objective-C has invalid DW_AT_bit_offset values in older versions
2652 // of clang, so we have to be careful and only insert unnamed bitfields
2653 // if we have a new enough clang.
2654 bool detect_unnamed_bitfields = true;
2655
2656 if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)
2657 detect_unnamed_bitfields = die.GetCU()->Supports_unnamed_objc_bitfields ();
2658
2659 if (detect_unnamed_bitfields)
2660 {
2661 BitfieldInfo anon_field_info;
2662
2663 if ((this_field_info.bit_offset % character_width) != 0) // not char aligned
2664 {
2665 uint64_t last_field_end = 0;
2666
2667 if (last_field_info.IsValid())
2668 last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
2669
2670 if (this_field_info.bit_offset != last_field_end)
2671 {
2672 if (((last_field_end % character_width) == 0) || // case 1
2673 (this_field_info.bit_offset - last_field_end >= word_width)) // case 3
2674 {
2675 anon_field_info.bit_size = this_field_info.bit_offset % character_width;
2676 anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size;
2677 }
2678 else // case 2
2679 {
2680 anon_field_info.bit_size = this_field_info.bit_offset - last_field_end;
2681 anon_field_info.bit_offset = last_field_end;
2682 }
2683 }
2684 }
2685
2686 if (anon_field_info.IsValid())
2687 {
2688 clang::FieldDecl *unnamed_bitfield_decl =
2689 ClangASTContext::AddFieldToRecordType (class_clang_type,
2690 NULL,
2691 m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
2692 accessibility,
2693 anon_field_info.bit_size);
2694
2695 layout_info.field_offsets.insert(
2696 std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
2697 }
2698 }
2699 last_field_info = this_field_info;
2700 }
2701 else
2702 {
2703 last_field_info.Clear();
2704 }
2705
2706 CompilerType member_clang_type = member_type->GetLayoutCompilerType ();
2707
2708 {
2709 // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
2710 // If the current field is at the end of the structure, then there is definitely no room for extra
2711 // elements and we override the type to array[0].
2712
2713 CompilerType member_array_element_type;
2714 uint64_t member_array_size;
2715 bool member_array_is_incomplete;
2716
2717 if (member_clang_type.IsArrayType(&member_array_element_type,
2718 &member_array_size,
2719 &member_array_is_incomplete) &&
2720 !member_array_is_incomplete)
2721 {
2722 uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);
2723
2724 if (member_byte_offset >= parent_byte_size)
2725 {
2726 if (member_array_size != 1)
2727 {
2728 module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64,
2729 die.GetID(),
2730 name,
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002731 encoding_form.Reference(),
Greg Clayton261ac3f2015-08-28 01:01:03 +00002732 parent_die.GetID());
2733 }
2734
2735 member_clang_type = m_ast.CreateArrayType(member_array_element_type, 0, false);
2736 }
2737 }
2738 }
2739
2740 field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type,
2741 name,
2742 member_clang_type,
2743 accessibility,
2744 bit_size);
2745
2746 m_ast.SetMetadataAsUserID (field_decl, die.GetID());
2747
2748 layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset));
2749 }
2750 else
2751 {
2752 if (name)
2753 module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
2754 die.GetID(),
2755 name,
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002756 encoding_form.Reference());
Greg Clayton261ac3f2015-08-28 01:01:03 +00002757 else
2758 module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
2759 die.GetID(),
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002760 encoding_form.Reference());
Greg Clayton261ac3f2015-08-28 01:01:03 +00002761 }
2762 }
2763
2764 if (prop_name != NULL && member_type)
2765 {
2766 clang::ObjCIvarDecl *ivar_decl = NULL;
2767
2768 if (field_decl)
2769 {
2770 ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
2771 assert (ivar_decl != NULL);
2772 }
2773
2774 ClangASTMetadata metadata;
2775 metadata.SetUserID (die.GetID());
2776 delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type,
2777 prop_name,
2778 member_type->GetLayoutCompilerType (),
2779 ivar_decl,
2780 prop_setter_name,
2781 prop_getter_name,
2782 prop_attributes,
2783 &metadata));
2784
2785 if (ivar_decl)
2786 m_ast.SetMetadataAsUserID (ivar_decl, die.GetID());
2787 }
2788 }
2789 }
2790 ++member_idx;
2791 }
2792 break;
2793
2794 case DW_TAG_subprogram:
2795 // Let the type parsing code handle this one for us.
2796 member_function_dies.Append (die);
2797 break;
2798
2799 case DW_TAG_inheritance:
2800 {
2801 is_a_class = true;
2802 if (default_accessibility == eAccessNone)
2803 default_accessibility = eAccessPrivate;
2804 // TODO: implement DW_TAG_inheritance type parsing
2805 DWARFAttributes attributes;
2806 const size_t num_attributes = die.GetAttributes (attributes);
2807 if (num_attributes > 0)
2808 {
2809 Declaration decl;
2810 DWARFExpression location(die.GetCU());
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002811 DWARFFormValue encoding_form;
Greg Clayton261ac3f2015-08-28 01:01:03 +00002812 AccessType accessibility = default_accessibility;
2813 bool is_virtual = false;
2814 bool is_base_of_class = true;
2815 off_t member_byte_offset = 0;
2816 uint32_t i;
2817 for (i=0; i<num_attributes; ++i)
2818 {
2819 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2820 DWARFFormValue form_value;
2821 if (attributes.ExtractFormValueAtIndex(i, form_value))
2822 {
2823 switch (attr)
2824 {
2825 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2826 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2827 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002828 case DW_AT_type: encoding_form = form_value; break;
Greg Clayton261ac3f2015-08-28 01:01:03 +00002829 case DW_AT_data_member_location:
2830 if (form_value.BlockData())
2831 {
2832 Value initialValue(0);
2833 Value memberOffset(0);
2834 const DWARFDataExtractor& debug_info_data = die.GetDWARF()->get_debug_info_data();
2835 uint32_t block_length = form_value.Unsigned();
2836 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
2837 if (DWARFExpression::Evaluate (NULL,
2838 NULL,
2839 NULL,
2840 NULL,
2841 module_sp,
2842 debug_info_data,
2843 die.GetCU(),
2844 block_offset,
2845 block_length,
2846 eRegisterKindDWARF,
2847 &initialValue,
2848 memberOffset,
2849 NULL))
2850 {
2851 member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
2852 }
2853 }
2854 else
2855 {
2856 // With DWARF 3 and later, if the value is an integer constant,
2857 // this form value is the offset in bytes from the beginning
2858 // of the containing entity.
2859 member_byte_offset = form_value.Unsigned();
2860 }
2861 break;
2862
2863 case DW_AT_accessibility:
2864 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2865 break;
2866
2867 case DW_AT_virtuality:
2868 is_virtual = form_value.Boolean();
2869 break;
2870
2871 case DW_AT_sibling:
2872 break;
2873
2874 default:
2875 break;
2876 }
2877 }
2878 }
2879
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002880 Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00002881 if (base_class_type == NULL)
2882 {
2883 module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message",
2884 die.GetOffset(),
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002885 encoding_form.Reference(),
Greg Clayton261ac3f2015-08-28 01:01:03 +00002886 parent_die.GetOffset());
2887 break;
2888 }
2889
2890 CompilerType base_class_clang_type = base_class_type->GetFullCompilerType ();
2891 assert (base_class_clang_type);
2892 if (class_language == eLanguageTypeObjC)
2893 {
2894 ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);
2895 }
2896 else
2897 {
2898 base_classes.push_back (ast->CreateBaseClassSpecifier (base_class_clang_type.GetOpaqueQualType(),
2899 accessibility,
2900 is_virtual,
2901 is_base_of_class));
2902
2903 if (is_virtual)
2904 {
2905 // Do not specify any offset for virtual inheritance. The DWARF produced by clang doesn't
2906 // give us a constant offset, but gives us a DWARF expressions that requires an actual object
2907 // in memory. the DW_AT_data_member_location for a virtual base class looks like:
2908 // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, DW_OP_plus )
2909 // Given this, there is really no valid response we can give to clang for virtual base
2910 // class offsets, and this should eventually be removed from LayoutRecordType() in the external
2911 // AST source in clang.
2912 }
2913 else
2914 {
2915 layout_info.base_offsets.insert(
2916 std::make_pair(ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()),
2917 clang::CharUnits::fromQuantity(member_byte_offset)));
2918 }
2919 }
2920 }
2921 }
2922 break;
2923
2924 default:
2925 break;
2926 }
2927 }
2928
2929 return count;
2930}
2931
2932
2933size_t
2934DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc,
2935 clang::DeclContext *containing_decl_ctx,
2936 const DWARFDIE &parent_die,
2937 bool skip_artificial,
2938 bool &is_static,
2939 bool &is_variadic,
2940 std::vector<CompilerType>& function_param_types,
2941 std::vector<clang::ParmVarDecl*>& function_param_decls,
2942 unsigned &type_quals)
2943{
2944 if (!parent_die)
2945 return 0;
2946
2947 size_t arg_idx = 0;
2948 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
2949 {
2950 const dw_tag_t tag = die.Tag();
2951 switch (tag)
2952 {
2953 case DW_TAG_formal_parameter:
2954 {
2955 DWARFAttributes attributes;
2956 const size_t num_attributes = die.GetAttributes(attributes);
2957 if (num_attributes > 0)
2958 {
2959 const char *name = NULL;
2960 Declaration decl;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002961 DWARFFormValue param_type_die_form;
Greg Clayton261ac3f2015-08-28 01:01:03 +00002962 bool is_artificial = false;
2963 // one of None, Auto, Register, Extern, Static, PrivateExtern
2964
2965 clang::StorageClass storage = clang::SC_None;
2966 uint32_t i;
2967 for (i=0; i<num_attributes; ++i)
2968 {
2969 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2970 DWARFFormValue form_value;
2971 if (attributes.ExtractFormValueAtIndex(i, form_value))
2972 {
2973 switch (attr)
2974 {
2975 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2976 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2977 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2978 case DW_AT_name: name = form_value.AsCString();
2979 break;
Tamas Berghammereb882fc2015-09-09 10:20:48 +00002980 case DW_AT_type: param_type_die_form = form_value; break;
Greg Clayton261ac3f2015-08-28 01:01:03 +00002981 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
2982 case DW_AT_location:
2983 // if (form_value.BlockData())
2984 // {
2985 // const DWARFDataExtractor& debug_info_data = debug_info();
2986 // uint32_t block_length = form_value.Unsigned();
2987 // DWARFDataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2988 // }
2989 // else
2990 // {
2991 // }
2992 // break;
2993 case DW_AT_const_value:
2994 case DW_AT_default_value:
2995 case DW_AT_description:
2996 case DW_AT_endianity:
2997 case DW_AT_is_optional:
2998 case DW_AT_segment:
2999 case DW_AT_variable_parameter:
3000 default:
3001 case DW_AT_abstract_origin:
3002 case DW_AT_sibling:
3003 break;
3004 }
3005 }
3006 }
3007
3008 bool skip = false;
3009 if (skip_artificial)
3010 {
3011 if (is_artificial)
3012 {
3013 // In order to determine if a C++ member function is
3014 // "const" we have to look at the const-ness of "this"...
3015 // Ugly, but that
3016 if (arg_idx == 0)
3017 {
3018 if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
3019 {
3020 // Often times compilers omit the "this" name for the
3021 // specification DIEs, so we can't rely upon the name
3022 // being in the formal parameter DIE...
3023 if (name == NULL || ::strcmp(name, "this")==0)
3024 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003025 Type *this_type = die.ResolveTypeUID (DIERef(param_type_die_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00003026 if (this_type)
3027 {
3028 uint32_t encoding_mask = this_type->GetEncodingMask();
3029 if (encoding_mask & Type::eEncodingIsPointerUID)
3030 {
3031 is_static = false;
3032
3033 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
3034 type_quals |= clang::Qualifiers::Const;
3035 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
3036 type_quals |= clang::Qualifiers::Volatile;
3037 }
3038 }
3039 }
3040 }
3041 }
3042 skip = true;
3043 }
3044 else
3045 {
3046
3047 // HACK: Objective C formal parameters "self" and "_cmd"
3048 // are not marked as artificial in the DWARF...
3049 CompileUnit *comp_unit = die.GetLLDBCompileUnit();
3050 if (comp_unit)
3051 {
3052 switch (comp_unit->GetLanguage())
3053 {
3054 case eLanguageTypeObjC:
3055 case eLanguageTypeObjC_plus_plus:
3056 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
3057 skip = true;
3058 break;
3059 default:
3060 break;
3061 }
3062 }
3063 }
3064 }
3065
3066 if (!skip)
3067 {
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003068 Type *type = die.ResolveTypeUID(DIERef(param_type_die_form).GetUID());
Greg Clayton261ac3f2015-08-28 01:01:03 +00003069 if (type)
3070 {
3071 function_param_types.push_back (type->GetForwardCompilerType ());
3072
3073 clang::ParmVarDecl *param_var_decl = m_ast.CreateParameterDeclaration (name,
3074 type->GetForwardCompilerType (),
3075 storage);
3076 assert(param_var_decl);
3077 function_param_decls.push_back(param_var_decl);
3078
3079 m_ast.SetMetadataAsUserID (param_var_decl, die.GetID());
3080 }
3081 }
3082 }
3083 arg_idx++;
3084 }
3085 break;
3086
3087 case DW_TAG_unspecified_parameters:
3088 is_variadic = true;
3089 break;
3090
3091 case DW_TAG_template_type_parameter:
3092 case DW_TAG_template_value_parameter:
3093 // The one caller of this was never using the template_param_infos,
3094 // and the local variable was taking up a large amount of stack space
3095 // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
3096 // the template params back, we can add them back.
3097 // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
3098 break;
3099
3100 default:
3101 break;
3102 }
3103 }
3104 return arg_idx;
3105}
3106
3107void
3108DWARFASTParserClang::ParseChildArrayInfo (const SymbolContext& sc,
3109 const DWARFDIE &parent_die,
3110 int64_t& first_index,
3111 std::vector<uint64_t>& element_orders,
3112 uint32_t& byte_stride,
3113 uint32_t& bit_stride)
3114{
3115 if (!parent_die)
3116 return;
3117
3118 for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling())
3119 {
3120 const dw_tag_t tag = die.Tag();
3121 switch (tag)
3122 {
3123 case DW_TAG_subrange_type:
3124 {
3125 DWARFAttributes attributes;
3126 const size_t num_child_attributes = die.GetAttributes(attributes);
3127 if (num_child_attributes > 0)
3128 {
3129 uint64_t num_elements = 0;
3130 uint64_t lower_bound = 0;
3131 uint64_t upper_bound = 0;
3132 bool upper_bound_valid = false;
3133 uint32_t i;
3134 for (i=0; i<num_child_attributes; ++i)
3135 {
3136 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3137 DWARFFormValue form_value;
3138 if (attributes.ExtractFormValueAtIndex(i, form_value))
3139 {
3140 switch (attr)
3141 {
3142 case DW_AT_name:
3143 break;
3144
3145 case DW_AT_count:
3146 num_elements = form_value.Unsigned();
3147 break;
3148
3149 case DW_AT_bit_stride:
3150 bit_stride = form_value.Unsigned();
3151 break;
3152
3153 case DW_AT_byte_stride:
3154 byte_stride = form_value.Unsigned();
3155 break;
3156
3157 case DW_AT_lower_bound:
3158 lower_bound = form_value.Unsigned();
3159 break;
3160
3161 case DW_AT_upper_bound:
3162 upper_bound_valid = true;
3163 upper_bound = form_value.Unsigned();
3164 break;
3165
3166 default:
3167 case DW_AT_abstract_origin:
3168 case DW_AT_accessibility:
3169 case DW_AT_allocated:
3170 case DW_AT_associated:
3171 case DW_AT_data_location:
3172 case DW_AT_declaration:
3173 case DW_AT_description:
3174 case DW_AT_sibling:
3175 case DW_AT_threads_scaled:
3176 case DW_AT_type:
3177 case DW_AT_visibility:
3178 break;
3179 }
3180 }
3181 }
3182
3183 if (num_elements == 0)
3184 {
3185 if (upper_bound_valid && upper_bound >= lower_bound)
3186 num_elements = upper_bound - lower_bound + 1;
3187 }
3188
3189 element_orders.push_back (num_elements);
3190 }
3191 }
3192 break;
3193 }
3194 }
3195}
3196
Paul Hermand628cbb2015-09-15 23:44:17 +00003197Type *
3198DWARFASTParserClang::GetTypeForDIE (const DWARFDIE &die)
3199{
3200 if (die)
3201 {
3202 SymbolFileDWARF *dwarf = die.GetDWARF();
3203 DWARFAttributes attributes;
3204 const size_t num_attributes = die.GetAttributes(attributes);
3205 if (num_attributes > 0)
3206 {
3207 DWARFFormValue type_die_form;
3208 for (size_t i = 0; i < num_attributes; ++i)
3209 {
3210 dw_attr_t attr = attributes.AttributeAtIndex(i);
3211 DWARFFormValue form_value;
3212
3213 if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value))
3214 return dwarf->ResolveTypeUID(DIERef(form_value).GetUID());
3215 }
3216 }
3217 }
3218
3219 return nullptr;
3220}
3221
3222clang::Decl *
3223DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
3224{
3225 if (!die)
3226 return nullptr;
3227
Paul Hermanf6681b42015-09-17 19:32:02 +00003228 switch (die.Tag())
3229 {
3230 case DW_TAG_variable:
3231 case DW_TAG_constant:
3232 case DW_TAG_formal_parameter:
3233 case DW_TAG_imported_declaration:
3234 case DW_TAG_imported_module:
3235 break;
3236 default:
3237 return nullptr;
3238 }
Paul Hermanea188fc2015-09-16 18:48:30 +00003239
Paul Hermanf6681b42015-09-17 19:32:02 +00003240 DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE());
3241 if (cache_pos != m_die_to_decl.end())
3242 return cache_pos->second;
3243
3244 if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification))
3245 {
3246 clang::Decl *decl = GetClangDeclForDIE(spec_die);
3247 m_die_to_decl[die.GetDIE()] = decl;
3248 m_decl_to_die[decl].insert(die.GetDIE());
Paul Hermand628cbb2015-09-15 23:44:17 +00003249 return decl;
Paul Hermanf6681b42015-09-17 19:32:02 +00003250 }
Paul Hermand628cbb2015-09-15 23:44:17 +00003251
Paul Hermanf6681b42015-09-17 19:32:02 +00003252 clang::Decl *decl = nullptr;
Paul Hermand628cbb2015-09-15 23:44:17 +00003253 switch (die.Tag())
3254 {
3255 case DW_TAG_variable:
3256 case DW_TAG_constant:
3257 case DW_TAG_formal_parameter:
3258 {
3259 SymbolFileDWARF *dwarf = die.GetDWARF();
3260 Type *type = GetTypeForDIE(die);
3261 const char *name = die.GetName();
3262 clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
3263 decl = m_ast.CreateVariableDeclaration(
3264 decl_context,
3265 name,
3266 ClangASTContext::GetQualType(type->GetForwardCompilerType()));
3267 break;
3268 }
3269 case DW_TAG_imported_declaration:
3270 {
3271 SymbolFileDWARF *dwarf = die.GetDWARF();
3272 lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
3273
3274 if (dwarf->UserIDMatches(imported_uid))
3275 {
3276 CompilerDecl imported_decl = dwarf->GetDeclForUID(imported_uid);
3277 if (imported_decl)
3278 {
3279 clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
3280 if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast<clang::NamedDecl>((clang::Decl *)imported_decl.GetOpaqueDecl()))
3281 decl = m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl);
3282 }
3283 }
3284 break;
3285 }
3286 case DW_TAG_imported_module:
3287 {
3288 SymbolFileDWARF *dwarf = die.GetDWARF();
3289 lldb::user_id_t imported_uid = die.GetAttributeValueAsReference(DW_AT_import, DW_INVALID_OFFSET);
3290
3291 if (dwarf->UserIDMatches(imported_uid))
3292 {
3293 CompilerDeclContext imported_decl = dwarf->GetDeclContextForUID(imported_uid);
3294 if (imported_decl)
3295 {
3296 clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
Paul Hermanea188fc2015-09-16 18:48:30 +00003297 if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl))
3298 decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
Paul Hermand628cbb2015-09-15 23:44:17 +00003299 }
3300 }
3301 break;
3302 }
3303 default:
3304 break;
3305 }
3306
3307 m_die_to_decl[die.GetDIE()] = decl;
3308 m_decl_to_die[decl].insert(die.GetDIE());
3309
3310 return decl;
3311}
3312
Greg Clayton261ac3f2015-08-28 01:01:03 +00003313clang::DeclContext *
3314DWARFASTParserClang::GetClangDeclContextForDIE (const DWARFDIE &die)
3315{
3316 if (die)
3317 {
3318 clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE (die);
3319 if (decl_ctx)
3320 return decl_ctx;
3321
3322 bool try_parsing_type = true;
3323 switch (die.Tag())
3324 {
3325 case DW_TAG_compile_unit:
3326 decl_ctx = m_ast.GetTranslationUnitDecl();
3327 try_parsing_type = false;
3328 break;
3329
3330 case DW_TAG_namespace:
3331 decl_ctx = ResolveNamespaceDIE (die);
3332 try_parsing_type = false;
3333 break;
3334
Paul Hermand628cbb2015-09-15 23:44:17 +00003335 case DW_TAG_lexical_block:
3336 decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die);
3337 try_parsing_type = false;
3338 break;
3339
Greg Clayton261ac3f2015-08-28 01:01:03 +00003340 default:
3341 break;
3342 }
3343
3344 if (decl_ctx == nullptr && try_parsing_type)
3345 {
3346 Type* type = die.GetDWARF()->ResolveType (die);
3347 if (type)
3348 decl_ctx = GetCachedClangDeclContextForDIE (die);
3349 }
3350
3351 if (decl_ctx)
3352 {
3353 LinkDeclContextToDIE (decl_ctx, die);
3354 return decl_ctx;
3355 }
3356 }
3357 return nullptr;
3358}
3359
Paul Hermand628cbb2015-09-15 23:44:17 +00003360clang::BlockDecl *
3361DWARFASTParserClang::ResolveBlockDIE (const DWARFDIE &die)
3362{
3363 if (die && die.Tag() == DW_TAG_lexical_block)
3364 {
3365 clang::BlockDecl *decl = llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
3366
3367 if (!decl)
3368 {
3369 DWARFDIE decl_context_die;
3370 clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die);
3371 decl = m_ast.CreateBlockDeclaration(decl_context);
3372
3373 if (decl)
3374 LinkDeclContextToDIE((clang::DeclContext *)decl, die);
3375 }
3376
3377 return decl;
3378 }
3379 return nullptr;
3380}
3381
Greg Clayton261ac3f2015-08-28 01:01:03 +00003382clang::NamespaceDecl *
3383DWARFASTParserClang::ResolveNamespaceDIE (const DWARFDIE &die)
3384{
3385 if (die && die.Tag() == DW_TAG_namespace)
3386 {
3387 // See if we already parsed this namespace DIE and associated it with a
3388 // uniqued namespace declaration
3389 clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);
3390 if (namespace_decl)
3391 return namespace_decl;
3392 else
3393 {
3394 const char *namespace_name = die.GetName();
3395 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, nullptr);
3396 namespace_decl = m_ast.GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
3397 Log *log = nullptr;// (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
3398 if (log)
3399 {
3400 SymbolFileDWARF *dwarf = die.GetDWARF();
3401 if (namespace_name)
3402 {
3403 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
3404 "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
3405 static_cast<void*>(m_ast.getASTContext()),
3406 die.GetID(),
3407 namespace_name,
3408 static_cast<void*>(namespace_decl),
3409 static_cast<void*>(namespace_decl->getOriginalNamespace()));
3410 }
3411 else
3412 {
3413 dwarf->GetObjectFile()->GetModule()->LogMessage (log,
3414 "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
3415 static_cast<void*>(m_ast.getASTContext()),
3416 die.GetID(),
3417 static_cast<void*>(namespace_decl),
3418 static_cast<void*>(namespace_decl->getOriginalNamespace()));
3419 }
3420 }
3421
3422 if (namespace_decl)
3423 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
3424 return namespace_decl;
3425 }
3426 }
3427 return nullptr;
3428}
3429
3430clang::DeclContext *
3431DWARFASTParserClang::GetClangDeclContextContainingDIE (const DWARFDIE &die,
3432 DWARFDIE *decl_ctx_die_copy)
3433{
3434 SymbolFileDWARF *dwarf = die.GetDWARF();
3435
3436 DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE (die);
3437
3438 if (decl_ctx_die_copy)
3439 *decl_ctx_die_copy = decl_ctx_die;
3440
3441 if (decl_ctx_die)
3442 {
3443 clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE (decl_ctx_die);
3444 if (clang_decl_ctx)
3445 return clang_decl_ctx;
3446 }
3447 return m_ast.GetTranslationUnitDecl();
3448}
3449
Greg Clayton261ac3f2015-08-28 01:01:03 +00003450clang::DeclContext *
3451DWARFASTParserClang::GetCachedClangDeclContextForDIE (const DWARFDIE &die)
3452{
3453 if (die)
3454 {
3455 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE());
3456 if (pos != m_die_to_decl_ctx.end())
3457 return pos->second;
3458 }
3459 return nullptr;
3460}
3461
3462void
3463DWARFASTParserClang::LinkDeclContextToDIE (clang::DeclContext *decl_ctx, const DWARFDIE &die)
3464{
3465 m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
3466 // There can be many DIEs for a single decl context
Paul Hermanea188fc2015-09-16 18:48:30 +00003467 //m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
3468 m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
Greg Clayton261ac3f2015-08-28 01:01:03 +00003469}
3470
3471bool
3472DWARFASTParserClang::CopyUniqueClassMethodTypes (const DWARFDIE &src_class_die,
3473 const DWARFDIE &dst_class_die,
3474 lldb_private::Type *class_type,
3475 DWARFDIECollection &failures)
3476{
3477 if (!class_type || !src_class_die || !dst_class_die)
3478 return false;
3479 if (src_class_die.Tag() != dst_class_die.Tag())
3480 return false;
3481
3482 // We need to complete the class type so we can get all of the method types
3483 // parsed so we can then unique those types to their equivalent counterparts
3484 // in "dst_cu" and "dst_class_die"
3485 class_type->GetFullCompilerType ();
3486
3487 DWARFDIE src_die;
3488 DWARFDIE dst_die;
3489 UniqueCStringMap<DWARFDIE> src_name_to_die;
3490 UniqueCStringMap<DWARFDIE> dst_name_to_die;
3491 UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
3492 UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
3493 for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); src_die = src_die.GetSibling())
3494 {
3495 if (src_die.Tag() == DW_TAG_subprogram)
3496 {
3497 // Make sure this is a declaration and not a concrete instance by looking
3498 // for DW_AT_declaration set to 1. Sometimes concrete function instances
3499 // are placed inside the class definitions and shouldn't be included in
3500 // the list of things are are tracking here.
3501 if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1)
3502 {
3503 const char *src_name = src_die.GetMangledName ();
3504 if (src_name)
3505 {
3506 ConstString src_const_name(src_name);
3507 if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
3508 src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
3509 else
3510 src_name_to_die.Append(src_const_name.GetCString(), src_die);
3511 }
3512 }
3513 }
3514 }
3515 for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); dst_die = dst_die.GetSibling())
3516 {
3517 if (dst_die.Tag() == DW_TAG_subprogram)
3518 {
3519 // Make sure this is a declaration and not a concrete instance by looking
3520 // for DW_AT_declaration set to 1. Sometimes concrete function instances
3521 // are placed inside the class definitions and shouldn't be included in
3522 // the list of things are are tracking here.
3523 if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1)
3524 {
3525 const char *dst_name = dst_die.GetMangledName ();
3526 if (dst_name)
3527 {
3528 ConstString dst_const_name(dst_name);
3529 if ( dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
3530 dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die);
3531 else
3532 dst_name_to_die.Append(dst_const_name.GetCString(), dst_die);
3533 }
3534 }
3535 }
3536 }
3537 const uint32_t src_size = src_name_to_die.GetSize ();
3538 const uint32_t dst_size = dst_name_to_die.GetSize ();
3539 Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
3540
3541 // Is everything kosher so we can go through the members at top speed?
3542 bool fast_path = true;
3543
3544 if (src_size != dst_size)
3545 {
3546 if (src_size != 0 && dst_size != 0)
3547 {
3548 if (log)
3549 log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
3550 src_class_die.GetOffset(),
3551 dst_class_die.GetOffset(),
3552 src_size,
3553 dst_size);
3554 }
3555
3556 fast_path = false;
3557 }
3558
3559 uint32_t idx;
3560
3561 if (fast_path)
3562 {
3563 for (idx = 0; idx < src_size; ++idx)
3564 {
3565 src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
3566 dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
3567
3568 if (src_die.Tag() != dst_die.Tag())
3569 {
3570 if (log)
3571 log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
3572 src_class_die.GetOffset(),
3573 dst_class_die.GetOffset(),
3574 src_die.GetOffset(),
3575 src_die.GetTagAsCString(),
3576 dst_die.GetOffset(),
3577 dst_die.GetTagAsCString());
3578 fast_path = false;
3579 }
3580
3581 const char *src_name = src_die.GetMangledName ();
3582 const char *dst_name = dst_die.GetMangledName ();
3583
3584 // Make sure the names match
3585 if (src_name == dst_name || (strcmp (src_name, dst_name) == 0))
3586 continue;
3587
3588 if (log)
3589 log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
3590 src_class_die.GetOffset(),
3591 dst_class_die.GetOffset(),
3592 src_die.GetOffset(),
3593 src_name,
3594 dst_die.GetOffset(),
3595 dst_name);
3596
3597 fast_path = false;
3598 }
3599 }
3600
3601 DWARFASTParserClang *src_dwarf_ast_parser = (DWARFASTParserClang *)src_die.GetDWARFParser();
3602 DWARFASTParserClang *dst_dwarf_ast_parser = (DWARFASTParserClang *)dst_die.GetDWARFParser();
3603
3604 // Now do the work of linking the DeclContexts and Types.
3605 if (fast_path)
3606 {
3607 // We can do this quickly. Just run across the tables index-for-index since
3608 // we know each node has matching names and tags.
3609 for (idx = 0; idx < src_size; ++idx)
3610 {
3611 src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
3612 dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
3613
3614 clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
3615 if (src_decl_ctx)
3616 {
3617 if (log)
3618 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
3619 static_cast<void*>(src_decl_ctx),
3620 src_die.GetOffset(), dst_die.GetOffset());
3621 dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die);
3622 }
3623 else
3624 {
3625 if (log)
3626 log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found",
3627 src_die.GetOffset(), dst_die.GetOffset());
3628 }
3629
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003630 Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
Greg Clayton261ac3f2015-08-28 01:01:03 +00003631 if (src_child_type)
3632 {
3633 if (log)
3634 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
3635 static_cast<void*>(src_child_type),
3636 src_child_type->GetID(),
3637 src_die.GetOffset(), dst_die.GetOffset());
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003638 dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
Greg Clayton261ac3f2015-08-28 01:01:03 +00003639 }
3640 else
3641 {
3642 if (log)
3643 log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
3644 }
3645 }
3646 }
3647 else
3648 {
3649 // We must do this slowly. For each member of the destination, look
3650 // up a member in the source with the same name, check its tag, and
3651 // unique them if everything matches up. Report failures.
3652
3653 if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
3654 {
3655 src_name_to_die.Sort();
3656
3657 for (idx = 0; idx < dst_size; ++idx)
3658 {
3659 const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
3660 dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
3661 src_die = src_name_to_die.Find(dst_name, DWARFDIE());
3662
3663 if (src_die && (src_die.Tag() == dst_die.Tag()))
3664 {
3665 clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
3666 if (src_decl_ctx)
3667 {
3668 if (log)
3669 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
3670 static_cast<void*>(src_decl_ctx),
3671 src_die.GetOffset(),
3672 dst_die.GetOffset());
3673 dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die);
3674 }
3675 else
3676 {
3677 if (log)
3678 log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
3679 }
3680
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003681 Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
Greg Clayton261ac3f2015-08-28 01:01:03 +00003682 if (src_child_type)
3683 {
3684 if (log)
3685 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
3686 static_cast<void*>(src_child_type),
3687 src_child_type->GetID(),
3688 src_die.GetOffset(),
3689 dst_die.GetOffset());
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003690 dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
Greg Clayton261ac3f2015-08-28 01:01:03 +00003691 }
3692 else
3693 {
3694 if (log)
3695 log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
3696 }
3697 }
3698 else
3699 {
3700 if (log)
3701 log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die.GetOffset());
3702
3703 failures.Append(dst_die);
3704 }
3705 }
3706 }
3707 }
3708
3709 const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
3710 const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
3711
3712 if (src_size_artificial && dst_size_artificial)
3713 {
3714 dst_name_to_die_artificial.Sort();
3715
3716 for (idx = 0; idx < src_size_artificial; ++idx)
3717 {
3718 const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
3719 src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
3720 dst_die = dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE());
3721
3722 if (dst_die)
3723 {
3724 // Both classes have the artificial types, link them
3725 clang::DeclContext *src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
3726 if (src_decl_ctx)
3727 {
3728 if (log)
3729 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
3730 static_cast<void*>(src_decl_ctx),
3731 src_die.GetOffset(), dst_die.GetOffset());
3732 dst_dwarf_ast_parser->LinkDeclContextToDIE (src_decl_ctx, dst_die);
3733 }
3734 else
3735 {
3736 if (log)
3737 log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
3738 }
3739
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003740 Type *src_child_type = dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
Greg Clayton261ac3f2015-08-28 01:01:03 +00003741 if (src_child_type)
3742 {
3743 if (log)
3744 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
3745 static_cast<void*>(src_child_type),
3746 src_child_type->GetID(),
3747 src_die.GetOffset(), dst_die.GetOffset());
Tamas Berghammereb882fc2015-09-09 10:20:48 +00003748 dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
Greg Clayton261ac3f2015-08-28 01:01:03 +00003749 }
3750 else
3751 {
3752 if (log)
3753 log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die.GetOffset(), dst_die.GetOffset());
3754 }
3755 }
3756 }
3757 }
3758
3759 if (dst_size_artificial)
3760 {
3761 for (idx = 0; idx < dst_size_artificial; ++idx)
3762 {
3763 const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
3764 dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
3765 if (log)
3766 log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die.GetOffset(), dst_name_artificial);
3767
3768 failures.Append(dst_die);
3769 }
3770 }
3771
3772 return (failures.Size() != 0);
3773}
3774
3775
3776bool
3777DWARFASTParserClang::LayoutRecordType(const clang::RecordDecl *record_decl,
3778 uint64_t &bit_size,
3779 uint64_t &alignment,
3780 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
3781 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
3782 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
3783{
3784 RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
3785 bool success = false;
3786 base_offsets.clear();
3787 vbase_offsets.clear();
3788 if (pos != m_record_decl_to_layout_map.end())
3789 {
3790 bit_size = pos->second.bit_size;
3791 alignment = pos->second.alignment;
3792 field_offsets.swap(pos->second.field_offsets);
3793 base_offsets.swap (pos->second.base_offsets);
3794 vbase_offsets.swap (pos->second.vbase_offsets);
3795 m_record_decl_to_layout_map.erase(pos);
3796 success = true;
3797 }
3798 else
3799 {
3800 bit_size = 0;
3801 alignment = 0;
3802 field_offsets.clear();
3803 }
3804 return success;
3805}