blob: b18628f7b19fb6078b8182de11009ff80a0d2e3b [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolFileDWARF.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 "SymbolFileDWARF.h"
11
12// Other libraries and framework includes
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
Jim Inghame3ae82a2011-11-12 01:36:43 +000017#include "clang/AST/DeclObjC.h"
Greg Clayton3c2e3ae2012-02-06 06:42:51 +000018#include "clang/AST/DeclTemplate.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "clang/Basic/Builtins.h"
20#include "clang/Basic/IdentifierTable.h"
21#include "clang/Basic/LangOptions.h"
22#include "clang/Basic/SourceManager.h"
23#include "clang/Basic/TargetInfo.h"
24#include "clang/Basic/Specifiers.h"
Greg Clayton7fedea22010-11-16 02:10:54 +000025#include "clang/Sema/DeclSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
Sean Callanancc427fa2011-07-30 02:42:06 +000027#include "llvm/Support/Casting.h"
28
Robert Flackeb83fab2015-05-15 18:59:59 +000029#include "lldb/Core/ArchSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Core/Module.h"
Sean Callananf0c5aeb2015-04-20 16:31:29 +000031#include "lldb/Core/ModuleList.h"
32#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Core/PluginManager.h"
34#include "lldb/Core/RegularExpression.h"
35#include "lldb/Core/Scalar.h"
36#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000037#include "lldb/Core/StreamFile.h"
Jim Ingham318c9f22011-08-26 19:44:13 +000038#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Core/Timer.h"
40#include "lldb/Core/Value.h"
41
Sean Callananf0c5aeb2015-04-20 16:31:29 +000042#include "lldb/Expression/ClangModulesDeclVendor.h"
43
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +000044#include "lldb/Host/FileSystem.h"
Greg Clayton20568dd2011-10-13 23:13:20 +000045#include "lldb/Host/Host.h"
46
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000048#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049#include "lldb/Symbol/CompileUnit.h"
50#include "lldb/Symbol/LineTable.h"
51#include "lldb/Symbol/ObjectFile.h"
52#include "lldb/Symbol/SymbolVendor.h"
53#include "lldb/Symbol/VariableList.h"
54
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000055#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham4cda6e02011-10-07 22:23:45 +000056#include "lldb/Target/CPPLanguageRuntime.h"
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000057
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058#include "DWARFCompileUnit.h"
59#include "DWARFDebugAbbrev.h"
60#include "DWARFDebugAranges.h"
61#include "DWARFDebugInfo.h"
62#include "DWARFDebugInfoEntry.h"
63#include "DWARFDebugLine.h"
64#include "DWARFDebugPubnames.h"
65#include "DWARFDebugRanges.h"
Greg Claytona8022fa2012-04-24 21:22:41 +000066#include "DWARFDeclContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067#include "DWARFDIECollection.h"
68#include "DWARFFormValue.h"
69#include "DWARFLocationList.h"
70#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000071#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072
73#include <map>
74
Matthew Gardinere81df3b2014-08-26 06:57:23 +000075#include <ctype.h>
76#include <string.h>
77
Greg Clayton62742b12010-11-11 01:09:45 +000078//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000079
80#ifdef ENABLE_DEBUG_PRINTF
81#include <stdio.h>
Ed Mastea0191d12013-10-17 20:42:56 +000082#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
Greg Claytonc93237c2010-10-01 20:48:32 +000083#else
84#define DEBUG_PRINTF(fmt, ...)
85#endif
86
Greg Clayton594e5ed2010-09-27 21:07:38 +000087#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088
89using namespace lldb;
90using namespace lldb_private;
91
Greg Clayton219cf312012-03-30 00:51:13 +000092//static inline bool
93//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
94//{
95// switch (tag)
96// {
97// default:
98// break;
99// case DW_TAG_subprogram:
100// case DW_TAG_inlined_subroutine:
101// case DW_TAG_class_type:
102// case DW_TAG_structure_type:
103// case DW_TAG_union_type:
104// return true;
105// }
106// return false;
107//}
108//
Sean Callananc7fbf732010-08-06 00:32:49 +0000109static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +0000110DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111{
112 switch (dwarf_accessibility)
113 {
Sean Callananc7fbf732010-08-06 00:32:49 +0000114 case DW_ACCESS_public: return eAccessPublic;
115 case DW_ACCESS_private: return eAccessPrivate;
116 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +0000117 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118 }
Sean Callananc7fbf732010-08-06 00:32:49 +0000119 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000120}
121
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000122static const char*
123removeHostnameFromPathname(const char* path_from_dwarf)
124{
125 if (!path_from_dwarf || !path_from_dwarf[0])
126 {
127 return path_from_dwarf;
128 }
Enrico Granata99e5e222015-07-27 21:27:02 +0000129
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000130 const char *colon_pos = strchr(path_from_dwarf, ':');
Enrico Granata99e5e222015-07-27 21:27:02 +0000131 if (nullptr == colon_pos)
132 {
133 return path_from_dwarf;
134 }
135
136 const char *slash_pos = strchr(path_from_dwarf, '/');
137 if (slash_pos && (slash_pos < colon_pos))
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000138 {
139 return path_from_dwarf;
140 }
141
142 // check whether we have a windows path, and so the first character
143 // is a drive-letter not a hostname.
144 if (
145 colon_pos == path_from_dwarf + 1 &&
146 isalpha(*path_from_dwarf) &&
147 strlen(path_from_dwarf) > 2 &&
148 '\\' == path_from_dwarf[2])
149 {
150 return path_from_dwarf;
151 }
Enrico Granata99e5e222015-07-27 21:27:02 +0000152
Matthew Gardinere81df3b2014-08-26 06:57:23 +0000153 return colon_pos + 1;
154}
155
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000156// DW_AT_comp_dir can be overridden by setting compiler's PWD environment
157// variable - for example, set to "/proc/self/cwd" in order to cope with
158// distributed builds.
159static const char* comp_dir_symlinks[] = {"/proc/self/cwd"};
160
161static const char*
162resolveCompDir(const char* path_from_dwarf)
163{
164 if (!path_from_dwarf)
165 return nullptr;
166
167 // DWARF2/3 suggests the form hostname:pathname for compilation directory.
168 // Remove the host part if present.
169 const char* local_path = removeHostnameFromPathname(path_from_dwarf);
170 if (!local_path)
171 return nullptr;
172
173 bool is_symlink = false;
174 for (unsigned long i = 0; i < sizeof(comp_dir_symlinks)/sizeof(comp_dir_symlinks[0]) && !is_symlink; ++i)
175 is_symlink = !strcmp(comp_dir_symlinks[i], local_path);
176
177 if (!is_symlink)
178 return local_path;
179
180 const FileSpec local_path_spec(local_path, true);
181 if (!local_path_spec.IsSymbolicLink())
182 return local_path;
183
184 FileSpec resolved_local_path_spec;
185 const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
186 if (error.Success())
187 return resolved_local_path_spec.GetCString();
188
189 return nullptr;
190}
191
192
Todd Fiala0a70a842014-05-28 16:43:26 +0000193#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
Greg Clayton1fba87112012-02-09 20:03:49 +0000194
195class DIEStack
196{
197public:
198
199 void Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
200 {
201 m_dies.push_back (DIEInfo(cu, die));
202 }
203
204
205 void LogDIEs (Log *log, SymbolFileDWARF *dwarf)
206 {
207 StreamString log_strm;
208 const size_t n = m_dies.size();
Daniel Malead01b2952012-11-29 21:49:15 +0000209 log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
Greg Clayton1fba87112012-02-09 20:03:49 +0000210 for (size_t i=0; i<n; i++)
211 {
212 DWARFCompileUnit *cu = m_dies[i].cu;
213 const DWARFDebugInfoEntry *die = m_dies[i].die;
214 std::string qualified_name;
215 die->GetQualifiedName(dwarf, cu, qualified_name);
Daniel Malead01b2952012-11-29 21:49:15 +0000216 log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n",
Greg Clayton43e0af02012-09-18 18:04:04 +0000217 (uint64_t)i,
Greg Clayton1fba87112012-02-09 20:03:49 +0000218 die->GetOffset(),
219 DW_TAG_value_to_name(die->Tag()),
220 qualified_name.c_str());
221 }
222 log->PutCString(log_strm.GetData());
223 }
224 void Pop ()
225 {
226 m_dies.pop_back();
227 }
228
229 class ScopedPopper
230 {
231 public:
232 ScopedPopper (DIEStack &die_stack) :
233 m_die_stack (die_stack),
234 m_valid (false)
235 {
236 }
237
238 void
239 Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
240 {
241 m_valid = true;
242 m_die_stack.Push (cu, die);
243 }
244
245 ~ScopedPopper ()
246 {
247 if (m_valid)
248 m_die_stack.Pop();
249 }
250
251
252
253 protected:
254 DIEStack &m_die_stack;
255 bool m_valid;
256 };
257
258protected:
259 struct DIEInfo {
260 DIEInfo (DWARFCompileUnit *c, const DWARFDebugInfoEntry *d) :
261 cu(c),
262 die(d)
263 {
264 }
265 DWARFCompileUnit *cu;
266 const DWARFDebugInfoEntry *die;
267 };
268 typedef std::vector<DIEInfo> Stack;
269 Stack m_dies;
270};
271#endif
272
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273void
274SymbolFileDWARF::Initialize()
275{
276 LogChannelDWARF::Initialize();
277 PluginManager::RegisterPlugin (GetPluginNameStatic(),
278 GetPluginDescriptionStatic(),
279 CreateInstance);
280}
281
282void
283SymbolFileDWARF::Terminate()
284{
285 PluginManager::UnregisterPlugin (CreateInstance);
286 LogChannelDWARF::Initialize();
287}
288
289
Greg Clayton57abc5d2013-05-10 21:47:16 +0000290lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291SymbolFileDWARF::GetPluginNameStatic()
292{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000293 static ConstString g_name("dwarf");
294 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295}
296
297const char *
298SymbolFileDWARF::GetPluginDescriptionStatic()
299{
300 return "DWARF and DWARF3 debug symbol file reader.";
301}
302
303
304SymbolFile*
305SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
306{
307 return new SymbolFileDWARF(obj_file);
308}
309
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000310TypeList *
311SymbolFileDWARF::GetTypeList ()
312{
Greg Clayton1f746072012-08-29 21:13:06 +0000313 if (GetDebugMapSymfile ())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000314 return m_debug_map_symfile->GetTypeList();
315 return m_obj_file->GetModule()->GetTypeList();
316
317}
Greg Claytonf02500c2013-06-18 22:51:05 +0000318void
319SymbolFileDWARF::GetTypes (DWARFCompileUnit* cu,
320 const DWARFDebugInfoEntry *die,
321 dw_offset_t min_die_offset,
322 dw_offset_t max_die_offset,
323 uint32_t type_mask,
324 TypeSet &type_set)
325{
326 if (cu)
327 {
328 if (die)
329 {
330 const dw_offset_t die_offset = die->GetOffset();
331
332 if (die_offset >= max_die_offset)
333 return;
334
335 if (die_offset >= min_die_offset)
336 {
337 const dw_tag_t tag = die->Tag();
338
339 bool add_type = false;
340
341 switch (tag)
342 {
343 case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
344 case DW_TAG_unspecified_type:
345 case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
346 case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
347 case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
348 case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
349 case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
350 case DW_TAG_subroutine_type:
351 case DW_TAG_subprogram:
352 case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
353 case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
354 case DW_TAG_rvalue_reference_type:
355 case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
356 case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
357 case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
358 }
359
360 if (add_type)
361 {
362 const bool assert_not_being_parsed = true;
363 Type *type = ResolveTypeUID (cu, die, assert_not_being_parsed);
364 if (type)
365 {
366 if (type_set.find(type) == type_set.end())
367 type_set.insert(type);
368 }
369 }
370 }
371
372 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild();
373 child_die != NULL;
374 child_die = child_die->GetSibling())
375 {
376 GetTypes (cu, child_die, min_die_offset, max_die_offset, type_mask, type_set);
377 }
378 }
379 }
380}
381
382size_t
383SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
384 uint32_t type_mask,
385 TypeList &type_list)
386
387{
388 TypeSet type_set;
389
390 CompileUnit *comp_unit = NULL;
391 DWARFCompileUnit* dwarf_cu = NULL;
392 if (sc_scope)
393 comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
394
395 if (comp_unit)
396 {
397 dwarf_cu = GetDWARFCompileUnit(comp_unit);
398 if (dwarf_cu == 0)
399 return 0;
400 GetTypes (dwarf_cu,
401 dwarf_cu->DIE(),
402 dwarf_cu->GetOffset(),
403 dwarf_cu->GetNextCompileUnitOffset(),
404 type_mask,
405 type_set);
406 }
407 else
408 {
409 DWARFDebugInfo* info = DebugInfo();
410 if (info)
411 {
412 const size_t num_cus = info->GetNumCompileUnits();
413 for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
414 {
415 dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
416 if (dwarf_cu)
417 {
418 GetTypes (dwarf_cu,
419 dwarf_cu->DIE(),
420 0,
421 UINT32_MAX,
422 type_mask,
423 type_set);
424 }
425 }
426 }
427 }
428// if (m_using_apple_tables)
429// {
430// DWARFMappedHash::MemoryTable *apple_types = m_apple_types_ap.get();
431// if (apple_types)
432// {
433// apple_types->ForEach([this, &type_set, apple_types, type_mask](const DWARFMappedHash::DIEInfoArray &die_info_array) -> bool {
434//
435// for (auto die_info: die_info_array)
436// {
437// bool add_type = TagMatchesTypeMask (type_mask, 0);
438// if (!add_type)
439// {
440// dw_tag_t tag = die_info.tag;
441// if (tag == 0)
442// {
443// const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtr(die_info.offset, NULL);
444// tag = die->Tag();
445// }
446// add_type = TagMatchesTypeMask (type_mask, tag);
447// }
448// if (add_type)
449// {
450// Type *type = ResolveTypeUID(die_info.offset);
451//
452// if (type_set.find(type) == type_set.end())
453// type_set.insert(type);
454// }
455// }
456// return true; // Keep iterating
457// });
458// }
459// }
460// else
461// {
462// if (!m_indexed)
463// Index ();
464//
465// m_type_index.ForEach([this, &type_set, type_mask](const char *name, uint32_t die_offset) -> bool {
466//
467// bool add_type = TagMatchesTypeMask (type_mask, 0);
468//
469// if (!add_type)
470// {
471// const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtr(die_offset, NULL);
472// if (die)
473// {
474// const dw_tag_t tag = die->Tag();
475// add_type = TagMatchesTypeMask (type_mask, tag);
476// }
477// }
478//
479// if (add_type)
480// {
481// Type *type = ResolveTypeUID(die_offset);
482//
483// if (type_set.find(type) == type_set.end())
484// type_set.insert(type);
485// }
486// return true; // Keep iterating
487// });
488// }
489
Greg Clayton57ee3062013-07-11 22:46:58 +0000490 std::set<ClangASTType> clang_type_set;
Greg Claytonf02500c2013-06-18 22:51:05 +0000491 size_t num_types_added = 0;
492 for (Type *type : type_set)
493 {
Greg Clayton57ee3062013-07-11 22:46:58 +0000494 ClangASTType clang_type = type->GetClangForwardType();
Greg Clayton0fc4f312013-06-20 01:23:18 +0000495 if (clang_type_set.find(clang_type) == clang_type_set.end())
496 {
497 clang_type_set.insert(clang_type);
498 type_list.Insert (type->shared_from_this());
499 ++num_types_added;
500 }
Greg Claytonf02500c2013-06-18 22:51:05 +0000501 }
502 return num_types_added;
503}
504
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000505
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000506//----------------------------------------------------------------------
507// Gets the first parent that is a lexical block, function or inlined
508// subroutine, or compile unit.
509//----------------------------------------------------------------------
510static const DWARFDebugInfoEntry *
511GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
512{
513 const DWARFDebugInfoEntry *die;
514 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
515 {
516 dw_tag_t tag = die->Tag();
517
518 switch (tag)
519 {
520 case DW_TAG_compile_unit:
521 case DW_TAG_subprogram:
522 case DW_TAG_inlined_subroutine:
523 case DW_TAG_lexical_block:
524 return die;
525 }
526 }
527 return NULL;
528}
529
530
Greg Clayton450e3f32010-10-12 02:24:53 +0000531SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
532 SymbolFile (objfile),
Greg Clayton81c22f62011-10-19 18:09:39 +0000533 UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
Greg Clayton1f746072012-08-29 21:13:06 +0000534 m_debug_map_module_wp (),
Greg Clayton450e3f32010-10-12 02:24:53 +0000535 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000536 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000537 m_flags(),
Greg Claytond4a2b372011-09-12 23:21:58 +0000538 m_data_debug_abbrev (),
539 m_data_debug_aranges (),
540 m_data_debug_frame (),
541 m_data_debug_info (),
542 m_data_debug_line (),
543 m_data_debug_loc (),
544 m_data_debug_ranges (),
545 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000546 m_data_apple_names (),
547 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000548 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000549 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550 m_info(),
551 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000552 m_apple_names_ap (),
553 m_apple_types_ap (),
554 m_apple_namespaces_ap (),
Greg Clayton5009f9d2011-10-27 17:55:14 +0000555 m_apple_objc_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000556 m_function_basename_index(),
557 m_function_fullname_index(),
558 m_function_method_index(),
559 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000560 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000561 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000562 m_type_index(),
563 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000564 m_indexed (false),
565 m_is_external_ast_source (false),
Greg Clayton97fbc342011-10-20 22:30:33 +0000566 m_using_apple_tables (false),
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000567 m_fetched_external_modules (false),
Greg Claytonc7f03b62012-01-12 04:33:28 +0000568 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000569 m_ranges(),
570 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000571{
572}
573
574SymbolFileDWARF::~SymbolFileDWARF()
575{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000576 if (m_is_external_ast_source)
Greg Claytone72dfb32012-02-24 01:59:29 +0000577 {
578 ModuleSP module_sp (m_obj_file->GetModule());
579 if (module_sp)
580 module_sp->GetClangASTContext().RemoveExternalSource ();
581 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000582}
583
584static const ConstString &
585GetDWARFMachOSegmentName ()
586{
587 static ConstString g_dwarf_section_name ("__DWARF");
588 return g_dwarf_section_name;
589}
590
Greg Claytone576ab22011-02-15 00:19:15 +0000591UniqueDWARFASTTypeMap &
592SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
593{
Greg Clayton1f746072012-08-29 21:13:06 +0000594 if (GetDebugMapSymfile ())
Greg Claytone576ab22011-02-15 00:19:15 +0000595 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
596 return m_unique_ast_type_map;
597}
598
Greg Clayton6beaaa62011-01-17 03:46:26 +0000599ClangASTContext &
600SymbolFileDWARF::GetClangASTContext ()
601{
Greg Clayton1f746072012-08-29 21:13:06 +0000602 if (GetDebugMapSymfile ())
Greg Clayton6beaaa62011-01-17 03:46:26 +0000603 return m_debug_map_symfile->GetClangASTContext ();
604
605 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
606 if (!m_is_external_ast_source)
607 {
608 m_is_external_ast_source = true;
Todd Fiala955fe6f2014-02-27 17:18:23 +0000609 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap (
Greg Clayton6beaaa62011-01-17 03:46:26 +0000610 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
611 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000612 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Claytoncaab74e2012-01-28 00:48:57 +0000613 SymbolFileDWARF::LayoutRecordType,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000614 this));
Greg Clayton6beaaa62011-01-17 03:46:26 +0000615 ast.SetExternalSource (ast_source_ap);
616 }
617 return ast;
618}
619
620void
621SymbolFileDWARF::InitializeObject()
622{
623 // Install our external AST source callbacks so we can complete Clang types.
Greg Claytone72dfb32012-02-24 01:59:29 +0000624 ModuleSP module_sp (m_obj_file->GetModule());
625 if (module_sp)
Greg Clayton6beaaa62011-01-17 03:46:26 +0000626 {
Greg Clayton3046e662013-07-10 01:23:25 +0000627 const SectionList *section_list = module_sp->GetSectionList();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000628
629 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
630
631 // Memory map the DWARF mach-o segment so we have everything mmap'ed
632 // to keep our heap memory usage down.
633 if (section)
Greg Claytonc9660542012-02-05 02:38:54 +0000634 m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000635 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000636 get_apple_names_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000637 if (m_data_apple_names.GetByteSize() > 0)
638 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000639 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
640 if (m_apple_names_ap->IsValid())
641 m_using_apple_tables = true;
642 else
Greg Clayton7f995132011-10-04 22:41:51 +0000643 m_apple_names_ap.reset();
644 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000645 get_apple_types_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000646 if (m_data_apple_types.GetByteSize() > 0)
647 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000648 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
649 if (m_apple_types_ap->IsValid())
650 m_using_apple_tables = true;
651 else
Greg Clayton7f995132011-10-04 22:41:51 +0000652 m_apple_types_ap.reset();
653 }
654
655 get_apple_namespaces_data();
656 if (m_data_apple_namespaces.GetByteSize() > 0)
657 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000658 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
659 if (m_apple_namespaces_ap->IsValid())
660 m_using_apple_tables = true;
661 else
Greg Clayton7f995132011-10-04 22:41:51 +0000662 m_apple_namespaces_ap.reset();
663 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000664
Greg Clayton5009f9d2011-10-27 17:55:14 +0000665 get_apple_objc_data();
666 if (m_data_apple_objc.GetByteSize() > 0)
667 {
668 m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
669 if (m_apple_objc_ap->IsValid())
670 m_using_apple_tables = true;
671 else
672 m_apple_objc_ap.reset();
673 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000674}
675
676bool
677SymbolFileDWARF::SupportedVersion(uint16_t version)
678{
Greg Claytonabcbfe52013-04-04 00:00:36 +0000679 return version == 2 || version == 3 || version == 4;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000680}
681
682uint32_t
Sean Callananbfaf54d2011-12-03 04:38:43 +0000683SymbolFileDWARF::CalculateAbilities ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000684{
685 uint32_t abilities = 0;
686 if (m_obj_file != NULL)
687 {
688 const Section* section = NULL;
689 const SectionList *section_list = m_obj_file->GetSectionList();
690 if (section_list == NULL)
691 return 0;
692
693 uint64_t debug_abbrev_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 uint64_t debug_info_file_size = 0;
695 uint64_t debug_line_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696
Greg Clayton6beaaa62011-01-17 03:46:26 +0000697 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698
699 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000700 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701
Greg Clayton4ceb9982010-07-21 22:54:26 +0000702 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703 if (section != NULL)
704 {
Greg Clayton47037bc2012-03-27 02:40:46 +0000705 debug_info_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000706
Greg Clayton4ceb9982010-07-21 22:54:26 +0000707 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000708 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000709 debug_abbrev_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000710 else
711 m_flags.Set (flagsGotDebugAbbrevData);
712
Greg Clayton4ceb9982010-07-21 22:54:26 +0000713 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000714 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000715 m_flags.Set (flagsGotDebugArangesData);
716
Greg Clayton4ceb9982010-07-21 22:54:26 +0000717 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000718 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000719 m_flags.Set (flagsGotDebugFrameData);
720
Greg Clayton4ceb9982010-07-21 22:54:26 +0000721 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000722 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000723 debug_line_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724 else
725 m_flags.Set (flagsGotDebugLineData);
726
Greg Clayton4ceb9982010-07-21 22:54:26 +0000727 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000728 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000729 m_flags.Set (flagsGotDebugLocData);
730
Greg Clayton4ceb9982010-07-21 22:54:26 +0000731 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000732 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733 m_flags.Set (flagsGotDebugMacInfoData);
734
Greg Clayton4ceb9982010-07-21 22:54:26 +0000735 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000736 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000737 m_flags.Set (flagsGotDebugPubNamesData);
738
Greg Clayton4ceb9982010-07-21 22:54:26 +0000739 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000740 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000741 m_flags.Set (flagsGotDebugPubTypesData);
742
Greg Clayton4ceb9982010-07-21 22:54:26 +0000743 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000744 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000745 m_flags.Set (flagsGotDebugRangesData);
746
Greg Clayton4ceb9982010-07-21 22:54:26 +0000747 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000748 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749 m_flags.Set (flagsGotDebugStrData);
750 }
Greg Clayton6c596612012-05-18 21:47:20 +0000751 else
752 {
753 const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
754 if (symfile_dir_cstr)
755 {
756 if (strcasestr(symfile_dir_cstr, ".dsym"))
757 {
758 if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
759 {
760 // We have a dSYM file that didn't have a any debug info.
761 // If the string table has a size of 1, then it was made from
762 // an executable with no debug info, or from an executable that
763 // was stripped.
764 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
765 if (section && section->GetFileSize() == 1)
766 {
767 m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
768 }
769 }
770 }
771 }
772 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000773
774 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
775 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
776
777 if (debug_line_file_size > 0)
778 abilities |= LineTables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779 }
780 return abilities;
781}
782
Ed Masteeeae7212013-10-24 20:43:47 +0000783const DWARFDataExtractor&
784SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785{
786 if (m_flags.IsClear (got_flag))
787 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000788 ModuleSP module_sp (m_obj_file->GetModule());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789 m_flags.Set (got_flag);
Greg Clayton3046e662013-07-10 01:23:25 +0000790 const SectionList *section_list = module_sp->GetSectionList();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000791 if (section_list)
792 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000793 SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
794 if (section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000795 {
796 // See if we memory mapped the DWARF segment?
797 if (m_dwarf_data.GetByteSize())
798 {
Greg Clayton47037bc2012-03-27 02:40:46 +0000799 data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000800 }
801 else
802 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000803 if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000804 data.Clear();
805 }
806 }
807 }
808 }
809 return data;
810}
811
Ed Masteeeae7212013-10-24 20:43:47 +0000812const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000813SymbolFileDWARF::get_debug_abbrev_data()
814{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000815 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000816}
817
Ed Masteeeae7212013-10-24 20:43:47 +0000818const DWARFDataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000819SymbolFileDWARF::get_debug_aranges_data()
820{
821 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
822}
823
Ed Masteeeae7212013-10-24 20:43:47 +0000824const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825SymbolFileDWARF::get_debug_frame_data()
826{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000827 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000828}
829
Ed Masteeeae7212013-10-24 20:43:47 +0000830const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000831SymbolFileDWARF::get_debug_info_data()
832{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000833 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000834}
835
Ed Masteeeae7212013-10-24 20:43:47 +0000836const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000837SymbolFileDWARF::get_debug_line_data()
838{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000839 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000840}
841
Ed Masteeeae7212013-10-24 20:43:47 +0000842const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000843SymbolFileDWARF::get_debug_loc_data()
844{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000845 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000846}
847
Ed Masteeeae7212013-10-24 20:43:47 +0000848const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000849SymbolFileDWARF::get_debug_ranges_data()
850{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000851 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000852}
853
Ed Masteeeae7212013-10-24 20:43:47 +0000854const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000855SymbolFileDWARF::get_debug_str_data()
856{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000857 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000858}
859
Ed Masteeeae7212013-10-24 20:43:47 +0000860const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000861SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000862{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000863 return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000864}
865
Ed Masteeeae7212013-10-24 20:43:47 +0000866const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000867SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000868{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000869 return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000870}
871
Ed Masteeeae7212013-10-24 20:43:47 +0000872const DWARFDataExtractor&
Greg Clayton7f995132011-10-04 22:41:51 +0000873SymbolFileDWARF::get_apple_namespaces_data()
874{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000875 return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
876}
877
Ed Masteeeae7212013-10-24 20:43:47 +0000878const DWARFDataExtractor&
Greg Clayton5009f9d2011-10-27 17:55:14 +0000879SymbolFileDWARF::get_apple_objc_data()
880{
881 return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
Greg Clayton7f995132011-10-04 22:41:51 +0000882}
883
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000884
885DWARFDebugAbbrev*
886SymbolFileDWARF::DebugAbbrev()
887{
888 if (m_abbr.get() == NULL)
889 {
Ed Masteeeae7212013-10-24 20:43:47 +0000890 const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000891 if (debug_abbrev_data.GetByteSize() > 0)
892 {
893 m_abbr.reset(new DWARFDebugAbbrev());
894 if (m_abbr.get())
895 m_abbr->Parse(debug_abbrev_data);
896 }
897 }
898 return m_abbr.get();
899}
900
901const DWARFDebugAbbrev*
902SymbolFileDWARF::DebugAbbrev() const
903{
904 return m_abbr.get();
905}
906
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000907
908DWARFDebugInfo*
909SymbolFileDWARF::DebugInfo()
910{
911 if (m_info.get() == NULL)
912 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000913 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
914 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000915 if (get_debug_info_data().GetByteSize() > 0)
916 {
917 m_info.reset(new DWARFDebugInfo());
918 if (m_info.get())
919 {
920 m_info->SetDwarfData(this);
921 }
922 }
923 }
924 return m_info.get();
925}
926
927const DWARFDebugInfo*
928SymbolFileDWARF::DebugInfo() const
929{
930 return m_info.get();
931}
932
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000933DWARFCompileUnit*
Greg Clayton1f746072012-08-29 21:13:06 +0000934SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000935{
936 DWARFDebugInfo* info = DebugInfo();
Greg Clayton1f746072012-08-29 21:13:06 +0000937 if (info)
938 {
939 if (GetDebugMapSymfile ())
940 {
941 // The debug map symbol file made the compile units for this DWARF
942 // file which is .o file with DWARF in it, and we should have
943 // only 1 compile unit which is at offset zero in the DWARF.
944 // TODO: modify to support LTO .o files where each .o file might
945 // have multiple DW_TAG_compile_unit tags.
Greg Clayton68c00bd2015-02-05 02:10:29 +0000946
947 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0).get();
948 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
949 dwarf_cu->SetUserData(comp_unit);
950 return dwarf_cu;
Greg Clayton1f746072012-08-29 21:13:06 +0000951 }
952 else
953 {
954 // Just a normal DWARF file whose user ID for the compile unit is
955 // the DWARF offset itself
Greg Clayton68c00bd2015-02-05 02:10:29 +0000956
957 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
958 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
959 dwarf_cu->SetUserData(comp_unit);
960 return dwarf_cu;
961
Greg Clayton1f746072012-08-29 21:13:06 +0000962 }
963 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000964 return NULL;
965}
966
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000967
968DWARFDebugRanges*
969SymbolFileDWARF::DebugRanges()
970{
971 if (m_ranges.get() == NULL)
972 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000973 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
974 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000975 if (get_debug_ranges_data().GetByteSize() > 0)
976 {
977 m_ranges.reset(new DWARFDebugRanges());
978 if (m_ranges.get())
979 m_ranges->Extract(this);
980 }
981 }
982 return m_ranges.get();
983}
984
985const DWARFDebugRanges*
986SymbolFileDWARF::DebugRanges() const
987{
988 return m_ranges.get();
989}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000990
Greg Clayton53eb1c22012-04-02 22:59:12 +0000991lldb::CompUnitSP
992SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993{
Greg Clayton53eb1c22012-04-02 22:59:12 +0000994 CompUnitSP cu_sp;
995 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000996 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000997 CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
998 if (comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000999 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001000 // We already parsed this compile unit, had out a shared pointer to it
1001 cu_sp = comp_unit->shared_from_this();
1002 }
1003 else
1004 {
Greg Clayton1f746072012-08-29 21:13:06 +00001005 if (GetDebugMapSymfile ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001006 {
Greg Clayton1f746072012-08-29 21:13:06 +00001007 // Let the debug map create the compile unit
1008 cu_sp = m_debug_map_symfile->GetCompileUnit(this);
1009 dwarf_cu->SetUserData(cu_sp.get());
1010 }
1011 else
1012 {
1013 ModuleSP module_sp (m_obj_file->GetModule());
1014 if (module_sp)
Greg Clayton53eb1c22012-04-02 22:59:12 +00001015 {
Greg Clayton1f746072012-08-29 21:13:06 +00001016 const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
1017 if (cu_die)
Greg Clayton53eb1c22012-04-02 22:59:12 +00001018 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001019 FileSpec cu_file_spec{cu_die->GetName(this, dwarf_cu), false};
1020 if (cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +00001021 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001022 // If we have a full path to the compile unit, we don't need to resolve
1023 // the file. This can be expensive e.g. when the source files are NFS mounted.
Chaoren Lin372e9062015-06-09 17:54:27 +00001024 if (cu_file_spec.IsRelative())
Greg Clayton53eb1c22012-04-02 22:59:12 +00001025 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001026 const char *cu_comp_dir{cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, nullptr)};
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +00001027 cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
Greg Clayton1f746072012-08-29 21:13:06 +00001028 }
1029
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001030 std::string remapped_file;
1031 if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
1032 cu_file_spec.SetFile(remapped_file, false);
David Srbeckyd515e942015-07-08 14:00:04 +00001033 }
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001034
David Srbeckyd515e942015-07-08 14:00:04 +00001035 LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0));
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001036
David Srbeckyd515e942015-07-08 14:00:04 +00001037 cu_sp.reset(new CompileUnit (module_sp,
1038 dwarf_cu,
1039 cu_file_spec,
1040 MakeUserID(dwarf_cu->GetOffset()),
1041 cu_language));
1042 if (cu_sp)
1043 {
1044 // If we just created a compile unit with an invalid file spec, try and get the
1045 // first entry in the supports files from the line table as that should be the
1046 // compile unit.
1047 if (!cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +00001048 {
David Srbeckyd515e942015-07-08 14:00:04 +00001049 cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
1050 if (cu_file_spec)
1051 {
1052 (FileSpec &)(*cu_sp) = cu_file_spec;
1053 // Also fix the invalid file spec which was copied from the compile unit.
1054 cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
1055 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001056 }
David Srbeckyd515e942015-07-08 14:00:04 +00001057
1058 dwarf_cu->SetUserData(cu_sp.get());
1059
1060 // Figure out the compile unit index if we weren't given one
1061 if (cu_idx == UINT32_MAX)
1062 DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
1063
1064 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
Greg Clayton53eb1c22012-04-02 22:59:12 +00001065 }
1066 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 }
1068 }
1069 }
1070 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001071 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001072}
1073
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074uint32_t
1075SymbolFileDWARF::GetNumCompileUnits()
1076{
1077 DWARFDebugInfo* info = DebugInfo();
1078 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001080 return 0;
1081}
1082
1083CompUnitSP
1084SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
1085{
Greg Clayton53eb1c22012-04-02 22:59:12 +00001086 CompUnitSP cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001087 DWARFDebugInfo* info = DebugInfo();
1088 if (info)
1089 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001090 DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
1091 if (dwarf_cu)
1092 cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001094 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095}
1096
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097Function *
Greg Clayton0fffff52010-09-24 05:15:53 +00001098SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099{
1100 DWARFDebugRanges::RangeList func_ranges;
1101 const char *name = NULL;
1102 const char *mangled = NULL;
1103 int decl_file = 0;
1104 int decl_line = 0;
1105 int decl_column = 0;
1106 int call_file = 0;
1107 int call_line = 0;
1108 int call_column = 0;
1109 DWARFExpression frame_base;
1110
Greg Claytonc93237c2010-10-01 20:48:32 +00001111 assert (die->Tag() == DW_TAG_subprogram);
1112
1113 if (die->Tag() != DW_TAG_subprogram)
1114 return NULL;
1115
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001116 if (die->GetDIENamesAndRanges (this,
1117 dwarf_cu,
1118 name,
1119 mangled,
1120 func_ranges,
1121 decl_file,
1122 decl_line,
1123 decl_column,
1124 call_file,
1125 call_line,
1126 call_column,
1127 &frame_base))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001128 {
1129 // Union of all ranges in the function DIE (if the function is discontiguous)
1130 AddressRange func_range;
Greg Claytonea3e7d52011-10-08 00:49:15 +00001131 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
1132 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
1134 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001135 ModuleSP module_sp (m_obj_file->GetModule());
Greg Clayton3046e662013-07-10 01:23:25 +00001136 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetSectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001137 if (func_range.GetBaseAddress().IsValid())
1138 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
1139 }
1140
1141 if (func_range.GetBaseAddress().IsValid())
1142 {
1143 Mangled func_name;
1144 if (mangled)
Greg Clayton037520e2012-07-18 23:18:10 +00001145 func_name.SetValue(ConstString(mangled), true);
Siva Chandra462722d2015-03-27 00:10:04 +00001146 else if (die->GetParent()->Tag() == DW_TAG_compile_unit &&
1147 LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()) &&
Greg Clayton94380562015-05-15 22:20:29 +00001148 name && strcmp(name, "main") != 0)
Siva Chandra462722d2015-03-27 00:10:04 +00001149 {
1150 // If the mangled name is not present in the DWARF, generate the demangled name
1151 // using the decl context. We skip if the function is "main" as its name is
1152 // never mangled.
1153 bool is_static = false;
1154 bool is_variadic = false;
1155 unsigned type_quals = 0;
1156 std::vector<ClangASTType> param_types;
1157 std::vector<clang::ParmVarDecl*> param_decls;
1158 const DWARFDebugInfoEntry *decl_ctx_die = NULL;
1159 DWARFDeclContext decl_ctx;
1160 StreamString sstr;
1161
1162 die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx);
1163 sstr << decl_ctx.GetQualifiedName();
1164
1165 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(dwarf_cu,
1166 die,
1167 &decl_ctx_die);
1168 ParseChildParameters(sc,
1169 containing_decl_ctx,
1170 dwarf_cu,
1171 die,
1172 true,
1173 is_static,
1174 is_variadic,
1175 param_types,
1176 param_decls,
1177 type_quals);
1178 sstr << "(";
1179 for (size_t i = 0; i < param_types.size(); i++)
1180 {
1181 if (i > 0)
1182 sstr << ", ";
1183 sstr << param_types[i].GetTypeName();
1184 }
1185 if (is_variadic)
1186 sstr << ", ...";
1187 sstr << ")";
1188 if (type_quals & clang::Qualifiers::Const)
1189 sstr << " const";
1190
1191 func_name.SetValue(ConstString(sstr.GetData()), false);
1192 }
1193 else
Greg Clayton037520e2012-07-18 23:18:10 +00001194 func_name.SetValue(ConstString(name), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001195
1196 FunctionSP func_sp;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001197 std::unique_ptr<Declaration> decl_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001198 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +00001199 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1200 decl_line,
1201 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001202
Greg Clayton0bd4e1b2011-09-30 20:52:25 +00001203 // Supply the type _only_ if it has already been parsed
Greg Clayton594e5ed2010-09-27 21:07:38 +00001204 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001205
1206 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
1207
Greg Clayton9422dd62013-03-04 21:46:16 +00001208 if (FixupAddress (func_range.GetBaseAddress()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001210 const user_id_t func_user_id = MakeUserID(die->GetOffset());
1211 func_sp.reset(new Function (sc.comp_unit,
1212 MakeUserID(func_user_id), // UserID is the DIE offset
1213 MakeUserID(func_user_id),
1214 func_name,
1215 func_type,
1216 func_range)); // first address range
1217
1218 if (func_sp.get() != NULL)
1219 {
1220 if (frame_base.IsValid())
1221 func_sp->GetFrameBaseExpression() = frame_base;
1222 sc.comp_unit->AddFunction(func_sp);
1223 return func_sp.get();
1224 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001225 }
1226 }
1227 }
1228 return NULL;
1229}
1230
Greg Clayton9422dd62013-03-04 21:46:16 +00001231bool
1232SymbolFileDWARF::FixupAddress (Address &addr)
1233{
1234 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
1235 if (debug_map_symfile)
1236 {
1237 return debug_map_symfile->LinkOSOAddress(addr);
1238 }
1239 // This is a normal DWARF file, no address fixups need to happen
1240 return true;
1241}
Greg Clayton1f746072012-08-29 21:13:06 +00001242lldb::LanguageType
1243SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
1244{
1245 assert (sc.comp_unit);
1246 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1247 if (dwarf_cu)
1248 {
1249 const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
Jim Ingham28eb5712012-10-12 17:34:26 +00001250 if (die)
Dawn Perchikd0e87eb2015-06-17 22:30:24 +00001251 return DWARFCompileUnit::LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0));
Greg Clayton1f746072012-08-29 21:13:06 +00001252 }
1253 return eLanguageTypeUnknown;
1254}
1255
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001256size_t
1257SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
1258{
1259 assert (sc.comp_unit);
1260 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00001261 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 if (dwarf_cu)
1263 {
1264 DWARFDIECollection function_dies;
Greg Clayton1f746072012-08-29 21:13:06 +00001265 const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001266 size_t func_idx;
Greg Clayton1f746072012-08-29 21:13:06 +00001267 for (func_idx = 0; func_idx < num_functions; ++func_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001268 {
1269 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
Greg Clayton81c22f62011-10-19 18:09:39 +00001270 if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001271 {
1272 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
1273 ++functions_added;
1274 }
1275 }
1276 //FixupTypes();
1277 }
1278 return functions_added;
1279}
1280
1281bool
1282SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
1283{
1284 assert (sc.comp_unit);
Greg Clayton1f746072012-08-29 21:13:06 +00001285 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Greg Claytonda2455b2012-11-01 17:28:37 +00001286 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001287 {
Greg Claytonda2455b2012-11-01 17:28:37 +00001288 const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001289
Greg Claytonda2455b2012-11-01 17:28:37 +00001290 if (cu_die)
1291 {
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +00001292 const char * cu_comp_dir = resolveCompDir(cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, nullptr));
Matthew Gardinere81df3b2014-08-26 06:57:23 +00001293
Greg Claytonda2455b2012-11-01 17:28:37 +00001294 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001295
Greg Claytonda2455b2012-11-01 17:28:37 +00001296 // All file indexes in DWARF are one based and a file of index zero is
1297 // supposed to be the compile unit itself.
1298 support_files.Append (*sc.comp_unit);
1299
1300 return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
1301 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302 }
1303 return false;
1304}
1305
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001306bool
1307SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
1308{
1309 assert (sc.comp_unit);
1310 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1311 if (dwarf_cu)
1312 {
1313 if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
1314 {
1315 UpdateExternalModuleListIfNeeded();
1316 for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
1317 {
1318 imported_modules.push_back(external_type_module.second.m_name);
1319 }
1320 }
1321 }
1322 return false;
1323}
1324
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001325struct ParseDWARFLineTableCallbackInfo
1326{
1327 LineTable* line_table;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001328 std::unique_ptr<LineSequence> sequence_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001329};
1330
1331//----------------------------------------------------------------------
1332// ParseStatementTableCallback
1333//----------------------------------------------------------------------
1334static void
1335ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1336{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001337 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1338 {
1339 // Just started parsing the line table
1340 }
1341 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1342 {
1343 // Done parsing line table, nothing to do for the cleanup
1344 }
1345 else
1346 {
1347 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
Greg Clayton9422dd62013-03-04 21:46:16 +00001348 LineTable* line_table = info->line_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001349
Greg Clayton9422dd62013-03-04 21:46:16 +00001350 // If this is our first time here, we need to create a
1351 // sequence container.
1352 if (!info->sequence_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001353 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001354 info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
1355 assert(info->sequence_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001356 }
Greg Clayton9422dd62013-03-04 21:46:16 +00001357 line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
1358 state.address,
1359 state.line,
1360 state.column,
1361 state.file,
1362 state.is_stmt,
1363 state.basic_block,
1364 state.prologue_end,
1365 state.epilogue_begin,
1366 state.end_sequence);
1367 if (state.end_sequence)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001368 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001369 // First, put the current sequence into the line table.
1370 line_table->InsertSequence(info->sequence_ap.get());
1371 // Then, empty it to prepare for the next sequence.
1372 info->sequence_ap->Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001373 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001374 }
1375}
1376
1377bool
1378SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1379{
1380 assert (sc.comp_unit);
1381 if (sc.comp_unit->GetLineTable() != NULL)
1382 return true;
1383
Greg Clayton1f746072012-08-29 21:13:06 +00001384 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001385 if (dwarf_cu)
1386 {
1387 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Greg Clayton129d12c2011-11-28 03:29:03 +00001388 if (dwarf_cu_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001389 {
Greg Clayton129d12c2011-11-28 03:29:03 +00001390 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
1391 if (cu_line_offset != DW_INVALID_OFFSET)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001392 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001393 std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
Greg Clayton129d12c2011-11-28 03:29:03 +00001394 if (line_table_ap.get())
1395 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001396 ParseDWARFLineTableCallbackInfo info;
1397 info.line_table = line_table_ap.get();
Greg Claytonc7bece562013-01-25 18:06:21 +00001398 lldb::offset_t offset = cu_line_offset;
Greg Clayton129d12c2011-11-28 03:29:03 +00001399 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
Greg Clayton9422dd62013-03-04 21:46:16 +00001400 if (m_debug_map_symfile)
1401 {
1402 // We have an object file that has a line table with addresses
1403 // that are not linked. We need to link the line table and convert
1404 // the addresses that are relative to the .o file into addresses
1405 // for the main executable.
1406 sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
1407 }
1408 else
1409 {
1410 sc.comp_unit->SetLineTable(line_table_ap.release());
1411 return true;
1412 }
Greg Clayton129d12c2011-11-28 03:29:03 +00001413 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001414 }
1415 }
1416 }
1417 return false;
1418}
1419
1420size_t
1421SymbolFileDWARF::ParseFunctionBlocks
1422(
1423 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001424 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +00001425 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001426 const DWARFDebugInfoEntry *die,
1427 addr_t subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001428 uint32_t depth
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001429)
1430{
1431 size_t blocks_added = 0;
1432 while (die != NULL)
1433 {
1434 dw_tag_t tag = die->Tag();
1435
1436 switch (tag)
1437 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001438 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001439 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001440 case DW_TAG_lexical_block:
1441 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001442 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001443 if (tag == DW_TAG_subprogram)
1444 {
1445 // Skip any DW_TAG_subprogram DIEs that are inside
1446 // of a normal or inlined functions. These will be
1447 // parsed on their own as separate entities.
1448
1449 if (depth > 0)
1450 break;
1451
1452 block = parent_block;
1453 }
1454 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001455 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001456 BlockSP block_sp(new Block (MakeUserID(die->GetOffset())));
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001457 parent_block->AddChild(block_sp);
1458 block = block_sp.get();
1459 }
Greg Claytondd7feaf2011-08-12 17:54:33 +00001460 DWARFDebugRanges::RangeList ranges;
1461 const char *name = NULL;
1462 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001463
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001464 int decl_file = 0;
1465 int decl_line = 0;
1466 int decl_column = 0;
1467 int call_file = 0;
1468 int call_line = 0;
1469 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001470 if (die->GetDIENamesAndRanges (this,
1471 dwarf_cu,
1472 name,
1473 mangled_name,
1474 ranges,
1475 decl_file, decl_line, decl_column,
1476 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001477 {
1478 if (tag == DW_TAG_subprogram)
1479 {
1480 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
Greg Claytonea3e7d52011-10-08 00:49:15 +00001481 subprogram_low_pc = ranges.GetMinRangeBase(0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001482 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001483 else if (tag == DW_TAG_inlined_subroutine)
1484 {
1485 // We get called here for inlined subroutines in two ways.
1486 // The first time is when we are making the Function object
1487 // for this inlined concrete instance. Since we're creating a top level block at
1488 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1489 // adjust the containing address.
1490 // The second time is when we are parsing the blocks inside the function that contains
1491 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1492 // function the offset will be for that function.
1493 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1494 {
Greg Claytonea3e7d52011-10-08 00:49:15 +00001495 subprogram_low_pc = ranges.GetMinRangeBase(0);
Jim Inghamb0be4422010-08-12 01:20:14 +00001496 }
1497 }
Greg Clayton103f3092015-01-15 03:04:37 +00001498
1499 const size_t num_ranges = ranges.GetSize();
1500 for (size_t i = 0; i<num_ranges; ++i)
1501 {
1502 const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
1503 const addr_t range_base = range.GetRangeBase();
1504 if (range_base >= subprogram_low_pc)
1505 block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
1506 else
1507 {
1508 GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
1509 block->GetID(),
1510 range_base,
1511 range.GetRangeEnd(),
1512 subprogram_low_pc);
1513 }
1514 }
1515 block->FinalizeRanges ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001516
1517 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1518 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001519 std::unique_ptr<Declaration> decl_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001520 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001521 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1522 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001523
Greg Clayton7b0992d2013-04-18 22:45:39 +00001524 std::unique_ptr<Declaration> call_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001525 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001526 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1527 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001528
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001529 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001530 }
1531
1532 ++blocks_added;
1533
Greg Claytondd7feaf2011-08-12 17:54:33 +00001534 if (die->HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001535 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001536 blocks_added += ParseFunctionBlocks (sc,
1537 block,
1538 dwarf_cu,
1539 die->GetFirstChild(),
1540 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001541 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001542 }
1543 }
1544 }
1545 break;
1546 default:
1547 break;
1548 }
1549
Greg Claytondd7feaf2011-08-12 17:54:33 +00001550 // Only parse siblings of the block if we are not at depth zero. A depth
1551 // of zero indicates we are currently parsing the top level
1552 // DW_TAG_subprogram DIE
1553
1554 if (depth == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001555 die = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001556 else
1557 die = die->GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001558 }
1559 return blocks_added;
1560}
1561
Greg Claytonf0705c82011-10-22 03:33:13 +00001562bool
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001563SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu,
1564 const DWARFDebugInfoEntry *die,
1565 ClangASTContext::TemplateParameterInfos &template_param_infos)
1566{
1567 const dw_tag_t tag = die->Tag();
1568
1569 switch (tag)
1570 {
1571 case DW_TAG_template_type_parameter:
1572 case DW_TAG_template_value_parameter:
1573 {
Todd Fialaee8bfc62014-09-11 17:29:12 +00001574 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001575
1576 DWARFDebugInfoEntry::Attributes attributes;
1577 const size_t num_attributes = die->GetAttributes (this,
1578 dwarf_cu,
1579 fixed_form_sizes,
1580 attributes);
1581 const char *name = NULL;
1582 Type *lldb_type = NULL;
Greg Clayton57ee3062013-07-11 22:46:58 +00001583 ClangASTType clang_type;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001584 uint64_t uval64 = 0;
1585 bool uval64_valid = false;
1586 if (num_attributes > 0)
1587 {
1588 DWARFFormValue form_value;
1589 for (size_t i=0; i<num_attributes; ++i)
1590 {
1591 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1592
1593 switch (attr)
1594 {
1595 case DW_AT_name:
1596 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1597 name = form_value.AsCString(&get_debug_str_data());
1598 break;
1599
1600 case DW_AT_type:
1601 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1602 {
Greg Clayton54166af2014-11-22 01:58:59 +00001603 const dw_offset_t type_die_offset = form_value.Reference();
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001604 lldb_type = ResolveTypeUID(type_die_offset);
1605 if (lldb_type)
1606 clang_type = lldb_type->GetClangForwardType();
1607 }
1608 break;
1609
1610 case DW_AT_const_value:
1611 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1612 {
1613 uval64_valid = true;
1614 uval64 = form_value.Unsigned();
1615 }
1616 break;
1617 default:
1618 break;
1619 }
1620 }
1621
Greg Clayton283b2652013-04-23 22:38:02 +00001622 clang::ASTContext *ast = GetClangASTContext().getASTContext();
1623 if (!clang_type)
Greg Clayton57ee3062013-07-11 22:46:58 +00001624 clang_type = GetClangASTContext().GetBasicType(eBasicTypeVoid);
Greg Clayton283b2652013-04-23 22:38:02 +00001625
1626 if (clang_type)
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001627 {
1628 bool is_signed = false;
Greg Clayton283b2652013-04-23 22:38:02 +00001629 if (name && name[0])
1630 template_param_infos.names.push_back(name);
1631 else
1632 template_param_infos.names.push_back(NULL);
1633
Greg Clayton283b2652013-04-23 22:38:02 +00001634 if (tag == DW_TAG_template_value_parameter &&
1635 lldb_type != NULL &&
Greg Clayton57ee3062013-07-11 22:46:58 +00001636 clang_type.IsIntegerType (is_signed) &&
Greg Clayton283b2652013-04-23 22:38:02 +00001637 uval64_valid)
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001638 {
1639 llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
Greg Clayton283b2652013-04-23 22:38:02 +00001640 template_param_infos.args.push_back (clang::TemplateArgument (*ast,
Sean Callanan3d654b32012-09-24 22:25:51 +00001641 llvm::APSInt(apint),
Pavel Labathc7c30eb2015-06-08 23:38:06 +00001642 clang_type.GetQualType()));
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001643 }
1644 else
1645 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00001646 template_param_infos.args.push_back (clang::TemplateArgument (clang_type.GetQualType()));
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001647 }
1648 }
1649 else
1650 {
1651 return false;
1652 }
1653
1654 }
1655 }
1656 return true;
1657
1658 default:
1659 break;
1660 }
1661 return false;
1662}
1663
1664bool
Greg Claytonf0705c82011-10-22 03:33:13 +00001665SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
1666 const DWARFDebugInfoEntry *parent_die,
1667 ClangASTContext::TemplateParameterInfos &template_param_infos)
1668{
1669
1670 if (parent_die == NULL)
Filipe Cabecinhas52008c62012-05-23 16:24:11 +00001671 return false;
Greg Claytonf0705c82011-10-22 03:33:13 +00001672
Greg Claytonf0705c82011-10-22 03:33:13 +00001673 Args template_parameter_names;
1674 for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild();
1675 die != NULL;
1676 die = die->GetSibling())
1677 {
1678 const dw_tag_t tag = die->Tag();
1679
1680 switch (tag)
1681 {
1682 case DW_TAG_template_type_parameter:
1683 case DW_TAG_template_value_parameter:
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001684 ParseTemplateDIE (dwarf_cu, die, template_param_infos);
Greg Claytonf0705c82011-10-22 03:33:13 +00001685 break;
1686
1687 default:
1688 break;
1689 }
1690 }
1691 if (template_param_infos.args.empty())
1692 return false;
1693 return template_param_infos.args.size() == template_param_infos.names.size();
1694}
1695
1696clang::ClassTemplateDecl *
1697SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00001698 lldb::AccessType access_type,
Greg Claytonf0705c82011-10-22 03:33:13 +00001699 const char *parent_name,
1700 int tag_decl_kind,
1701 const ClangASTContext::TemplateParameterInfos &template_param_infos)
1702{
1703 if (template_param_infos.IsValid())
1704 {
1705 std::string template_basename(parent_name);
1706 template_basename.erase (template_basename.find('<'));
1707 ClangASTContext &ast = GetClangASTContext();
1708
1709 return ast.CreateClassTemplateDecl (decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00001710 access_type,
Greg Claytonf0705c82011-10-22 03:33:13 +00001711 template_basename.c_str(),
1712 tag_decl_kind,
1713 template_param_infos);
1714 }
1715 return NULL;
1716}
1717
Sean Callanana0b80ab2012-06-04 22:28:05 +00001718class SymbolFileDWARF::DelayedAddObjCClassProperty
1719{
1720public:
1721 DelayedAddObjCClassProperty
1722 (
Greg Clayton57ee3062013-07-11 22:46:58 +00001723 const ClangASTType &class_opaque_type,
Sean Callanana0b80ab2012-06-04 22:28:05 +00001724 const char *property_name,
Greg Clayton57ee3062013-07-11 22:46:58 +00001725 const ClangASTType &property_opaque_type, // The property type is only required if you don't have an ivar decl
Sean Callanana0b80ab2012-06-04 22:28:05 +00001726 clang::ObjCIvarDecl *ivar_decl,
1727 const char *property_setter_name,
1728 const char *property_getter_name,
1729 uint32_t property_attributes,
Greg Claytonc4ffd662013-03-08 01:37:30 +00001730 const ClangASTMetadata *metadata
Sean Callanana0b80ab2012-06-04 22:28:05 +00001731 ) :
Sean Callanana0b80ab2012-06-04 22:28:05 +00001732 m_class_opaque_type (class_opaque_type),
1733 m_property_name (property_name),
1734 m_property_opaque_type (property_opaque_type),
1735 m_ivar_decl (ivar_decl),
1736 m_property_setter_name (property_setter_name),
1737 m_property_getter_name (property_getter_name),
Jim Ingham379397632012-10-27 02:54:13 +00001738 m_property_attributes (property_attributes)
Sean Callanana0b80ab2012-06-04 22:28:05 +00001739 {
Jim Ingham379397632012-10-27 02:54:13 +00001740 if (metadata != NULL)
1741 {
1742 m_metadata_ap.reset(new ClangASTMetadata());
Greg Claytonc4ffd662013-03-08 01:37:30 +00001743 *m_metadata_ap = *metadata;
Jim Ingham379397632012-10-27 02:54:13 +00001744 }
1745 }
1746
1747 DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
1748 {
Greg Clayton57ee3062013-07-11 22:46:58 +00001749 *this = rhs;
Daniel Malead4c5be62012-11-12 21:02:14 +00001750 }
1751
1752 DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
1753 {
Jim Ingham379397632012-10-27 02:54:13 +00001754 m_class_opaque_type = rhs.m_class_opaque_type;
1755 m_property_name = rhs.m_property_name;
1756 m_property_opaque_type = rhs.m_property_opaque_type;
1757 m_ivar_decl = rhs.m_ivar_decl;
1758 m_property_setter_name = rhs.m_property_setter_name;
1759 m_property_getter_name = rhs.m_property_getter_name;
1760 m_property_attributes = rhs.m_property_attributes;
1761
1762 if (rhs.m_metadata_ap.get())
1763 {
1764 m_metadata_ap.reset (new ClangASTMetadata());
Greg Claytonc4ffd662013-03-08 01:37:30 +00001765 *m_metadata_ap = *rhs.m_metadata_ap;
Jim Ingham379397632012-10-27 02:54:13 +00001766 }
Daniel Malead4c5be62012-11-12 21:02:14 +00001767 return *this;
Sean Callanana0b80ab2012-06-04 22:28:05 +00001768 }
1769
Greg Clayton57ee3062013-07-11 22:46:58 +00001770 bool
1771 Finalize()
Sean Callanana0b80ab2012-06-04 22:28:05 +00001772 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00001773 return m_class_opaque_type.AddObjCClassProperty (m_property_name,
1774 m_property_opaque_type,
1775 m_ivar_decl,
1776 m_property_setter_name,
1777 m_property_getter_name,
1778 m_property_attributes,
1779 m_metadata_ap.get());
Sean Callanana0b80ab2012-06-04 22:28:05 +00001780 }
1781private:
Greg Clayton57ee3062013-07-11 22:46:58 +00001782 ClangASTType m_class_opaque_type;
Sean Callanana0b80ab2012-06-04 22:28:05 +00001783 const char *m_property_name;
Greg Clayton57ee3062013-07-11 22:46:58 +00001784 ClangASTType m_property_opaque_type;
Sean Callanana0b80ab2012-06-04 22:28:05 +00001785 clang::ObjCIvarDecl *m_ivar_decl;
1786 const char *m_property_setter_name;
1787 const char *m_property_getter_name;
1788 uint32_t m_property_attributes;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001789 std::unique_ptr<ClangASTMetadata> m_metadata_ap;
Sean Callanana0b80ab2012-06-04 22:28:05 +00001790};
1791
Sean Callananfaa0bb32012-12-05 23:37:14 +00001792struct BitfieldInfo
1793{
1794 uint64_t bit_size;
1795 uint64_t bit_offset;
1796
1797 BitfieldInfo () :
1798 bit_size (LLDB_INVALID_ADDRESS),
1799 bit_offset (LLDB_INVALID_ADDRESS)
1800 {
1801 }
1802
Greg Clayton78f4d952013-12-11 23:10:39 +00001803 void
1804 Clear()
1805 {
1806 bit_size = LLDB_INVALID_ADDRESS;
1807 bit_offset = LLDB_INVALID_ADDRESS;
1808 }
1809
Sean Callananfaa0bb32012-12-05 23:37:14 +00001810 bool IsValid ()
1811 {
1812 return (bit_size != LLDB_INVALID_ADDRESS) &&
1813 (bit_offset != LLDB_INVALID_ADDRESS);
1814 }
1815};
1816
Greg Claytonc4ffd662013-03-08 01:37:30 +00001817
1818bool
1819SymbolFileDWARF::ClassOrStructIsVirtual (DWARFCompileUnit* dwarf_cu,
1820 const DWARFDebugInfoEntry *parent_die)
1821{
1822 if (parent_die)
1823 {
1824 for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1825 {
1826 dw_tag_t tag = die->Tag();
1827 bool check_virtuality = false;
1828 switch (tag)
1829 {
1830 case DW_TAG_inheritance:
1831 case DW_TAG_subprogram:
1832 check_virtuality = true;
1833 break;
1834 default:
1835 break;
1836 }
1837 if (check_virtuality)
1838 {
1839 if (die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_virtuality, 0) != 0)
1840 return true;
1841 }
1842 }
1843 }
1844 return false;
1845}
1846
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001847size_t
1848SymbolFileDWARF::ParseChildMembers
1849(
1850 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001851 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001852 const DWARFDebugInfoEntry *parent_die,
Greg Clayton57ee3062013-07-11 22:46:58 +00001853 ClangASTType &class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001854 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001855 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1856 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001857 DWARFDIECollection& member_function_dies,
Sean Callanana0b80ab2012-06-04 22:28:05 +00001858 DelayedPropertyList& delayed_properties,
Sean Callananc7fbf732010-08-06 00:32:49 +00001859 AccessType& default_accessibility,
Greg Claytoncaab74e2012-01-28 00:48:57 +00001860 bool &is_a_class,
1861 LayoutInfo &layout_info
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001862)
1863{
1864 if (parent_die == NULL)
1865 return 0;
1866
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001867 size_t count = 0;
1868 const DWARFDebugInfoEntry *die;
Todd Fialaee8bfc62014-09-11 17:29:12 +00001869 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001870 uint32_t member_idx = 0;
Sean Callananfaa0bb32012-12-05 23:37:14 +00001871 BitfieldInfo last_field_info;
Richard Mitton0a558352013-10-17 21:14:00 +00001872 ModuleSP module = GetObjectFile()->GetModule();
Greg Claytond88d7592010-09-15 08:33:30 +00001873
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001874 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1875 {
1876 dw_tag_t tag = die->Tag();
1877
1878 switch (tag)
1879 {
1880 case DW_TAG_member:
Sean Callanan3d654b32012-09-24 22:25:51 +00001881 case DW_TAG_APPLE_property:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001882 {
1883 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001884 const size_t num_attributes = die->GetAttributes (this,
1885 dwarf_cu,
1886 fixed_form_sizes,
1887 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001888 if (num_attributes > 0)
1889 {
1890 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001891 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001892 const char *name = NULL;
Jim Inghame3ae82a2011-11-12 01:36:43 +00001893 const char *prop_name = NULL;
1894 const char *prop_getter_name = NULL;
1895 const char *prop_setter_name = NULL;
Greg Claytone528efd72013-02-26 23:45:18 +00001896 uint32_t prop_attributes = 0;
Jim Inghame3ae82a2011-11-12 01:36:43 +00001897
1898
Greg Clayton24739922010-10-13 03:15:28 +00001899 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001901 AccessType accessibility = eAccessNone;
Greg Claytoncaab74e2012-01-28 00:48:57 +00001902 uint32_t member_byte_offset = UINT32_MAX;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001903 size_t byte_size = 0;
1904 size_t bit_offset = 0;
1905 size_t bit_size = 0;
Greg Claytone528efd72013-02-26 23:45:18 +00001906 bool is_external = false; // On DW_TAG_members, this means the member is static
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001907 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001908 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001909 {
1910 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1911 DWARFFormValue form_value;
1912 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1913 {
1914 switch (attr)
1915 {
1916 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1917 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1918 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1919 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00001920 case DW_AT_type: encoding_uid = form_value.Reference(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001921 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1922 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1923 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1924 case DW_AT_data_member_location:
Greg Claytoncaab74e2012-01-28 00:48:57 +00001925 if (form_value.BlockData())
1926 {
1927 Value initialValue(0);
1928 Value memberOffset(0);
Ed Masteeeae7212013-10-24 20:43:47 +00001929 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Claytoncaab74e2012-01-28 00:48:57 +00001930 uint32_t block_length = form_value.Unsigned();
1931 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1932 if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
Greg Claytoncaab74e2012-01-28 00:48:57 +00001933 NULL, // ClangExpressionVariableList *
1934 NULL, // ClangExpressionDeclMap *
1935 NULL, // RegisterContext *
Richard Mitton0a558352013-10-17 21:14:00 +00001936 module,
Greg Claytoncaab74e2012-01-28 00:48:57 +00001937 debug_info_data,
1938 block_offset,
1939 block_length,
1940 eRegisterKindDWARF,
1941 &initialValue,
1942 memberOffset,
1943 NULL))
1944 {
Greg Clayton57ee3062013-07-11 22:46:58 +00001945 member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
Greg Claytoncaab74e2012-01-28 00:48:57 +00001946 }
1947 }
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00001948 else
1949 {
1950 // With DWARF 3 and later, if the value is an integer constant,
1951 // this form value is the offset in bytes from the beginning
1952 // of the containing entity.
1953 member_byte_offset = form_value.Unsigned();
1954 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001955 break;
1956
Greg Clayton8cf05932010-07-22 18:30:50 +00001957 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00001958 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Jim Inghame3ae82a2011-11-12 01:36:43 +00001959 case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(&get_debug_str_data()); break;
1960 case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
1961 case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
1962 case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00001963 case DW_AT_external: is_external = form_value.Boolean(); break;
Jim Inghame3ae82a2011-11-12 01:36:43 +00001964
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001965 default:
Greg Clayton1b02c172012-03-14 21:00:47 +00001966 case DW_AT_declaration:
1967 case DW_AT_description:
1968 case DW_AT_mutable:
1969 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001970 case DW_AT_sibling:
1971 break;
1972 }
1973 }
1974 }
Sean Callanana6582262012-04-05 00:12:52 +00001975
1976 if (prop_name)
Sean Callanan751aac62012-03-29 19:07:06 +00001977 {
Sean Callanana6582262012-04-05 00:12:52 +00001978 ConstString fixed_getter;
1979 ConstString fixed_setter;
1980
1981 // Check if the property getter/setter were provided as full
1982 // names. We want basenames, so we extract them.
1983
1984 if (prop_getter_name && prop_getter_name[0] == '-')
1985 {
Greg Clayton1b3815c2013-01-30 00:18:29 +00001986 ObjCLanguageRuntime::MethodName prop_getter_method(prop_getter_name, true);
1987 prop_getter_name = prop_getter_method.GetSelector().GetCString();
Sean Callanana6582262012-04-05 00:12:52 +00001988 }
1989
1990 if (prop_setter_name && prop_setter_name[0] == '-')
1991 {
Greg Clayton1b3815c2013-01-30 00:18:29 +00001992 ObjCLanguageRuntime::MethodName prop_setter_method(prop_setter_name, true);
1993 prop_setter_name = prop_setter_method.GetSelector().GetCString();
Sean Callanana6582262012-04-05 00:12:52 +00001994 }
1995
1996 // If the names haven't been provided, they need to be
1997 // filled in.
1998
1999 if (!prop_getter_name)
2000 {
2001 prop_getter_name = prop_name;
2002 }
2003 if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly))
2004 {
2005 StreamString ss;
2006
2007 ss.Printf("set%c%s:",
2008 toupper(prop_name[0]),
2009 &prop_name[1]);
2010
2011 fixed_setter.SetCString(ss.GetData());
2012 prop_setter_name = fixed_setter.GetCString();
2013 }
Sean Callanan751aac62012-03-29 19:07:06 +00002014 }
2015
2016 // Clang has a DWARF generation bug where sometimes it
Greg Clayton44953932011-10-25 01:25:35 +00002017 // represents fields that are references with bad byte size
2018 // and bit size/offset information such as:
2019 //
2020 // DW_AT_byte_size( 0x00 )
2021 // DW_AT_bit_size( 0x40 )
2022 // DW_AT_bit_offset( 0xffffffffffffffc0 )
2023 //
2024 // So check the bit offset to make sure it is sane, and if
2025 // the values are not sane, remove them. If we don't do this
2026 // then we will end up with a crash if we try to use this
2027 // type in an expression when clang becomes unhappy with its
2028 // recycled debug info.
Sean Callanan5a477cf2010-10-30 01:56:10 +00002029
Greg Clayton44953932011-10-25 01:25:35 +00002030 if (bit_offset > 128)
2031 {
2032 bit_size = 0;
2033 bit_offset = 0;
2034 }
2035
2036 // FIXME: Make Clang ignore Objective-C accessibility for expressions
Sean Callanan5a477cf2010-10-30 01:56:10 +00002037 if (class_language == eLanguageTypeObjC ||
2038 class_language == eLanguageTypeObjC_plus_plus)
2039 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002040
2041 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
2042 {
2043 // Not all compilers will mark the vtable pointer
2044 // member as artificial (llvm-gcc). We can't have
2045 // the virtual members in our classes otherwise it
2046 // throws off all child offsets since we end up
2047 // having and extra pointer sized member in our
2048 // class layouts.
2049 is_artificial = true;
2050 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002051
Greg Clayton29659712013-07-12 20:08:35 +00002052 // Handle static members
Greg Claytone528efd72013-02-26 23:45:18 +00002053 if (is_external && member_byte_offset == UINT32_MAX)
Greg Clayton973b6c92013-04-11 16:57:51 +00002054 {
2055 Type *var_type = ResolveTypeUID(encoding_uid);
2056
2057 if (var_type)
2058 {
Greg Clayton29659712013-07-12 20:08:35 +00002059 if (accessibility == eAccessNone)
2060 accessibility = eAccessPublic;
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002061 class_clang_type.AddVariableToRecordType (name,
Greg Clayton57ee3062013-07-11 22:46:58 +00002062 var_type->GetClangLayoutType(),
2063 accessibility);
Greg Clayton973b6c92013-04-11 16:57:51 +00002064 }
Greg Claytone528efd72013-02-26 23:45:18 +00002065 break;
Greg Clayton973b6c92013-04-11 16:57:51 +00002066 }
Greg Claytone528efd72013-02-26 23:45:18 +00002067
Greg Clayton24739922010-10-13 03:15:28 +00002068 if (is_artificial == false)
2069 {
2070 Type *member_type = ResolveTypeUID(encoding_uid);
Sean Callananfa3ab452012-12-14 00:54:13 +00002071
Jim Inghame3ae82a2011-11-12 01:36:43 +00002072 clang::FieldDecl *field_decl = NULL;
Sean Callanan751aac62012-03-29 19:07:06 +00002073 if (tag == DW_TAG_member)
Greg Claytond16e1e52011-07-12 17:06:17 +00002074 {
Sean Callanan751aac62012-03-29 19:07:06 +00002075 if (member_type)
2076 {
2077 if (accessibility == eAccessNone)
2078 accessibility = default_accessibility;
2079 member_accessibilities.push_back(accessibility);
Sean Callananfaa0bb32012-12-05 23:37:14 +00002080
Greg Clayton78f4d952013-12-11 23:10:39 +00002081 uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
2082 if (bit_size > 0)
Greg Clayton88bc7f32012-11-06 00:20:41 +00002083 {
Greg Clayton78f4d952013-12-11 23:10:39 +00002084
2085 BitfieldInfo this_field_info;
2086 this_field_info.bit_offset = field_bit_offset;
2087 this_field_info.bit_size = bit_size;
2088
Sean Callananfaa0bb32012-12-05 23:37:14 +00002089 /////////////////////////////////////////////////////////////
2090 // How to locate a field given the DWARF debug information
2091 //
2092 // AT_byte_size indicates the size of the word in which the
2093 // bit offset must be interpreted.
2094 //
2095 // AT_data_member_location indicates the byte offset of the
2096 // word from the base address of the structure.
2097 //
2098 // AT_bit_offset indicates how many bits into the word
2099 // (according to the host endianness) the low-order bit of
2100 // the field starts. AT_bit_offset can be negative.
2101 //
2102 // AT_bit_size indicates the size of the field in bits.
2103 /////////////////////////////////////////////////////////////
2104
Greg Clayton78f4d952013-12-11 23:10:39 +00002105 if (byte_size == 0)
2106 byte_size = member_type->GetByteSize();
2107
Sean Callananfaa0bb32012-12-05 23:37:14 +00002108 if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
2109 {
2110 this_field_info.bit_offset += byte_size * 8;
2111 this_field_info.bit_offset -= (bit_offset + bit_size);
2112 }
2113 else
2114 {
2115 this_field_info.bit_offset += bit_offset;
2116 }
Greg Clayton78f4d952013-12-11 23:10:39 +00002117
2118 // Update the field bit offset we will report for layout
2119 field_bit_offset = this_field_info.bit_offset;
Sean Callananfaa0bb32012-12-05 23:37:14 +00002120
Greg Clayton78f4d952013-12-11 23:10:39 +00002121 // If the member to be emitted did not start on a character boundary and there is
2122 // empty space between the last field and this one, then we need to emit an
2123 // anonymous member filling up the space up to its start. There are three cases
2124 // here:
2125 //
2126 // 1 If the previous member ended on a character boundary, then we can emit an
2127 // anonymous member starting at the most recent character boundary.
2128 //
2129 // 2 If the previous member did not end on a character boundary and the distance
2130 // from the end of the previous member to the current member is less than a
2131 // word width, then we can emit an anonymous member starting right after the
2132 // previous member and right before this member.
2133 //
2134 // 3 If the previous member did not end on a character boundary and the distance
2135 // from the end of the previous member to the current member is greater than
2136 // or equal a word width, then we act as in Case 1.
2137
2138 const uint64_t character_width = 8;
2139 const uint64_t word_width = 32;
2140
Sean Callananfaa0bb32012-12-05 23:37:14 +00002141 // Objective-C has invalid DW_AT_bit_offset values in older versions
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +00002142 // of clang, so we have to be careful and only insert unnamed bitfields
Greg Clayton37c36e42012-11-27 00:59:26 +00002143 // if we have a new enough clang.
2144 bool detect_unnamed_bitfields = true;
Greg Clayton88bc7f32012-11-06 00:20:41 +00002145
Greg Clayton37c36e42012-11-27 00:59:26 +00002146 if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)
2147 detect_unnamed_bitfields = dwarf_cu->Supports_unnamed_objc_bitfields ();
2148
2149 if (detect_unnamed_bitfields)
Greg Clayton88bc7f32012-11-06 00:20:41 +00002150 {
Sean Callananfaa0bb32012-12-05 23:37:14 +00002151 BitfieldInfo anon_field_info;
2152
2153 if ((this_field_info.bit_offset % character_width) != 0) // not char aligned
Greg Clayton88bc7f32012-11-06 00:20:41 +00002154 {
Sean Callananfaa0bb32012-12-05 23:37:14 +00002155 uint64_t last_field_end = 0;
Greg Clayton88bc7f32012-11-06 00:20:41 +00002156
Sean Callananfaa0bb32012-12-05 23:37:14 +00002157 if (last_field_info.IsValid())
2158 last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
Greg Clayton88bc7f32012-11-06 00:20:41 +00002159
Sean Callananfaa0bb32012-12-05 23:37:14 +00002160 if (this_field_info.bit_offset != last_field_end)
2161 {
2162 if (((last_field_end % character_width) == 0) || // case 1
2163 (this_field_info.bit_offset - last_field_end >= word_width)) // case 3
2164 {
2165 anon_field_info.bit_size = this_field_info.bit_offset % character_width;
2166 anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size;
2167 }
2168 else // case 2
2169 {
2170 anon_field_info.bit_size = this_field_info.bit_offset - last_field_end;
2171 anon_field_info.bit_offset = last_field_end;
2172 }
Greg Clayton88bc7f32012-11-06 00:20:41 +00002173 }
Greg Clayton88bc7f32012-11-06 00:20:41 +00002174 }
2175
Sean Callananfaa0bb32012-12-05 23:37:14 +00002176 if (anon_field_info.IsValid())
Greg Clayton88bc7f32012-11-06 00:20:41 +00002177 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002178 clang::FieldDecl *unnamed_bitfield_decl = class_clang_type.AddFieldToRecordType (NULL,
2179 GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
2180 accessibility,
2181 anon_field_info.bit_size);
Zachary Turner504f38d2015-03-24 16:24:50 +00002182
Zachary Turnera98fac22015-03-24 18:56:08 +00002183 layout_info.field_offsets.insert(
Zachary Turner504f38d2015-03-24 16:24:50 +00002184 std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
Greg Clayton88bc7f32012-11-06 00:20:41 +00002185 }
2186 }
Greg Clayton78f4d952013-12-11 23:10:39 +00002187 last_field_info = this_field_info;
2188 }
2189 else
2190 {
2191 last_field_info.Clear();
Greg Clayton88bc7f32012-11-06 00:20:41 +00002192 }
Sean Callananfaa0bb32012-12-05 23:37:14 +00002193
Greg Clayton57ee3062013-07-11 22:46:58 +00002194 ClangASTType member_clang_type = member_type->GetClangLayoutType();
Sean Callananfa3ab452012-12-14 00:54:13 +00002195
2196 {
2197 // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
2198 // If the current field is at the end of the structure, then there is definitely no room for extra
2199 // elements and we override the type to array[0].
2200
Greg Clayton57ee3062013-07-11 22:46:58 +00002201 ClangASTType member_array_element_type;
Sean Callananfa3ab452012-12-14 00:54:13 +00002202 uint64_t member_array_size;
2203 bool member_array_is_incomplete;
2204
Greg Clayton57ee3062013-07-11 22:46:58 +00002205 if (member_clang_type.IsArrayType(&member_array_element_type,
2206 &member_array_size,
2207 &member_array_is_incomplete) &&
Sean Callananfa3ab452012-12-14 00:54:13 +00002208 !member_array_is_incomplete)
2209 {
2210 uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX);
2211
2212 if (member_byte_offset >= parent_byte_size)
2213 {
2214 if (member_array_size != 1)
2215 {
2216 GetObjectFile()->GetModule()->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,
2217 MakeUserID(die->GetOffset()),
2218 name,
2219 encoding_uid,
2220 MakeUserID(parent_die->GetOffset()));
2221 }
2222
Greg Clayton1c8ef472013-04-05 23:27:21 +00002223 member_clang_type = GetClangASTContext().CreateArrayType(member_array_element_type, 0, false);
Sean Callananfa3ab452012-12-14 00:54:13 +00002224 }
2225 }
2226 }
2227
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002228 field_decl = class_clang_type.AddFieldToRecordType (name,
Greg Clayton57ee3062013-07-11 22:46:58 +00002229 member_clang_type,
2230 accessibility,
2231 bit_size);
Sean Callanan60217122012-04-13 00:10:03 +00002232
Greg Claytond0029442013-03-27 01:48:02 +00002233 GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset()));
Greg Clayton78f4d952013-12-11 23:10:39 +00002234
Zachary Turnera98fac22015-03-24 18:56:08 +00002235 layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset));
Sean Callanan5b26f272012-02-04 08:49:35 +00002236 }
2237 else
2238 {
Sean Callanan751aac62012-03-29 19:07:06 +00002239 if (name)
Daniel Malead01b2952012-11-29 21:49:15 +00002240 GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
Sean Callanan751aac62012-03-29 19:07:06 +00002241 MakeUserID(die->GetOffset()),
2242 name,
2243 encoding_uid);
2244 else
Daniel Malead01b2952012-11-29 21:49:15 +00002245 GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
Sean Callanan751aac62012-03-29 19:07:06 +00002246 MakeUserID(die->GetOffset()),
2247 encoding_uid);
Sean Callanan5b26f272012-02-04 08:49:35 +00002248 }
Greg Claytoncaab74e2012-01-28 00:48:57 +00002249 }
Sean Callanan751aac62012-03-29 19:07:06 +00002250
Greg Clayton3ca8f422015-07-13 22:08:16 +00002251 if (prop_name != NULL && member_type)
Jim Inghame3ae82a2011-11-12 01:36:43 +00002252 {
Sean Callanan751aac62012-03-29 19:07:06 +00002253 clang::ObjCIvarDecl *ivar_decl = NULL;
Jim Inghame3ae82a2011-11-12 01:36:43 +00002254
Sean Callanan751aac62012-03-29 19:07:06 +00002255 if (field_decl)
2256 {
2257 ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
2258 assert (ivar_decl != NULL);
2259 }
Jim Inghame3ae82a2011-11-12 01:36:43 +00002260
Jim Ingham379397632012-10-27 02:54:13 +00002261 ClangASTMetadata metadata;
2262 metadata.SetUserID (MakeUserID(die->GetOffset()));
Greg Clayton57ee3062013-07-11 22:46:58 +00002263 delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type,
Sean Callanana0b80ab2012-06-04 22:28:05 +00002264 prop_name,
2265 member_type->GetClangLayoutType(),
2266 ivar_decl,
2267 prop_setter_name,
2268 prop_getter_name,
2269 prop_attributes,
Jim Ingham379397632012-10-27 02:54:13 +00002270 &metadata));
Sean Callanan60217122012-04-13 00:10:03 +00002271
Sean Callananad880762012-04-18 01:06:17 +00002272 if (ivar_decl)
Greg Claytond0029442013-03-27 01:48:02 +00002273 GetClangASTContext().SetMetadataAsUserID (ivar_decl, MakeUserID(die->GetOffset()));
Jim Inghame3ae82a2011-11-12 01:36:43 +00002274 }
Greg Clayton24739922010-10-13 03:15:28 +00002275 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002276 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00002277 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002278 }
2279 break;
2280
2281 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00002282 // Let the type parsing code handle this one for us.
2283 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002284 break;
2285
2286 case DW_TAG_inheritance:
2287 {
2288 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00002289 if (default_accessibility == eAccessNone)
2290 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002291 // TODO: implement DW_TAG_inheritance type parsing
2292 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00002293 const size_t num_attributes = die->GetAttributes (this,
2294 dwarf_cu,
2295 fixed_form_sizes,
2296 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002297 if (num_attributes > 0)
2298 {
2299 Declaration decl;
2300 DWARFExpression location;
2301 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00002302 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002303 bool is_virtual = false;
2304 bool is_base_of_class = true;
Greg Clayton2508b9b2012-11-01 23:20:02 +00002305 off_t member_byte_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002306 uint32_t i;
2307 for (i=0; i<num_attributes; ++i)
2308 {
2309 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2310 DWARFFormValue form_value;
2311 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2312 {
2313 switch (attr)
2314 {
2315 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2316 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2317 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00002318 case DW_AT_type: encoding_uid = form_value.Reference(); break;
Greg Clayton2508b9b2012-11-01 23:20:02 +00002319 case DW_AT_data_member_location:
2320 if (form_value.BlockData())
2321 {
2322 Value initialValue(0);
2323 Value memberOffset(0);
Ed Masteeeae7212013-10-24 20:43:47 +00002324 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Clayton2508b9b2012-11-01 23:20:02 +00002325 uint32_t block_length = form_value.Unsigned();
2326 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
2327 if (DWARFExpression::Evaluate (NULL,
2328 NULL,
2329 NULL,
Greg Clayton2508b9b2012-11-01 23:20:02 +00002330 NULL,
Richard Mitton0a558352013-10-17 21:14:00 +00002331 module,
Greg Clayton2508b9b2012-11-01 23:20:02 +00002332 debug_info_data,
2333 block_offset,
2334 block_length,
2335 eRegisterKindDWARF,
2336 &initialValue,
2337 memberOffset,
2338 NULL))
2339 {
Greg Clayton57ee3062013-07-11 22:46:58 +00002340 member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
Greg Clayton2508b9b2012-11-01 23:20:02 +00002341 }
2342 }
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00002343 else
2344 {
2345 // With DWARF 3 and later, if the value is an integer constant,
2346 // this form value is the offset in bytes from the beginning
2347 // of the containing entity.
2348 member_byte_offset = form_value.Unsigned();
2349 }
Greg Clayton2508b9b2012-11-01 23:20:02 +00002350 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002351
2352 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00002353 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002354 break;
2355
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00002356 case DW_AT_virtuality:
2357 is_virtual = form_value.Boolean();
2358 break;
2359
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002360 case DW_AT_sibling:
2361 break;
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00002362
2363 default:
2364 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002365 }
2366 }
2367 }
2368
Greg Clayton526e5af2010-11-13 03:52:47 +00002369 Type *base_class_type = ResolveTypeUID(encoding_uid);
Greg Clayton898c1b22015-05-15 22:31:18 +00002370 if (base_class_type == NULL)
2371 {
Bruce Mitchener58ef3912015-06-18 05:27:05 +00002372 GetObjectFile()->GetModule()->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",
Greg Clayton898c1b22015-05-15 22:31:18 +00002373 die->GetOffset(),
2374 encoding_uid,
2375 parent_die->GetOffset());
2376 break;
2377 }
2378
Greg Clayton57ee3062013-07-11 22:46:58 +00002379 ClangASTType base_class_clang_type = base_class_type->GetClangFullType();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00002380 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00002381 if (class_language == eLanguageTypeObjC)
2382 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002383 class_clang_type.SetObjCSuperClass(base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00002384 }
2385 else
2386 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002387 base_classes.push_back (base_class_clang_type.CreateBaseClassSpecifier (accessibility,
2388 is_virtual,
2389 is_base_of_class));
Greg Clayton2508b9b2012-11-01 23:20:02 +00002390
2391 if (is_virtual)
2392 {
Greg Clayton52694e32013-09-16 21:57:07 +00002393 // Do not specify any offset for virtual inheritance. The DWARF produced by clang doesn't
2394 // give us a constant offset, but gives us a DWARF expressions that requires an actual object
2395 // in memory. the DW_AT_data_member_location for a virtual base class looks like:
2396 // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, DW_OP_plus )
2397 // Given this, there is really no valid response we can give to clang for virtual base
2398 // class offsets, and this should eventually be removed from LayoutRecordType() in the external
2399 // AST source in clang.
Greg Clayton2508b9b2012-11-01 23:20:02 +00002400 }
2401 else
2402 {
Zachary Turnera98fac22015-03-24 18:56:08 +00002403 layout_info.base_offsets.insert(
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002404 std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(),
Zachary Turner504f38d2015-03-24 16:24:50 +00002405 clang::CharUnits::fromQuantity(member_byte_offset)));
Greg Clayton2508b9b2012-11-01 23:20:02 +00002406 }
Greg Clayton9e409562010-07-28 02:04:09 +00002407 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002408 }
2409 }
2410 break;
2411
2412 default:
2413 break;
2414 }
2415 }
Sean Callanana0b80ab2012-06-04 22:28:05 +00002416
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002417 return count;
2418}
2419
2420
2421clang::DeclContext*
Sean Callanan72e49402011-08-05 23:43:37 +00002422SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002423{
2424 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton81c22f62011-10-19 18:09:39 +00002425 if (debug_info && UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002426 {
2427 DWARFCompileUnitSP cu_sp;
2428 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
2429 if (die)
Greg Claytoncb5860a2011-10-13 23:49:28 +00002430 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
Sean Callanan72e49402011-08-05 23:43:37 +00002431 }
2432 return NULL;
2433}
2434
2435clang::DeclContext*
2436SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
2437{
Greg Clayton81c22f62011-10-19 18:09:39 +00002438 if (UserIDMatches(type_uid))
2439 return GetClangDeclContextForDIEOffset (sc, type_uid);
2440 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002441}
2442
2443Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00002444SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002445{
Greg Clayton81c22f62011-10-19 18:09:39 +00002446 if (UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002447 {
Greg Clayton81c22f62011-10-19 18:09:39 +00002448 DWARFDebugInfo* debug_info = DebugInfo();
2449 if (debug_info)
Greg Claytonca512b32011-01-14 04:54:56 +00002450 {
Greg Clayton81c22f62011-10-19 18:09:39 +00002451 DWARFCompileUnitSP cu_sp;
2452 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Greg Claytoncab36a32011-12-08 05:16:30 +00002453 const bool assert_not_being_parsed = true;
2454 return ResolveTypeUID (cu_sp.get(), type_die, assert_not_being_parsed);
Greg Claytonca512b32011-01-14 04:54:56 +00002455 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002456 }
2457 return NULL;
2458}
2459
Greg Claytoncab36a32011-12-08 05:16:30 +00002460Type*
2461SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed)
Sean Callanan5b26f272012-02-04 08:49:35 +00002462{
Greg Claytoncab36a32011-12-08 05:16:30 +00002463 if (die != NULL)
2464 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002465 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00002466 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002467 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002468 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
2469 die->GetOffset(),
2470 DW_TAG_value_to_name(die->Tag()),
2471 die->GetName(this, cu));
Greg Clayton3bffb082011-12-10 02:15:28 +00002472
Greg Claytoncab36a32011-12-08 05:16:30 +00002473 // We might be coming in in the middle of a type tree (a class
2474 // withing a class, an enum within a class), so parse any needed
2475 // parent DIEs before we get to this one...
2476 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
2477 switch (decl_ctx_die->Tag())
2478 {
2479 case DW_TAG_structure_type:
2480 case DW_TAG_union_type:
2481 case DW_TAG_class_type:
2482 {
2483 // Get the type, which could be a forward declaration
Greg Clayton3bffb082011-12-10 02:15:28 +00002484 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002485 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002486 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
2487 die->GetOffset(),
2488 DW_TAG_value_to_name(die->Tag()),
2489 die->GetName(this, cu),
2490 decl_ctx_die->GetOffset());
Greg Clayton219cf312012-03-30 00:51:13 +00002491//
2492// Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
2493// if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
2494// {
2495// if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002496// GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton219cf312012-03-30 00:51:13 +00002497// "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function",
2498// die->GetOffset(),
2499// DW_TAG_value_to_name(die->Tag()),
2500// die->GetName(this, cu),
2501// decl_ctx_die->GetOffset());
2502// // Ask the type to complete itself if it already hasn't since if we
2503// // want a function (method or static) from a class, the class must
2504// // create itself and add it's own methods and class functions.
2505// if (parent_type)
2506// parent_type->GetClangFullType();
2507// }
Greg Claytoncab36a32011-12-08 05:16:30 +00002508 }
2509 break;
2510
2511 default:
2512 break;
2513 }
2514 return ResolveType (cu, die);
2515 }
2516 return NULL;
2517}
2518
Greg Clayton6beaaa62011-01-17 03:46:26 +00002519// This function is used when SymbolFileDWARFDebugMap owns a bunch of
2520// SymbolFileDWARF objects to detect if this DWARF file is the one that
2521// can resolve a clang_type.
2522bool
Greg Clayton57ee3062013-07-11 22:46:58 +00002523SymbolFileDWARF::HasForwardDeclForClangType (const ClangASTType &clang_type)
Greg Clayton6beaaa62011-01-17 03:46:26 +00002524{
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002525 ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
Greg Clayton57ee3062013-07-11 22:46:58 +00002526 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002527 return die != NULL;
2528}
2529
2530
Greg Clayton57ee3062013-07-11 22:46:58 +00002531bool
2532SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00002533{
2534 // We have a struct/union/class/enum that needs to be fully resolved.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002535 ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
Greg Clayton57ee3062013-07-11 22:46:58 +00002536 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
Greg Clayton1be10fc2010-09-29 01:12:09 +00002537 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00002538 {
2539 // We have already resolved this type...
Greg Clayton57ee3062013-07-11 22:46:58 +00002540 return true;
Greg Clayton73b472d2010-10-27 03:32:59 +00002541 }
2542 // Once we start resolving this type, remove it from the forward declaration
2543 // map in case anyone child members or other types require this type to get resolved.
2544 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
2545 // are done.
Greg Clayton57ee3062013-07-11 22:46:58 +00002546 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType());
Greg Clayton1be10fc2010-09-29 01:12:09 +00002547
Greg Clayton85ae2e12011-10-18 23:36:41 +00002548 // Disable external storage for this type so we don't get anymore
2549 // clang::ExternalASTSource queries for this type.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002550 clang_type.SetHasExternalStorage (false);
Greg Clayton85ae2e12011-10-18 23:36:41 +00002551
Greg Clayton450e3f32010-10-12 02:24:53 +00002552 DWARFDebugInfo* debug_info = DebugInfo();
2553
Greg Clayton53eb1c22012-04-02 22:59:12 +00002554 DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002555 Type *type = m_die_to_type.lookup (die);
2556
2557 const dw_tag_t tag = die->Tag();
2558
Greg Clayton5160ce52013-03-27 23:08:40 +00002559 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
Greg Clayton3bffb082011-12-10 02:15:28 +00002560 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002561 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
Daniel Malead01b2952012-11-29 21:49:15 +00002562 "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
Greg Claytond61c0fc2012-04-23 22:55:20 +00002563 MakeUserID(die->GetOffset()),
2564 DW_TAG_value_to_name(tag),
2565 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00002566 assert (clang_type);
2567 DWARFDebugInfoEntry::Attributes attributes;
2568
Greg Clayton1be10fc2010-09-29 01:12:09 +00002569 switch (tag)
2570 {
2571 case DW_TAG_structure_type:
2572 case DW_TAG_union_type:
2573 case DW_TAG_class_type:
Greg Claytonc93237c2010-10-01 20:48:32 +00002574 {
Greg Claytoncaab74e2012-01-28 00:48:57 +00002575 LayoutInfo layout_info;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002576
Greg Clayton1be10fc2010-09-29 01:12:09 +00002577 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002578 if (die->HasChildren())
Greg Claytonc93237c2010-10-01 20:48:32 +00002579 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002580 LanguageType class_language = eLanguageTypeUnknown;
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002581 if (clang_type.IsObjCObjectOrInterfaceType())
Greg Clayton219cf312012-03-30 00:51:13 +00002582 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002583 class_language = eLanguageTypeObjC;
Greg Clayton219cf312012-03-30 00:51:13 +00002584 // For objective C we don't start the definition when
2585 // the class is created.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002586 clang_type.StartTagDeclarationDefinition ();
Greg Clayton219cf312012-03-30 00:51:13 +00002587 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002588
Sean Callanan77a1fd32012-02-27 20:07:01 +00002589 int tag_decl_kind = -1;
2590 AccessType default_accessibility = eAccessNone;
2591 if (tag == DW_TAG_structure_type)
2592 {
2593 tag_decl_kind = clang::TTK_Struct;
2594 default_accessibility = eAccessPublic;
2595 }
2596 else if (tag == DW_TAG_union_type)
2597 {
2598 tag_decl_kind = clang::TTK_Union;
2599 default_accessibility = eAccessPublic;
2600 }
2601 else if (tag == DW_TAG_class_type)
2602 {
2603 tag_decl_kind = clang::TTK_Class;
2604 default_accessibility = eAccessPrivate;
2605 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002606
Greg Clayton53eb1c22012-04-02 22:59:12 +00002607 SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
Sean Callanan77a1fd32012-02-27 20:07:01 +00002608 std::vector<clang::CXXBaseSpecifier *> base_classes;
2609 std::vector<int> member_accessibilities;
2610 bool is_a_class = false;
2611 // Parse members and base classes first
2612 DWARFDIECollection member_function_dies;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002613
Sean Callanana0b80ab2012-06-04 22:28:05 +00002614 DelayedPropertyList delayed_properties;
Greg Clayton88bc7f32012-11-06 00:20:41 +00002615 ParseChildMembers (sc,
Greg Clayton53eb1c22012-04-02 22:59:12 +00002616 dwarf_cu,
Sean Callanan77a1fd32012-02-27 20:07:01 +00002617 die,
2618 clang_type,
2619 class_language,
2620 base_classes,
2621 member_accessibilities,
2622 member_function_dies,
Sean Callanana0b80ab2012-06-04 22:28:05 +00002623 delayed_properties,
Sean Callanan77a1fd32012-02-27 20:07:01 +00002624 default_accessibility,
2625 is_a_class,
2626 layout_info);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002627
Sean Callanan77a1fd32012-02-27 20:07:01 +00002628 // Now parse any methods if there were any...
2629 size_t num_functions = member_function_dies.Size();
2630 if (num_functions > 0)
2631 {
2632 for (size_t i=0; i<num_functions; ++i)
Greg Claytond4a2b372011-09-12 23:21:58 +00002633 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00002634 ResolveType(dwarf_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytoncaab74e2012-01-28 00:48:57 +00002635 }
Sean Callanan77a1fd32012-02-27 20:07:01 +00002636 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002637
Sean Callanan77a1fd32012-02-27 20:07:01 +00002638 if (class_language == eLanguageTypeObjC)
2639 {
Jim Inghamfb6fc0d2013-09-27 20:59:37 +00002640 ConstString class_name (clang_type.GetTypeName());
2641 if (class_name)
Greg Claytoncaab74e2012-01-28 00:48:57 +00002642 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002643 DIEArray method_die_offsets;
2644 if (m_using_apple_tables)
Greg Clayton95d87902011-11-11 03:16:25 +00002645 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002646 if (m_apple_objc_ap.get())
Jim Inghamfb6fc0d2013-09-27 20:59:37 +00002647 m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
Sean Callanan77a1fd32012-02-27 20:07:01 +00002648 }
2649 else
2650 {
2651 if (!m_indexed)
2652 Index ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002653
Sean Callanan77a1fd32012-02-27 20:07:01 +00002654 m_objc_class_selectors_index.Find (class_name, method_die_offsets);
2655 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002656
Sean Callanan77a1fd32012-02-27 20:07:01 +00002657 if (!method_die_offsets.empty())
2658 {
2659 DWARFDebugInfo* debug_info = DebugInfo();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002660
Sean Callanan77a1fd32012-02-27 20:07:01 +00002661 DWARFCompileUnit* method_cu = NULL;
2662 const size_t num_matches = method_die_offsets.size();
2663 for (size_t i=0; i<num_matches; ++i)
Greg Clayton95d87902011-11-11 03:16:25 +00002664 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002665 const dw_offset_t die_offset = method_die_offsets[i];
2666 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002667
Sean Callanan77a1fd32012-02-27 20:07:01 +00002668 if (method_die)
2669 ResolveType (method_cu, method_die);
2670 else
Greg Claytoncaab74e2012-01-28 00:48:57 +00002671 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002672 if (m_using_apple_tables)
2673 {
2674 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n",
Jim Inghamfb6fc0d2013-09-27 20:59:37 +00002675 die_offset, class_name.GetCString());
Sean Callanan77a1fd32012-02-27 20:07:01 +00002676 }
2677 }
2678 }
Greg Claytoncaab74e2012-01-28 00:48:57 +00002679 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002680
Greg Clayton57ee3062013-07-11 22:46:58 +00002681 for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
Sean Callanana0b80ab2012-06-04 22:28:05 +00002682 pi != pe;
2683 ++pi)
2684 pi->Finalize();
Greg Clayton450e3f32010-10-12 02:24:53 +00002685 }
2686 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002687
Sean Callanan77a1fd32012-02-27 20:07:01 +00002688 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2689 // need to tell the clang type it is actually a class.
2690 if (class_language != eLanguageTypeObjC)
2691 {
2692 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002693 clang_type.SetTagTypeKind (clang::TTK_Class);
Sean Callanan77a1fd32012-02-27 20:07:01 +00002694 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002695
Sean Callanan77a1fd32012-02-27 20:07:01 +00002696 // Since DW_TAG_structure_type gets used for both classes
2697 // and structures, we may need to set any DW_TAG_member
2698 // fields to have a "private" access if none was specified.
2699 // When we parsed the child members we tracked that actual
2700 // accessibility value for each DW_TAG_member in the
2701 // "member_accessibilities" array. If the value for the
2702 // member is zero, then it was set to the "default_accessibility"
2703 // which for structs was "public". Below we correct this
2704 // by setting any fields to "private" that weren't correctly
2705 // set.
2706 if (is_a_class && !member_accessibilities.empty())
2707 {
2708 // This is a class and all members that didn't have
2709 // their access specified are private.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002710 clang_type.SetDefaultAccessForRecordFields (eAccessPrivate,
2711 &member_accessibilities.front(),
2712 member_accessibilities.size());
Sean Callanan77a1fd32012-02-27 20:07:01 +00002713 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002714
Sean Callanan77a1fd32012-02-27 20:07:01 +00002715 if (!base_classes.empty())
2716 {
Greg Clayton4705f8d2013-12-12 01:54:04 +00002717 // Make sure all base classes refer to complete types and not
2718 // forward declarations. If we don't do this, clang will crash
2719 // with an assertion in the call to clang_type.SetBaseClassesForClassType()
2720 bool base_class_error = false;
2721 for (auto &base_class : base_classes)
2722 {
2723 clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo();
2724 if (type_source_info)
2725 {
2726 ClangASTType base_class_type (GetClangASTContext().getASTContext(), type_source_info->getType());
2727 if (base_class_type.GetCompleteType() == false)
2728 {
2729 if (!base_class_error)
2730 {
2731 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",
2732 die->GetOffset(),
2733 die->GetName(this, dwarf_cu),
2734 base_class_type.GetTypeName().GetCString(),
2735 sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
2736 }
2737 // We have no choice other than to pretend that the base class
2738 // is complete. If we don't do this, clang will crash when we
2739 // call setBases() inside of "clang_type.SetBaseClassesForClassType()"
2740 // below. Since we provide layout assistance, all ivars in this
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002741 // class and other classes will be fine, this is the best we can do
Greg Clayton4705f8d2013-12-12 01:54:04 +00002742 // short of crashing.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002743 base_class_type.StartTagDeclarationDefinition ();
2744 base_class_type.CompleteTagDeclarationDefinition ();
Greg Clayton4705f8d2013-12-12 01:54:04 +00002745 }
2746 }
2747 }
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002748 clang_type.SetBaseClassesForClassType (&base_classes.front(),
2749 base_classes.size());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002750
Sean Callanan77a1fd32012-02-27 20:07:01 +00002751 // Clang will copy each CXXBaseSpecifier in "base_classes"
2752 // so we have to free them all.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002753 ClangASTType::DeleteBaseClassSpecifiers (&base_classes.front(),
2754 base_classes.size());
Sean Callanan77a1fd32012-02-27 20:07:01 +00002755 }
Greg Clayton450e3f32010-10-12 02:24:53 +00002756 }
Greg Claytonc93237c2010-10-01 20:48:32 +00002757 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002758
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002759 clang_type.BuildIndirectFields ();
2760 clang_type.CompleteTagDeclarationDefinition ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002761
Greg Clayton2508b9b2012-11-01 23:20:02 +00002762 if (!layout_info.field_offsets.empty() ||
2763 !layout_info.base_offsets.empty() ||
2764 !layout_info.vbase_offsets.empty() )
Greg Claytoncaab74e2012-01-28 00:48:57 +00002765 {
2766 if (type)
2767 layout_info.bit_size = type->GetByteSize() * 8;
2768 if (layout_info.bit_size == 0)
Greg Clayton53eb1c22012-04-02 22:59:12 +00002769 layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002770
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002771 clang::CXXRecordDecl *record_decl = clang_type.GetAsCXXRecordDecl();
Greg Clayton2508b9b2012-11-01 23:20:02 +00002772 if (record_decl)
Greg Claytoncaab74e2012-01-28 00:48:57 +00002773 {
Greg Claytoncaab74e2012-01-28 00:48:57 +00002774 if (log)
Greg Clayton821ac6d2012-01-28 02:22:27 +00002775 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002776 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00002777 "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002778 static_cast<void*>(clang_type.GetOpaqueQualType()),
2779 static_cast<void*>(record_decl),
Greg Claytoncaab74e2012-01-28 00:48:57 +00002780 layout_info.bit_size,
2781 layout_info.alignment,
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002782 static_cast<uint32_t>(layout_info.field_offsets.size()),
2783 static_cast<uint32_t>(layout_info.base_offsets.size()),
2784 static_cast<uint32_t>(layout_info.vbase_offsets.size()));
2785
Zachary Turnera98fac22015-03-24 18:56:08 +00002786 uint32_t idx;
2787 {
2788 llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos,
2789 end = layout_info.field_offsets.end();
2790 for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx)
Greg Clayton2508b9b2012-11-01 23:20:02 +00002791 {
Zachary Turner504f38d2015-03-24 16:24:50 +00002792 GetObjectFile()->GetModule()->LogMessage(
2793 log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = "
2794 "{ bit_offset=%u, name='%s' }",
Zachary Turner504f38d2015-03-24 16:24:50 +00002795 static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
Zachary Turnera98fac22015-03-24 18:56:08 +00002796 static_cast<uint32_t>(pos->second), pos->first->getNameAsString().c_str());
2797 }
2798 }
2799
2800 {
2801 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos,
2802 base_end = layout_info.base_offsets.end();
2803 for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end;
2804 ++base_pos, ++idx)
2805 {
2806 GetObjectFile()->GetModule()->LogMessage(
2807 log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] "
2808 "= { byte_offset=%u, name='%s' }",
2809 clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(),
2810 base_pos->first->getNameAsString().c_str());
2811 }
2812 }
2813 {
2814 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos,
2815 vbase_end = layout_info.vbase_offsets.end();
2816 for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end;
2817 ++vbase_pos, ++idx)
2818 {
2819 GetObjectFile()->GetModule()->LogMessage(
2820 log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) "
2821 "vbase[%u] = { byte_offset=%u, name='%s' }",
2822 static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
2823 static_cast<uint32_t>(vbase_pos->second.getQuantity()),
2824 vbase_pos->first->getNameAsString().c_str());
2825 }
Greg Clayton2508b9b2012-11-01 23:20:02 +00002826 }
Greg Clayton821ac6d2012-01-28 02:22:27 +00002827 }
Greg Claytoncaab74e2012-01-28 00:48:57 +00002828 m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
2829 }
2830 }
Greg Claytonc93237c2010-10-01 20:48:32 +00002831 }
Sean Callanan77a1fd32012-02-27 20:07:01 +00002832
Sean Callanan9076c0f2013-10-04 21:35:29 +00002833 return (bool)clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002834
2835 case DW_TAG_enumeration_type:
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002836 clang_type.StartTagDeclarationDefinition ();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002837 if (die->HasChildren())
2838 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00002839 SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
Greg Clayton3e067532013-03-05 23:54:39 +00002840 bool is_signed = false;
Greg Clayton57ee3062013-07-11 22:46:58 +00002841 clang_type.IsIntegerType(is_signed);
Greg Clayton3e067532013-03-05 23:54:39 +00002842 ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002843 }
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002844 clang_type.CompleteTagDeclarationDefinition ();
Sean Callanan9076c0f2013-10-04 21:35:29 +00002845 return (bool)clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002846
2847 default:
2848 assert(false && "not a forward clang type decl!");
2849 break;
2850 }
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00002851 return false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002852}
2853
Greg Claytonc685f8e2010-09-15 04:15:46 +00002854Type*
Greg Clayton53eb1c22012-04-02 22:59:12 +00002855SymbolFileDWARF::ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002856{
2857 if (type_die != NULL)
2858 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002859 Type *type = m_die_to_type.lookup (type_die);
Greg Claytoncab36a32011-12-08 05:16:30 +00002860
Greg Claytonc685f8e2010-09-15 04:15:46 +00002861 if (type == NULL)
Greg Clayton53eb1c22012-04-02 22:59:12 +00002862 type = GetTypeForDIE (dwarf_cu, type_die).get();
Greg Claytoncab36a32011-12-08 05:16:30 +00002863
Greg Clayton24739922010-10-13 03:15:28 +00002864 if (assert_not_being_parsed)
Jim Inghamc3549282012-01-11 02:21:12 +00002865 {
2866 if (type != DIE_IS_BEING_PARSED)
2867 return type;
2868
2869 GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
Greg Clayton53eb1c22012-04-02 22:59:12 +00002870 type_die->GetOffset(),
2871 DW_TAG_value_to_name(type_die->Tag()),
2872 type_die->GetName(this, dwarf_cu));
Jim Inghamc3549282012-01-11 02:21:12 +00002873
2874 }
2875 else
2876 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002877 }
2878 return NULL;
2879}
2880
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002881CompileUnit*
Greg Clayton53eb1c22012-04-02 22:59:12 +00002882SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002883{
2884 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton53eb1c22012-04-02 22:59:12 +00002885 if (dwarf_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002886 {
2887 // The symbol vendor doesn't know about this compile unit, we
2888 // need to parse and add it to the symbol vendor object.
Greg Clayton53eb1c22012-04-02 22:59:12 +00002889 return ParseCompileUnit(dwarf_cu, cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002890 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00002891 return (CompileUnit*)dwarf_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002892}
2893
2894bool
Greg Clayton53eb1c22012-04-02 22:59:12 +00002895SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002896{
Greg Clayton72310352013-02-23 04:12:47 +00002897 sc.Clear(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002898 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton53eb1c22012-04-02 22:59:12 +00002899 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002900
Greg Clayton81c22f62011-10-19 18:09:39 +00002901 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002902 if (sc.function == NULL)
Greg Clayton53eb1c22012-04-02 22:59:12 +00002903 sc.function = ParseCompileUnitFunction(sc, dwarf_cu, func_die);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002904
2905 if (sc.function)
2906 {
Greg Claytone72dfb32012-02-24 01:59:29 +00002907 sc.module_sp = sc.function->CalculateSymbolContextModule();
Jim Ingham4cda6e02011-10-07 22:23:45 +00002908 return true;
2909 }
2910
2911 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002912}
2913
Sean Callananf0c5aeb2015-04-20 16:31:29 +00002914void
2915SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
2916{
2917 if (m_fetched_external_modules)
2918 return;
2919 m_fetched_external_modules = true;
2920
2921 DWARFDebugInfo * debug_info = DebugInfo();
2922 debug_info->GetNumCompileUnits();
2923
2924 const uint32_t num_compile_units = GetNumCompileUnits();
2925 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2926 {
2927 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
2928
2929 const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
2930 if (die && die->HasChildren() == false)
2931 {
2932 const uint64_t name_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_name, UINT64_MAX);
2933 const uint64_t dwo_path_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_GNU_dwo_name, UINT64_MAX);
2934
2935 if (name_strp != UINT64_MAX)
2936 {
2937 if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
2938 {
2939 const char *name = get_debug_str_data().PeekCStr(name_strp);
2940 const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);
2941 if (name || dwo_path)
2942 {
2943 ModuleSP module_sp;
2944 if (dwo_path)
2945 {
2946 ModuleSpec dwo_module_spec;
2947 dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
2948 dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
2949 //printf ("Loading dwo = '%s'\n", dwo_path);
2950 Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
2951 }
2952
2953 if (dwo_path_strp != LLDB_INVALID_UID)
2954 {
2955 m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };
2956 }
2957 else
2958 {
2959 // This hack should be removed promptly once clang emits both.
2960 m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };
2961 }
2962 }
2963 }
2964 }
2965 }
2966 }
2967}
Greg Clayton2501e5e2015-01-15 02:59:20 +00002968
2969SymbolFileDWARF::GlobalVariableMap &
2970SymbolFileDWARF::GetGlobalAranges()
2971{
2972 if (!m_global_aranges_ap)
2973 {
2974 m_global_aranges_ap.reset (new GlobalVariableMap());
2975
2976 ModuleSP module_sp = GetObjectFile()->GetModule();
2977 if (module_sp)
2978 {
2979 const size_t num_cus = module_sp->GetNumCompileUnits();
2980 for (size_t i = 0; i < num_cus; ++i)
2981 {
2982 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
2983 if (cu_sp)
2984 {
2985 VariableListSP globals_sp = cu_sp->GetVariableList(true);
2986 if (globals_sp)
2987 {
2988 const size_t num_globals = globals_sp->GetSize();
2989 for (size_t g = 0; g < num_globals; ++g)
2990 {
2991 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
2992 if (var_sp && !var_sp->GetLocationIsConstantValueData())
2993 {
2994 const DWARFExpression &location = var_sp->LocationExpression();
2995 Value location_result;
2996 Error error;
2997 if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
2998 {
2999 if (location_result.GetValueType() == Value::eValueTypeFileAddress)
3000 {
3001 lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
3002 lldb::addr_t byte_size = 1;
3003 if (var_sp->GetType())
3004 byte_size = var_sp->GetType()->GetByteSize();
3005 m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
3006 }
3007 }
3008 }
3009 }
3010 }
3011 }
3012 }
3013 }
3014 m_global_aranges_ap->Sort();
3015 }
3016 return *m_global_aranges_ap;
3017}
3018
3019
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003020uint32_t
3021SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
3022{
3023 Timer scoped_timer(__PRETTY_FUNCTION__,
Daniel Malead01b2952012-11-29 21:49:15 +00003024 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003025 static_cast<void*>(so_addr.GetSection().get()),
3026 so_addr.GetOffset(), resolve_scope);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003027 uint32_t resolved = 0;
Greg Clayton2501e5e2015-01-15 02:59:20 +00003028 if (resolve_scope & ( eSymbolContextCompUnit |
3029 eSymbolContextFunction |
3030 eSymbolContextBlock |
3031 eSymbolContextLineEntry |
3032 eSymbolContextVariable ))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003033 {
3034 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
3035
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003036 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00003037 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003038 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003039 const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Greg Clayton2501e5e2015-01-15 02:59:20 +00003040 if (cu_offset == DW_INVALID_OFFSET)
3041 {
3042 // Global variables are not in the compile unit address ranges. The only way to
3043 // currently find global variables is to iterate over the .debug_pubnames or the
3044 // __apple_names table and find all items in there that point to DW_TAG_variable
3045 // DIEs and then find the address that matches.
3046 if (resolve_scope & eSymbolContextVariable)
3047 {
3048 GlobalVariableMap &map = GetGlobalAranges();
3049 const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
3050 if (entry && entry->data)
3051 {
3052 Variable *variable = entry->data;
3053 SymbolContextScope *scc = variable->GetSymbolContextScope();
3054 if (scc)
3055 {
3056 scc->CalculateSymbolContext(&sc);
3057 sc.variable = variable;
3058 }
3059 return sc.GetResolvedMask();
3060 }
3061 }
3062 }
3063 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003064 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003065 uint32_t cu_idx = DW_INVALID_INDEX;
Greg Clayton53eb1c22012-04-02 22:59:12 +00003066 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
3067 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003068 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003069 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00003070 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003071 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003072 resolved |= eSymbolContextCompUnit;
3073
Greg Clayton6ab80132012-12-12 17:30:52 +00003074 bool force_check_line_table = false;
Greg Clayton526a4ae2012-05-16 22:09:01 +00003075 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
3076 {
3077 DWARFDebugInfoEntry *function_die = NULL;
3078 DWARFDebugInfoEntry *block_die = NULL;
3079 if (resolve_scope & eSymbolContextBlock)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003080 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003081 dwarf_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
3082 }
3083 else
3084 {
3085 dwarf_cu->LookupAddress(file_vm_addr, &function_die, NULL);
3086 }
3087
3088 if (function_die != NULL)
3089 {
3090 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
3091 if (sc.function == NULL)
3092 sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
3093 }
3094 else
3095 {
3096 // We might have had a compile unit that had discontiguous
3097 // address ranges where the gaps are symbols that don't have
3098 // any debug info. Discontiguous compile unit address ranges
3099 // should only happen when there aren't other functions from
3100 // other compile units in these gaps. This helps keep the size
3101 // of the aranges down.
Greg Clayton6ab80132012-12-12 17:30:52 +00003102 force_check_line_table = true;
Greg Clayton526a4ae2012-05-16 22:09:01 +00003103 }
3104
3105 if (sc.function != NULL)
3106 {
3107 resolved |= eSymbolContextFunction;
3108
3109 if (resolve_scope & eSymbolContextBlock)
3110 {
3111 Block& block = sc.function->GetBlock (true);
3112
3113 if (block_die != NULL)
3114 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
3115 else
3116 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
3117 if (sc.block)
3118 resolved |= eSymbolContextBlock;
3119 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003120 }
3121 }
Greg Clayton6ab80132012-12-12 17:30:52 +00003122
3123 if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
3124 {
3125 LineTable *line_table = sc.comp_unit->GetLineTable();
3126 if (line_table != NULL)
3127 {
Greg Clayton9422dd62013-03-04 21:46:16 +00003128 // And address that makes it into this function should be in terms
3129 // of this debug file if there is no debug map, or it will be an
3130 // address in the .o file which needs to be fixed up to be in terms
3131 // of the debug map executable. Either way, calling FixupAddress()
3132 // will work for us.
3133 Address exe_so_addr (so_addr);
3134 if (FixupAddress(exe_so_addr))
Greg Clayton6ab80132012-12-12 17:30:52 +00003135 {
Greg Clayton9422dd62013-03-04 21:46:16 +00003136 if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
Greg Clayton6ab80132012-12-12 17:30:52 +00003137 {
3138 resolved |= eSymbolContextLineEntry;
3139 }
3140 }
Greg Clayton6ab80132012-12-12 17:30:52 +00003141 }
3142 }
3143
3144 if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
3145 {
3146 // We might have had a compile unit that had discontiguous
3147 // address ranges where the gaps are symbols that don't have
3148 // any debug info. Discontiguous compile unit address ranges
3149 // should only happen when there aren't other functions from
3150 // other compile units in these gaps. This helps keep the size
3151 // of the aranges down.
3152 sc.comp_unit = NULL;
3153 resolved &= ~eSymbolContextCompUnit;
3154 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003155 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00003156 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003157 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003158 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
3159 cu_offset,
3160 cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003161 }
3162 }
3163 }
3164 }
3165 }
3166 return resolved;
3167}
3168
3169
3170
3171uint32_t
3172SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
3173{
3174 const uint32_t prev_size = sc_list.GetSize();
3175 if (resolve_scope & eSymbolContextCompUnit)
3176 {
3177 DWARFDebugInfo* debug_info = DebugInfo();
3178 if (debug_info)
3179 {
3180 uint32_t cu_idx;
Greg Clayton53eb1c22012-04-02 22:59:12 +00003181 DWARFCompileUnit* dwarf_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003182
Greg Clayton53eb1c22012-04-02 22:59:12 +00003183 for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003184 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003185 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Sean Callananddd7a2a2013-10-03 22:27:29 +00003186 const bool full_match = (bool)file_spec.GetDirectory();
Greg Clayton1f746072012-08-29 21:13:06 +00003187 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003188 if (check_inlines || file_spec_matches_cu_file_spec)
3189 {
3190 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton53eb1c22012-04-02 22:59:12 +00003191 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00003192 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003193 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003194 uint32_t file_idx = UINT32_MAX;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003195
Greg Clayton526a4ae2012-05-16 22:09:01 +00003196 // If we are looking for inline functions only and we don't
3197 // find it in the support files, we are done.
3198 if (check_inlines)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003199 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003200 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
3201 if (file_idx == UINT32_MAX)
3202 continue;
3203 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003204
Greg Clayton526a4ae2012-05-16 22:09:01 +00003205 if (line != 0)
3206 {
3207 LineTable *line_table = sc.comp_unit->GetLineTable();
3208
3209 if (line_table != NULL && line != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003210 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003211 // We will have already looked up the file index if
3212 // we are searching for inline entries.
3213 if (!check_inlines)
3214 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003215
Greg Clayton526a4ae2012-05-16 22:09:01 +00003216 if (file_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003217 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003218 uint32_t found_line;
3219 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
3220 found_line = sc.line_entry.line;
3221
3222 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003223 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003224 sc.function = NULL;
3225 sc.block = NULL;
3226 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003227 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003228 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
3229 if (file_vm_addr != LLDB_INVALID_ADDRESS)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003230 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003231 DWARFDebugInfoEntry *function_die = NULL;
3232 DWARFDebugInfoEntry *block_die = NULL;
3233 dwarf_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003234
Greg Clayton526a4ae2012-05-16 22:09:01 +00003235 if (function_die != NULL)
3236 {
3237 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
3238 if (sc.function == NULL)
3239 sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
3240 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003241
Greg Clayton526a4ae2012-05-16 22:09:01 +00003242 if (sc.function != NULL)
3243 {
3244 Block& block = sc.function->GetBlock (true);
3245
3246 if (block_die != NULL)
3247 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
Jason Molenda60db6e42014-10-16 01:40:16 +00003248 else if (function_die != NULL)
Greg Clayton526a4ae2012-05-16 22:09:01 +00003249 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
3250 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003251 }
3252 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003253
Greg Clayton526a4ae2012-05-16 22:09:01 +00003254 sc_list.Append(sc);
3255 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
3256 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003257 }
3258 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00003259 else if (file_spec_matches_cu_file_spec && !check_inlines)
3260 {
3261 // only append the context if we aren't looking for inline call sites
3262 // by file and line and if the file spec matches that of the compile unit
3263 sc_list.Append(sc);
3264 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003265 }
3266 else if (file_spec_matches_cu_file_spec && !check_inlines)
3267 {
3268 // only append the context if we aren't looking for inline call sites
3269 // by file and line and if the file spec matches that of the compile unit
3270 sc_list.Append(sc);
3271 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003272
Greg Clayton526a4ae2012-05-16 22:09:01 +00003273 if (!check_inlines)
3274 break;
3275 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003276 }
3277 }
3278 }
3279 }
3280 return sc_list.GetSize() - prev_size;
3281}
3282
3283void
3284SymbolFileDWARF::Index ()
3285{
3286 if (m_indexed)
3287 return;
3288 m_indexed = true;
3289 Timer scoped_timer (__PRETTY_FUNCTION__,
3290 "SymbolFileDWARF::Index (%s)",
Jim Ingham4af59612014-12-19 19:20:44 +00003291 GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003292
3293 DWARFDebugInfo* debug_info = DebugInfo();
3294 if (debug_info)
3295 {
3296 uint32_t cu_idx = 0;
3297 const uint32_t num_compile_units = GetNumCompileUnits();
3298 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
3299 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003300 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003301
Greg Clayton53eb1c22012-04-02 22:59:12 +00003302 bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003303
Greg Clayton53eb1c22012-04-02 22:59:12 +00003304 dwarf_cu->Index (cu_idx,
3305 m_function_basename_index,
3306 m_function_fullname_index,
3307 m_function_method_index,
3308 m_function_selector_index,
3309 m_objc_class_selectors_index,
3310 m_global_index,
3311 m_type_index,
3312 m_namespace_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003313
3314 // Keep memory down by clearing DIEs if this generate function
3315 // caused them to be parsed
3316 if (clear_dies)
Greg Clayton53eb1c22012-04-02 22:59:12 +00003317 dwarf_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003318 }
3319
Greg Claytond4a2b372011-09-12 23:21:58 +00003320 m_function_basename_index.Finalize();
3321 m_function_fullname_index.Finalize();
3322 m_function_method_index.Finalize();
3323 m_function_selector_index.Finalize();
3324 m_objc_class_selectors_index.Finalize();
3325 m_global_index.Finalize();
3326 m_type_index.Finalize();
3327 m_namespace_index.Finalize();
Greg Claytonc685f8e2010-09-15 04:15:46 +00003328
Greg Clayton24739922010-10-13 03:15:28 +00003329#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00003330 StreamFile s(stdout, false);
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00003331 s.Printf ("DWARF index for '%s':",
3332 GetObjectFile()->GetFileSpec().GetPath().c_str());
Greg Claytonba2d22d2010-11-13 22:57:37 +00003333 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
3334 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
3335 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
3336 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
3337 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
3338 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00003339 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Bruce Mitchenere171da52015-07-22 00:16:02 +00003340 s.Printf("\nNamespaces:\n") m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00003341#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003342 }
3343}
Greg Claytonbfe3dd42011-10-13 00:00:53 +00003344
3345bool
3346SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl)
3347{
3348 if (namespace_decl == NULL)
3349 {
3350 // Invalid namespace decl which means we aren't matching only things
3351 // in this symbol file, so return true to indicate it matches this
3352 // symbol file.
3353 return true;
3354 }
3355
3356 clang::ASTContext *namespace_ast = namespace_decl->GetASTContext();
3357
3358 if (namespace_ast == NULL)
3359 return true; // No AST in the "namespace_decl", return true since it
3360 // could then match any symbol file, including this one
3361
3362 if (namespace_ast == GetClangASTContext().getASTContext())
3363 return true; // The ASTs match, return true
3364
3365 // The namespace AST was valid, and it does not match...
Greg Clayton5160ce52013-03-27 23:08:40 +00003366 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Sean Callananc41e68b2011-10-13 21:08:11 +00003367
3368 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003369 GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
Sean Callananc41e68b2011-10-13 21:08:11 +00003370
Greg Claytonbfe3dd42011-10-13 00:00:53 +00003371 return false;
3372}
3373
Greg Clayton2506a7a2011-10-12 23:34:26 +00003374bool
3375SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl,
3376 DWARFCompileUnit* cu,
3377 const DWARFDebugInfoEntry* die)
3378{
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +00003379 // No namespace specified, so the answer is
Greg Clayton2506a7a2011-10-12 23:34:26 +00003380 if (namespace_decl == NULL)
3381 return true;
Sean Callananebe60672011-10-13 21:50:33 +00003382
Greg Clayton5160ce52013-03-27 23:08:40 +00003383 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Claytonbfe3dd42011-10-13 00:00:53 +00003384
Greg Clayton437a1352012-04-09 22:43:43 +00003385 const DWARFDebugInfoEntry *decl_ctx_die = NULL;
3386 clang::DeclContext *die_clang_decl_ctx = GetClangDeclContextContainingDIE (cu, die, &decl_ctx_die);
Greg Clayton2506a7a2011-10-12 23:34:26 +00003387 if (decl_ctx_die)
Greg Clayton437a1352012-04-09 22:43:43 +00003388 {
Greg Clayton2506a7a2011-10-12 23:34:26 +00003389 clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl();
Greg Clayton437a1352012-04-09 22:43:43 +00003390
Greg Clayton2506a7a2011-10-12 23:34:26 +00003391 if (clang_namespace_decl)
3392 {
3393 if (decl_ctx_die->Tag() != DW_TAG_namespace)
Sean Callananebe60672011-10-13 21:50:33 +00003394 {
3395 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003396 GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent is not a namespace");
Greg Clayton2506a7a2011-10-12 23:34:26 +00003397 return false;
Sean Callananebe60672011-10-13 21:50:33 +00003398 }
3399
Greg Clayton437a1352012-04-09 22:43:43 +00003400 if (clang_namespace_decl == die_clang_decl_ctx)
3401 return true;
3402 else
Greg Clayton2506a7a2011-10-12 23:34:26 +00003403 return false;
Greg Clayton2506a7a2011-10-12 23:34:26 +00003404 }
3405 else
3406 {
3407 // We have a namespace_decl that was not NULL but it contained
3408 // a NULL "clang::NamespaceDecl", so this means the global namespace
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003409 // So as long the contained decl context DIE isn't a namespace
Greg Clayton2506a7a2011-10-12 23:34:26 +00003410 // we should be ok.
3411 if (decl_ctx_die->Tag() != DW_TAG_namespace)
3412 return true;
3413 }
3414 }
Sean Callananebe60672011-10-13 21:50:33 +00003415
3416 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003417 GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent doesn't exist");
Sean Callananebe60672011-10-13 21:50:33 +00003418
Greg Clayton2506a7a2011-10-12 23:34:26 +00003419 return false;
3420}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003421uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +00003422SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003423{
Greg Clayton5160ce52013-03-27 23:08:40 +00003424 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00003425
3426 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003427 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003428 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables)",
3429 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003430 static_cast<const void*>(namespace_decl),
3431 append, max_matches);
3432
Sean Callanan213fdb82011-10-13 01:49:10 +00003433 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
Ed Maste4c24b122013-10-17 20:13:14 +00003434 return 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003435
Greg Claytonc685f8e2010-09-15 04:15:46 +00003436 DWARFDebugInfo* info = DebugInfo();
3437 if (info == NULL)
3438 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003439
3440 // If we aren't appending the results to this list, then clear the list
3441 if (!append)
3442 variables.Clear();
3443
3444 // Remember how many variables are in the list before we search in case
3445 // we are appending the results to a variable list.
3446 const uint32_t original_size = variables.GetSize();
3447
Greg Claytond4a2b372011-09-12 23:21:58 +00003448 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003449
Greg Clayton97fbc342011-10-20 22:30:33 +00003450 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003451 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003452 if (m_apple_names_ap.get())
3453 {
3454 const char *name_cstr = name.GetCString();
Jim Inghamfa39bb42014-10-25 00:33:55 +00003455 llvm::StringRef basename;
3456 llvm::StringRef context;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003457
Jim Inghamfa39bb42014-10-25 00:33:55 +00003458 if (!CPPLanguageRuntime::ExtractContextAndIdentifier(name_cstr, context, basename))
3459 basename = name_cstr;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003460
Jim Inghamfa39bb42014-10-25 00:33:55 +00003461 m_apple_names_ap->FindByName (basename.data(), die_offsets);
Greg Clayton97fbc342011-10-20 22:30:33 +00003462 }
Greg Clayton7f995132011-10-04 22:41:51 +00003463 }
3464 else
3465 {
3466 // Index the DWARF if we haven't already
3467 if (!m_indexed)
3468 Index ();
3469
3470 m_global_index.Find (name, die_offsets);
3471 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003472
Greg Clayton437a1352012-04-09 22:43:43 +00003473 const size_t num_die_matches = die_offsets.size();
3474 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003475 {
Greg Clayton7f995132011-10-04 22:41:51 +00003476 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00003477 sc.module_sp = m_obj_file->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00003478 assert (sc.module_sp);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003479
Greg Claytond4a2b372011-09-12 23:21:58 +00003480 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton7f995132011-10-04 22:41:51 +00003481 DWARFCompileUnit* dwarf_cu = NULL;
3482 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton437a1352012-04-09 22:43:43 +00003483 bool done = false;
3484 for (size_t i=0; i<num_die_matches && !done; ++i)
Greg Claytond4a2b372011-09-12 23:21:58 +00003485 {
3486 const dw_offset_t die_offset = die_offsets[i];
3487 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003488
Greg Clayton95d87902011-11-11 03:16:25 +00003489 if (die)
3490 {
Greg Clayton437a1352012-04-09 22:43:43 +00003491 switch (die->Tag())
3492 {
3493 default:
3494 case DW_TAG_subprogram:
3495 case DW_TAG_inlined_subroutine:
3496 case DW_TAG_try_block:
3497 case DW_TAG_catch_block:
3498 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003499
Greg Clayton437a1352012-04-09 22:43:43 +00003500 case DW_TAG_variable:
3501 {
3502 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003503
Greg Clayton437a1352012-04-09 22:43:43 +00003504 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3505 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003506
Greg Clayton437a1352012-04-09 22:43:43 +00003507 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003508
Greg Clayton437a1352012-04-09 22:43:43 +00003509 if (variables.GetSize() - original_size >= max_matches)
3510 done = true;
3511 }
3512 break;
3513 }
Greg Clayton95d87902011-11-11 03:16:25 +00003514 }
3515 else
3516 {
3517 if (m_using_apple_tables)
3518 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003519 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
3520 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00003521 }
3522 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003523 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003524 }
3525
3526 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00003527 const uint32_t num_matches = variables.GetSize() - original_size;
3528 if (log && num_matches > 0)
3529 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003530 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00003531 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables) => %u",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003532 name.GetCString(),
3533 static_cast<const void*>(namespace_decl),
3534 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00003535 num_matches);
3536 }
3537 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003538}
3539
3540uint32_t
3541SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
3542{
Greg Clayton5160ce52013-03-27 23:08:40 +00003543 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003544
Greg Clayton21f2a492011-10-06 00:09:08 +00003545 if (log)
3546 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003547 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003548 "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003549 regex.GetText(), append,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003550 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00003551 }
3552
Greg Claytonc685f8e2010-09-15 04:15:46 +00003553 DWARFDebugInfo* info = DebugInfo();
3554 if (info == NULL)
3555 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003556
3557 // If we aren't appending the results to this list, then clear the list
3558 if (!append)
3559 variables.Clear();
3560
3561 // Remember how many variables are in the list before we search in case
3562 // we are appending the results to a variable list.
3563 const uint32_t original_size = variables.GetSize();
3564
Greg Clayton7f995132011-10-04 22:41:51 +00003565 DIEArray die_offsets;
3566
Greg Clayton97fbc342011-10-20 22:30:33 +00003567 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003568 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003569 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00003570 {
3571 DWARFMappedHash::DIEInfoArray hash_data_array;
3572 if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
3573 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
3574 }
Greg Clayton7f995132011-10-04 22:41:51 +00003575 }
3576 else
3577 {
3578 // Index the DWARF if we haven't already
3579 if (!m_indexed)
3580 Index ();
3581
3582 m_global_index.Find (regex, die_offsets);
3583 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003584
Greg Claytonc685f8e2010-09-15 04:15:46 +00003585 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00003586 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00003587 assert (sc.module_sp);
3588
Greg Claytond4a2b372011-09-12 23:21:58 +00003589 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00003590 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00003591 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003592 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003593 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003594 DWARFDebugInfo* debug_info = DebugInfo();
3595 for (size_t i=0; i<num_matches; ++i)
3596 {
3597 const dw_offset_t die_offset = die_offsets[i];
3598 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Greg Clayton95d87902011-11-11 03:16:25 +00003599
3600 if (die)
3601 {
3602 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003603
Greg Clayton95d87902011-11-11 03:16:25 +00003604 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003605
Greg Clayton95d87902011-11-11 03:16:25 +00003606 if (variables.GetSize() - original_size >= max_matches)
3607 break;
3608 }
3609 else
3610 {
3611 if (m_using_apple_tables)
3612 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003613 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
3614 die_offset, regex.GetText());
Greg Clayton95d87902011-11-11 03:16:25 +00003615 }
3616 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003617 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003618 }
3619
3620 // Return the number of variable that were appended to the list
3621 return variables.GetSize() - original_size;
3622}
3623
Greg Claytonaa044962011-10-13 00:59:38 +00003624
Jim Ingham4cda6e02011-10-07 22:23:45 +00003625bool
3626SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
3627 DWARFCompileUnit *&dwarf_cu,
Pavel Labatha73d6572015-03-13 10:22:00 +00003628 bool include_inlines,
Jim Ingham4cda6e02011-10-07 22:23:45 +00003629 SymbolContextList& sc_list)
Greg Clayton9e315582011-09-02 04:03:59 +00003630{
Greg Claytonaa044962011-10-13 00:59:38 +00003631 const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Pavel Labatha73d6572015-03-13 10:22:00 +00003632 return ResolveFunction (dwarf_cu, die, include_inlines, sc_list);
Greg Claytonaa044962011-10-13 00:59:38 +00003633}
3634
3635
3636bool
3637SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
3638 const DWARFDebugInfoEntry *die,
Pavel Labatha73d6572015-03-13 10:22:00 +00003639 bool include_inlines,
Greg Claytonaa044962011-10-13 00:59:38 +00003640 SymbolContextList& sc_list)
3641{
Greg Clayton9e315582011-09-02 04:03:59 +00003642 SymbolContext sc;
Greg Claytonaa044962011-10-13 00:59:38 +00003643
3644 if (die == NULL)
3645 return false;
3646
Jim Ingham4cda6e02011-10-07 22:23:45 +00003647 // If we were passed a die that is not a function, just return false...
Pavel Labatha73d6572015-03-13 10:22:00 +00003648 if (! (die->Tag() == DW_TAG_subprogram || (include_inlines && die->Tag() == DW_TAG_inlined_subroutine)))
Jim Ingham4cda6e02011-10-07 22:23:45 +00003649 return false;
3650
3651 const DWARFDebugInfoEntry* inlined_die = NULL;
3652 if (die->Tag() == DW_TAG_inlined_subroutine)
Greg Clayton9e315582011-09-02 04:03:59 +00003653 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00003654 inlined_die = die;
Greg Clayton9e315582011-09-02 04:03:59 +00003655
Jim Ingham4cda6e02011-10-07 22:23:45 +00003656 while ((die = die->GetParent()) != NULL)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003657 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00003658 if (die->Tag() == DW_TAG_subprogram)
3659 break;
Greg Clayton9e315582011-09-02 04:03:59 +00003660 }
3661 }
Jason Molenda60db6e42014-10-16 01:40:16 +00003662 assert (die && die->Tag() == DW_TAG_subprogram);
Greg Claytonaa044962011-10-13 00:59:38 +00003663 if (GetFunction (cu, die, sc))
Jim Ingham4cda6e02011-10-07 22:23:45 +00003664 {
3665 Address addr;
3666 // Parse all blocks if needed
3667 if (inlined_die)
3668 {
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00003669 Block &function_block = sc.function->GetBlock (true);
3670 sc.block = function_block.FindBlockByID (MakeUserID(inlined_die->GetOffset()));
3671 if (sc.block == NULL)
3672 sc.block = function_block.FindBlockByID (inlined_die->GetOffset());
3673 if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
Jim Ingham4cda6e02011-10-07 22:23:45 +00003674 addr.Clear();
3675 }
3676 else
3677 {
3678 sc.block = NULL;
3679 addr = sc.function->GetAddressRange().GetBaseAddress();
3680 }
3681
3682 if (addr.IsValid())
3683 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00003684 sc_list.Append(sc);
Greg Claytonaa044962011-10-13 00:59:38 +00003685 return true;
Jim Ingham4cda6e02011-10-07 22:23:45 +00003686 }
3687 }
3688
Greg Claytonaa044962011-10-13 00:59:38 +00003689 return false;
Greg Clayton9e315582011-09-02 04:03:59 +00003690}
3691
Greg Clayton7f995132011-10-04 22:41:51 +00003692void
3693SymbolFileDWARF::FindFunctions (const ConstString &name,
3694 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00003695 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00003696 SymbolContextList& sc_list)
3697{
Greg Claytond4a2b372011-09-12 23:21:58 +00003698 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00003699 if (name_to_die.Find (name, die_offsets))
3700 {
Pavel Labatha73d6572015-03-13 10:22:00 +00003701 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00003702 }
3703}
3704
3705
3706void
3707SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
3708 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00003709 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00003710 SymbolContextList& sc_list)
3711{
3712 DIEArray die_offsets;
3713 if (name_to_die.Find (regex, die_offsets))
3714 {
Pavel Labatha73d6572015-03-13 10:22:00 +00003715 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00003716 }
3717}
3718
3719
3720void
3721SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
3722 const DWARFMappedHash::MemoryTable &memory_table,
Pavel Labatha73d6572015-03-13 10:22:00 +00003723 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00003724 SymbolContextList& sc_list)
3725{
3726 DIEArray die_offsets;
Greg Claytond1767f02011-12-08 02:13:16 +00003727 DWARFMappedHash::DIEInfoArray hash_data_array;
3728 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
Greg Clayton7f995132011-10-04 22:41:51 +00003729 {
Greg Claytond1767f02011-12-08 02:13:16 +00003730 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
Pavel Labatha73d6572015-03-13 10:22:00 +00003731 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00003732 }
3733}
3734
3735void
3736SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
Pavel Labatha73d6572015-03-13 10:22:00 +00003737 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00003738 SymbolContextList& sc_list)
3739{
3740 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003741 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00003742 {
Greg Clayton7f995132011-10-04 22:41:51 +00003743 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00003744 for (size_t i=0; i<num_matches; ++i)
Greg Claytond7e05462010-11-14 00:22:48 +00003745 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003746 const dw_offset_t die_offset = die_offsets[i];
Pavel Labatha73d6572015-03-13 10:22:00 +00003747 ResolveFunction (die_offset, dwarf_cu, include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003748 }
3749 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00003750}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003751
Jim Ingham4cda6e02011-10-07 22:23:45 +00003752bool
3753SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
3754 const DWARFCompileUnit *dwarf_cu,
3755 uint32_t name_type_mask,
3756 const char *partial_name,
3757 const char *base_name_start,
3758 const char *base_name_end)
3759{
Greg Claytonfbea0f62012-11-15 18:05:43 +00003760 // If we are looking only for methods, throw away all the ones that are or aren't in C++ classes:
3761 if (name_type_mask == eFunctionNameTypeMethod || name_type_mask == eFunctionNameTypeBase)
Jim Ingham4cda6e02011-10-07 22:23:45 +00003762 {
Greg Claytonf0705c82011-10-22 03:33:13 +00003763 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
3764 if (!containing_decl_ctx)
3765 return false;
3766
3767 bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
3768
Greg Claytonfbea0f62012-11-15 18:05:43 +00003769 if (name_type_mask == eFunctionNameTypeMethod)
3770 {
3771 if (is_cxx_method == false)
3772 return false;
3773 }
3774
3775 if (name_type_mask == eFunctionNameTypeBase)
3776 {
3777 if (is_cxx_method == true)
3778 return false;
3779 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00003780 }
3781
3782 // Now we need to check whether the name we got back for this type matches the extra specifications
3783 // that were in the name we're looking up:
3784 if (base_name_start != partial_name || *base_name_end != '\0')
3785 {
3786 // First see if the stuff to the left matches the full name. To do that let's see if
3787 // we can pull out the mips linkage name attribute:
3788
3789 Mangled best_name;
Jim Ingham4cda6e02011-10-07 22:23:45 +00003790 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonfbea0f62012-11-15 18:05:43 +00003791 DWARFFormValue form_value;
Jim Ingham4cda6e02011-10-07 22:23:45 +00003792 die->GetAttributes(this, dwarf_cu, NULL, attributes);
3793 uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
Greg Clayton71415542012-12-08 00:24:40 +00003794 if (idx == UINT32_MAX)
3795 idx = attributes.FindAttributeIndex(DW_AT_linkage_name);
Jim Ingham4cda6e02011-10-07 22:23:45 +00003796 if (idx != UINT32_MAX)
3797 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00003798 if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
3799 {
Greg Claytonfbea0f62012-11-15 18:05:43 +00003800 const char *mangled_name = form_value.AsCString(&get_debug_str_data());
3801 if (mangled_name)
3802 best_name.SetValue (ConstString(mangled_name), true);
3803 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00003804 }
Greg Claytonfbea0f62012-11-15 18:05:43 +00003805
3806 if (!best_name)
3807 {
3808 idx = attributes.FindAttributeIndex(DW_AT_name);
3809 if (idx != UINT32_MAX && attributes.ExtractFormValueAtIndex(this, idx, form_value))
3810 {
3811 const char *name = form_value.AsCString(&get_debug_str_data());
3812 best_name.SetValue (ConstString(name), false);
3813 }
3814 }
3815
Greg Claytonddaf6a72015-07-08 22:32:23 +00003816 const LanguageType cu_language = const_cast<DWARFCompileUnit *>(dwarf_cu)->GetLanguageType();
3817 if (best_name.GetDemangledName(cu_language))
Jim Ingham4cda6e02011-10-07 22:23:45 +00003818 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00003819 const char *demangled = best_name.GetDemangledName(cu_language).GetCString();
Jim Ingham4cda6e02011-10-07 22:23:45 +00003820 if (demangled)
3821 {
3822 std::string name_no_parens(partial_name, base_name_end - partial_name);
Jim Ingham85c13d72012-03-02 02:24:42 +00003823 const char *partial_in_demangled = strstr (demangled, name_no_parens.c_str());
3824 if (partial_in_demangled == NULL)
Jim Ingham4cda6e02011-10-07 22:23:45 +00003825 return false;
Jim Ingham85c13d72012-03-02 02:24:42 +00003826 else
3827 {
3828 // Sort out the case where our name is something like "Process::Destroy" and the match is
3829 // "SBProcess::Destroy" - that shouldn't be a match. We should really always match on
3830 // namespace boundaries...
3831
3832 if (partial_name[0] == ':' && partial_name[1] == ':')
3833 {
3834 // The partial name was already on a namespace boundary so all matches are good.
3835 return true;
3836 }
3837 else if (partial_in_demangled == demangled)
3838 {
3839 // They both start the same, so this is an good match.
3840 return true;
3841 }
3842 else
3843 {
3844 if (partial_in_demangled - demangled == 1)
3845 {
3846 // Only one character difference, can't be a namespace boundary...
3847 return false;
3848 }
3849 else if (*(partial_in_demangled - 1) == ':' && *(partial_in_demangled - 2) == ':')
3850 {
3851 // We are on a namespace boundary, so this is also good.
3852 return true;
3853 }
3854 else
3855 return false;
3856 }
3857 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00003858 }
3859 }
3860 }
3861
3862 return true;
3863}
Greg Claytonc685f8e2010-09-15 04:15:46 +00003864
Greg Clayton0c5cd902010-06-28 21:30:43 +00003865uint32_t
Greg Clayton2bc22f82011-09-30 03:20:47 +00003866SymbolFileDWARF::FindFunctions (const ConstString &name,
Sean Callanan213fdb82011-10-13 01:49:10 +00003867 const lldb_private::ClangNamespaceDecl *namespace_decl,
Sean Callanan9df05fb2012-02-10 22:52:19 +00003868 uint32_t name_type_mask,
3869 bool include_inlines,
Greg Clayton2bc22f82011-09-30 03:20:47 +00003870 bool append,
3871 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00003872{
3873 Timer scoped_timer (__PRETTY_FUNCTION__,
3874 "SymbolFileDWARF::FindFunctions (name = '%s')",
3875 name.AsCString());
3876
Greg Clayton43fe2172013-04-03 02:00:15 +00003877 // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
3878 assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
3879
Greg Clayton5160ce52013-03-27 23:08:40 +00003880 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00003881
3882 if (log)
3883 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003884 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003885 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
3886 name.GetCString(),
3887 name_type_mask,
3888 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00003889 }
3890
Greg Clayton0c5cd902010-06-28 21:30:43 +00003891 // If we aren't appending the results to this list, then clear the list
3892 if (!append)
3893 sc_list.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00003894
3895 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
Ed Maste4c24b122013-10-17 20:13:14 +00003896 return 0;
Jim Ingham4cda6e02011-10-07 22:23:45 +00003897
3898 // If name is empty then we won't find anything.
3899 if (name.IsEmpty())
3900 return 0;
Greg Clayton0c5cd902010-06-28 21:30:43 +00003901
3902 // Remember how many sc_list are in the list before we search in case
3903 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00003904
Jim Ingham4cda6e02011-10-07 22:23:45 +00003905 const char *name_cstr = name.GetCString();
Greg Clayton43fe2172013-04-03 02:00:15 +00003906
3907 const uint32_t original_size = sc_list.GetSize();
3908
Jim Ingham4cda6e02011-10-07 22:23:45 +00003909 DWARFDebugInfo* info = DebugInfo();
3910 if (info == NULL)
3911 return 0;
3912
Greg Claytonaa044962011-10-13 00:59:38 +00003913 DWARFCompileUnit *dwarf_cu = NULL;
Greg Clayton43fe2172013-04-03 02:00:15 +00003914 std::set<const DWARFDebugInfoEntry *> resolved_dies;
Greg Clayton97fbc342011-10-20 22:30:33 +00003915 if (m_using_apple_tables)
Greg Clayton4d01ace2011-09-29 16:58:15 +00003916 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003917 if (m_apple_names_ap.get())
Jim Ingham4cda6e02011-10-07 22:23:45 +00003918 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003919
3920 DIEArray die_offsets;
3921
3922 uint32_t num_matches = 0;
3923
Greg Clayton43fe2172013-04-03 02:00:15 +00003924 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonaa044962011-10-13 00:59:38 +00003925 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003926 // If they asked for the full name, match what they typed. At some point we may
3927 // want to canonicalize this (strip double spaces, etc. For now, we just add all the
3928 // dies that we find by exact match.
Jim Ingham4cda6e02011-10-07 22:23:45 +00003929 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00003930 for (uint32_t i = 0; i < num_matches; i++)
3931 {
Greg Clayton95d87902011-11-11 03:16:25 +00003932 const dw_offset_t die_offset = die_offsets[i];
3933 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Greg Claytonaa044962011-10-13 00:59:38 +00003934 if (die)
3935 {
Sean Callanan213fdb82011-10-13 01:49:10 +00003936 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3937 continue;
3938
Greg Clayton43fe2172013-04-03 02:00:15 +00003939 if (resolved_dies.find(die) == resolved_dies.end())
3940 {
Pavel Labatha73d6572015-03-13 10:22:00 +00003941 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00003942 resolved_dies.insert(die);
3943 }
Greg Claytonaa044962011-10-13 00:59:38 +00003944 }
Greg Clayton95d87902011-11-11 03:16:25 +00003945 else
3946 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003947 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
3948 die_offset, name_cstr);
Greg Clayton95d87902011-11-11 03:16:25 +00003949 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00003950 }
Greg Clayton97fbc342011-10-20 22:30:33 +00003951 }
Greg Clayton43fe2172013-04-03 02:00:15 +00003952
3953 if (name_type_mask & eFunctionNameTypeSelector)
3954 {
3955 if (namespace_decl && *namespace_decl)
3956 return 0; // no selectors in namespaces
Greg Clayton97fbc342011-10-20 22:30:33 +00003957
Greg Clayton43fe2172013-04-03 02:00:15 +00003958 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
3959 // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
3960 // and if it is an ObjC method name, we're good.
Greg Clayton97fbc342011-10-20 22:30:33 +00003961
Greg Clayton43fe2172013-04-03 02:00:15 +00003962 for (uint32_t i = 0; i < num_matches; i++)
Greg Clayton97fbc342011-10-20 22:30:33 +00003963 {
Greg Clayton43fe2172013-04-03 02:00:15 +00003964 const dw_offset_t die_offset = die_offsets[i];
3965 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
3966 if (die)
Greg Clayton97fbc342011-10-20 22:30:33 +00003967 {
Greg Clayton43fe2172013-04-03 02:00:15 +00003968 const char *die_name = die->GetName(this, dwarf_cu);
3969 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
Greg Clayton97fbc342011-10-20 22:30:33 +00003970 {
Greg Clayton43fe2172013-04-03 02:00:15 +00003971 if (resolved_dies.find(die) == resolved_dies.end())
3972 {
Pavel Labatha73d6572015-03-13 10:22:00 +00003973 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00003974 resolved_dies.insert(die);
3975 }
Greg Clayton97fbc342011-10-20 22:30:33 +00003976 }
3977 }
Greg Clayton43fe2172013-04-03 02:00:15 +00003978 else
3979 {
3980 GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
3981 die_offset, name_cstr);
3982 }
Greg Clayton97fbc342011-10-20 22:30:33 +00003983 }
Greg Clayton43fe2172013-04-03 02:00:15 +00003984 die_offsets.clear();
3985 }
3986
3987 if (((name_type_mask & eFunctionNameTypeMethod) && !namespace_decl) || name_type_mask & eFunctionNameTypeBase)
3988 {
3989 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
3990 // extract the base name, look that up, and if there is any other information in the name we were
3991 // passed in we have to post-filter based on that.
3992
3993 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
3994 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
3995
3996 for (uint32_t i = 0; i < num_matches; i++)
3997 {
3998 const dw_offset_t die_offset = die_offsets[i];
3999 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
4000 if (die)
4001 {
Greg Clayton43fe2172013-04-03 02:00:15 +00004002 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
4003 continue;
4004
4005 // If we get to here, the die is good, and we should add it:
4006 if (resolved_dies.find(die) == resolved_dies.end())
Pavel Labatha73d6572015-03-13 10:22:00 +00004007 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00004008 {
4009 bool keep_die = true;
4010 if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
4011 {
4012 // We are looking for either basenames or methods, so we need to
4013 // trim out the ones we won't want by looking at the type
4014 SymbolContext sc;
4015 if (sc_list.GetLastContext(sc))
4016 {
4017 if (sc.block)
4018 {
4019 // We have an inlined function
4020 }
4021 else if (sc.function)
4022 {
4023 Type *type = sc.function->GetType();
4024
Sean Callananc370a8a2013-09-18 22:59:55 +00004025 if (type)
Greg Clayton43fe2172013-04-03 02:00:15 +00004026 {
Sean Callananc370a8a2013-09-18 22:59:55 +00004027 clang::DeclContext* decl_ctx = GetClangDeclContextContainingTypeUID (type->GetID());
4028 if (decl_ctx->isRecord())
Greg Clayton43fe2172013-04-03 02:00:15 +00004029 {
Sean Callananc370a8a2013-09-18 22:59:55 +00004030 if (name_type_mask & eFunctionNameTypeBase)
4031 {
4032 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
4033 keep_die = false;
4034 }
4035 }
4036 else
4037 {
4038 if (name_type_mask & eFunctionNameTypeMethod)
4039 {
4040 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
4041 keep_die = false;
4042 }
Greg Clayton43fe2172013-04-03 02:00:15 +00004043 }
4044 }
4045 else
4046 {
Sean Callananc370a8a2013-09-18 22:59:55 +00004047 GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
4048 die_offset);
Greg Clayton43fe2172013-04-03 02:00:15 +00004049 }
4050 }
4051 }
4052 }
4053 if (keep_die)
4054 resolved_dies.insert(die);
4055 }
4056 }
4057 else
4058 {
4059 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
4060 die_offset, name_cstr);
4061 }
4062 }
4063 die_offsets.clear();
Jim Ingham4cda6e02011-10-07 22:23:45 +00004064 }
4065 }
Greg Clayton7f995132011-10-04 22:41:51 +00004066 }
4067 else
4068 {
4069
4070 // Index the DWARF if we haven't already
4071 if (!m_indexed)
4072 Index ();
4073
Greg Clayton7f995132011-10-04 22:41:51 +00004074 if (name_type_mask & eFunctionNameTypeFull)
Matt Kopecd6089962013-05-10 17:53:48 +00004075 {
Pavel Labatha73d6572015-03-13 10:22:00 +00004076 FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00004077
Ed Mastefc7baa02013-09-09 18:00:45 +00004078 // FIXME Temporary workaround for global/anonymous namespace
Robert Flack5cbd3bf2015-05-13 18:20:02 +00004079 // functions debugging FreeBSD and Linux binaries.
Matt Kopecd6089962013-05-10 17:53:48 +00004080 // If we didn't find any functions in the global namespace try
4081 // looking in the basename index but ignore any returned
Robert Flackeb83fab2015-05-15 18:59:59 +00004082 // functions that have a namespace but keep functions which
4083 // have an anonymous namespace
4084 // TODO: The arch in the object file isn't correct for MSVC
4085 // binaries on windows, we should find a way to make it
4086 // correct and handle those symbols as well.
Matt Kopecd6089962013-05-10 17:53:48 +00004087 if (sc_list.GetSize() == 0)
4088 {
Robert Flackeb83fab2015-05-15 18:59:59 +00004089 ArchSpec arch;
4090 if (!namespace_decl &&
4091 GetObjectFile()->GetArchitecture(arch) &&
4092 (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
4093 arch.GetMachine() == llvm::Triple::hexagon))
Matt Kopecd6089962013-05-10 17:53:48 +00004094 {
Robert Flackeb83fab2015-05-15 18:59:59 +00004095 SymbolContextList temp_sc_list;
4096 FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
Matt Kopecd6089962013-05-10 17:53:48 +00004097 SymbolContext sc;
4098 for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
4099 {
4100 if (temp_sc_list.GetContextAtIndex(i, sc))
4101 {
Matt Kopeca189d492013-05-10 22:55:24 +00004102 ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
4103 ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
Robert Flackeb83fab2015-05-15 18:59:59 +00004104 // Mangled names on Linux and FreeBSD are of the form:
4105 // _ZN18function_namespace13function_nameEv.
Matt Kopec04e5d582013-05-14 19:00:41 +00004106 if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
4107 !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
Matt Kopecd6089962013-05-10 17:53:48 +00004108 {
4109 sc_list.Append(sc);
4110 }
4111 }
4112 }
4113 }
4114 }
Matt Kopecd6089962013-05-10 17:53:48 +00004115 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00004116 DIEArray die_offsets;
4117 DWARFCompileUnit *dwarf_cu = NULL;
4118
Greg Clayton43fe2172013-04-03 02:00:15 +00004119 if (name_type_mask & eFunctionNameTypeBase)
Jim Ingham4cda6e02011-10-07 22:23:45 +00004120 {
Greg Clayton43fe2172013-04-03 02:00:15 +00004121 uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
Greg Claytonaa044962011-10-13 00:59:38 +00004122 for (uint32_t i = 0; i < num_base; i++)
Jim Ingham4cda6e02011-10-07 22:23:45 +00004123 {
Greg Claytonaa044962011-10-13 00:59:38 +00004124 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
4125 if (die)
4126 {
Sean Callanan213fdb82011-10-13 01:49:10 +00004127 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
4128 continue;
4129
Greg Claytonaa044962011-10-13 00:59:38 +00004130 // If we get to here, the die is good, and we should add it:
Greg Clayton43fe2172013-04-03 02:00:15 +00004131 if (resolved_dies.find(die) == resolved_dies.end())
4132 {
Pavel Labatha73d6572015-03-13 10:22:00 +00004133 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00004134 resolved_dies.insert(die);
4135 }
Greg Claytonaa044962011-10-13 00:59:38 +00004136 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00004137 }
4138 die_offsets.clear();
4139 }
4140
Greg Clayton43fe2172013-04-03 02:00:15 +00004141 if (name_type_mask & eFunctionNameTypeMethod)
Jim Ingham4cda6e02011-10-07 22:23:45 +00004142 {
Sean Callanan213fdb82011-10-13 01:49:10 +00004143 if (namespace_decl && *namespace_decl)
4144 return 0; // no methods in namespaces
4145
Greg Clayton43fe2172013-04-03 02:00:15 +00004146 uint32_t num_base = m_function_method_index.Find(name, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00004147 {
Greg Claytonaa044962011-10-13 00:59:38 +00004148 for (uint32_t i = 0; i < num_base; i++)
4149 {
4150 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
4151 if (die)
4152 {
Greg Claytonaa044962011-10-13 00:59:38 +00004153 // If we get to here, the die is good, and we should add it:
Greg Clayton43fe2172013-04-03 02:00:15 +00004154 if (resolved_dies.find(die) == resolved_dies.end())
4155 {
Pavel Labatha73d6572015-03-13 10:22:00 +00004156 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00004157 resolved_dies.insert(die);
4158 }
Greg Claytonaa044962011-10-13 00:59:38 +00004159 }
4160 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00004161 }
4162 die_offsets.clear();
4163 }
Greg Clayton7f995132011-10-04 22:41:51 +00004164
Greg Clayton43fe2172013-04-03 02:00:15 +00004165 if ((name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
Jim Ingham4cda6e02011-10-07 22:23:45 +00004166 {
Pavel Labatha73d6572015-03-13 10:22:00 +00004167 FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
Jim Ingham4cda6e02011-10-07 22:23:45 +00004168 }
4169
Greg Clayton4d01ace2011-09-29 16:58:15 +00004170 }
4171
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004172 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00004173 const uint32_t num_matches = sc_list.GetSize() - original_size;
4174
4175 if (log && num_matches > 0)
4176 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004177 GetObjectFile()->GetModule()->LogMessage (log,
Pavel Labatha73d6572015-03-13 10:22:00 +00004178 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00004179 name.GetCString(),
4180 name_type_mask,
Pavel Labatha73d6572015-03-13 10:22:00 +00004181 include_inlines,
Greg Clayton437a1352012-04-09 22:43:43 +00004182 append,
4183 num_matches);
4184 }
4185 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004186}
4187
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004188uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +00004189SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004190{
4191 Timer scoped_timer (__PRETTY_FUNCTION__,
4192 "SymbolFileDWARF::FindFunctions (regex = '%s')",
4193 regex.GetText());
4194
Greg Clayton5160ce52013-03-27 23:08:40 +00004195 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00004196
4197 if (log)
4198 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004199 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00004200 "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
4201 regex.GetText(),
4202 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00004203 }
4204
4205
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004206 // If we aren't appending the results to this list, then clear the list
4207 if (!append)
4208 sc_list.Clear();
4209
4210 // Remember how many sc_list are in the list before we search in case
4211 // we are appending the results to a variable list.
4212 uint32_t original_size = sc_list.GetSize();
4213
Greg Clayton97fbc342011-10-20 22:30:33 +00004214 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00004215 {
Greg Clayton97fbc342011-10-20 22:30:33 +00004216 if (m_apple_names_ap.get())
Pavel Labatha73d6572015-03-13 10:22:00 +00004217 FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00004218 }
4219 else
4220 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00004221 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00004222 if (!m_indexed)
4223 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004224
Pavel Labatha73d6572015-03-13 10:22:00 +00004225 FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004226
Pavel Labatha73d6572015-03-13 10:22:00 +00004227 FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00004228 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004229
4230 // Return the number of variable that were appended to the list
4231 return sc_list.GetSize() - original_size;
4232}
Jim Ingham318c9f22011-08-26 19:44:13 +00004233
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004234uint32_t
Greg Claytond1767f02011-12-08 02:13:16 +00004235SymbolFileDWARF::FindTypes (const SymbolContext& sc,
4236 const ConstString &name,
4237 const lldb_private::ClangNamespaceDecl *namespace_decl,
4238 bool append,
4239 uint32_t max_matches,
4240 TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004241{
Greg Claytonc685f8e2010-09-15 04:15:46 +00004242 DWARFDebugInfo* info = DebugInfo();
4243 if (info == NULL)
4244 return 0;
4245
Greg Clayton5160ce52013-03-27 23:08:40 +00004246 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004247
Greg Clayton21f2a492011-10-06 00:09:08 +00004248 if (log)
4249 {
Greg Clayton437a1352012-04-09 22:43:43 +00004250 if (namespace_decl)
Greg Clayton5160ce52013-03-27 23:08:40 +00004251 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004252 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list)",
4253 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004254 static_cast<void*>(namespace_decl->GetNamespaceDecl()),
Greg Clayton437a1352012-04-09 22:43:43 +00004255 namespace_decl->GetQualifiedName().c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004256 append, max_matches);
Greg Clayton437a1352012-04-09 22:43:43 +00004257 else
Greg Clayton5160ce52013-03-27 23:08:40 +00004258 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004259 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004260 name.GetCString(), append,
Greg Clayton437a1352012-04-09 22:43:43 +00004261 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00004262 }
4263
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004264 // If we aren't appending the results to this list, then clear the list
4265 if (!append)
4266 types.Clear();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004267
Sean Callanan213fdb82011-10-13 01:49:10 +00004268 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
Ed Maste4c24b122013-10-17 20:13:14 +00004269 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004270
Greg Claytond4a2b372011-09-12 23:21:58 +00004271 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004272
Greg Clayton97fbc342011-10-20 22:30:33 +00004273 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00004274 {
Greg Clayton97fbc342011-10-20 22:30:33 +00004275 if (m_apple_types_ap.get())
4276 {
4277 const char *name_cstr = name.GetCString();
4278 m_apple_types_ap->FindByName (name_cstr, die_offsets);
4279 }
Greg Clayton7f995132011-10-04 22:41:51 +00004280 }
4281 else
4282 {
4283 if (!m_indexed)
4284 Index ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004285
Greg Clayton7f995132011-10-04 22:41:51 +00004286 m_type_index.Find (name, die_offsets);
4287 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004288
Greg Clayton437a1352012-04-09 22:43:43 +00004289 const size_t num_die_matches = die_offsets.size();
Greg Clayton7f995132011-10-04 22:41:51 +00004290
Greg Clayton437a1352012-04-09 22:43:43 +00004291 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004292 {
Greg Clayton7f995132011-10-04 22:41:51 +00004293 const uint32_t initial_types_size = types.GetSize();
4294 DWARFCompileUnit* dwarf_cu = NULL;
4295 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00004296 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton437a1352012-04-09 22:43:43 +00004297 for (size_t i=0; i<num_die_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004298 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004299 const dw_offset_t die_offset = die_offsets[i];
4300 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
4301
Greg Clayton95d87902011-11-11 03:16:25 +00004302 if (die)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004303 {
Greg Clayton95d87902011-11-11 03:16:25 +00004304 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
4305 continue;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004306
Greg Clayton95d87902011-11-11 03:16:25 +00004307 Type *matching_type = ResolveType (dwarf_cu, die);
4308 if (matching_type)
4309 {
4310 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone1cd1be2012-01-29 20:56:30 +00004311 types.InsertUnique (matching_type->shared_from_this());
Greg Clayton95d87902011-11-11 03:16:25 +00004312 if (types.GetSize() >= max_matches)
4313 break;
4314 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004315 }
Greg Clayton95d87902011-11-11 03:16:25 +00004316 else
4317 {
4318 if (m_using_apple_tables)
4319 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00004320 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
4321 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00004322 }
4323 }
4324
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004325 }
Greg Clayton437a1352012-04-09 22:43:43 +00004326 const uint32_t num_matches = types.GetSize() - initial_types_size;
4327 if (log && num_matches)
4328 {
4329 if (namespace_decl)
4330 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004331 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004332 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list) => %u",
4333 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004334 static_cast<void*>(namespace_decl->GetNamespaceDecl()),
Greg Clayton437a1352012-04-09 22:43:43 +00004335 namespace_decl->GetQualifiedName().c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004336 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00004337 num_matches);
4338 }
4339 else
4340 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004341 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004342 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list) => %u",
4343 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004344 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00004345 num_matches);
4346 }
4347 }
4348 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004349 }
Greg Clayton7f995132011-10-04 22:41:51 +00004350 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004351}
4352
4353
Greg Clayton526e5af2010-11-13 03:52:47 +00004354ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00004355SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00004356 const ConstString &name,
4357 const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00004358{
Greg Clayton5160ce52013-03-27 23:08:40 +00004359 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00004360
4361 if (log)
4362 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004363 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00004364 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
4365 name.GetCString());
Greg Clayton21f2a492011-10-06 00:09:08 +00004366 }
Sean Callanan213fdb82011-10-13 01:49:10 +00004367
4368 if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl))
Ed Maste4c24b122013-10-17 20:13:14 +00004369 return ClangNamespaceDecl();
Greg Clayton21f2a492011-10-06 00:09:08 +00004370
Greg Clayton526e5af2010-11-13 03:52:47 +00004371 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00004372 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00004373 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00004374 {
Greg Clayton7f995132011-10-04 22:41:51 +00004375 DIEArray die_offsets;
4376
Greg Clayton526e5af2010-11-13 03:52:47 +00004377 // Index if we already haven't to make sure the compile units
4378 // get indexed and make their global DIE index list
Greg Clayton97fbc342011-10-20 22:30:33 +00004379 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00004380 {
Greg Clayton97fbc342011-10-20 22:30:33 +00004381 if (m_apple_namespaces_ap.get())
4382 {
4383 const char *name_cstr = name.GetCString();
4384 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
4385 }
Greg Clayton7f995132011-10-04 22:41:51 +00004386 }
4387 else
4388 {
4389 if (!m_indexed)
4390 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00004391
Greg Clayton7f995132011-10-04 22:41:51 +00004392 m_namespace_index.Find (name, die_offsets);
4393 }
Greg Claytond4a2b372011-09-12 23:21:58 +00004394
4395 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton526e5af2010-11-13 03:52:47 +00004396 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00004397 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00004398 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00004399 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004400 DWARFDebugInfo* debug_info = DebugInfo();
4401 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00004402 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004403 const dw_offset_t die_offset = die_offsets[i];
4404 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Sean Callanan213fdb82011-10-13 01:49:10 +00004405
Greg Clayton95d87902011-11-11 03:16:25 +00004406 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00004407 {
Greg Clayton95d87902011-11-11 03:16:25 +00004408 if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die))
4409 continue;
4410
4411 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
4412 if (clang_namespace_decl)
4413 {
4414 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
4415 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
Greg Claytond1767f02011-12-08 02:13:16 +00004416 break;
Greg Clayton95d87902011-11-11 03:16:25 +00004417 }
Greg Claytond4a2b372011-09-12 23:21:58 +00004418 }
Greg Clayton95d87902011-11-11 03:16:25 +00004419 else
4420 {
4421 if (m_using_apple_tables)
4422 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00004423 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
4424 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00004425 }
4426 }
4427
Greg Clayton526e5af2010-11-13 03:52:47 +00004428 }
4429 }
Greg Clayton96d7d742010-11-10 23:42:09 +00004430 }
Greg Clayton437a1352012-04-09 22:43:43 +00004431 if (log && namespace_decl.GetNamespaceDecl())
4432 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004433 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004434 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => clang::NamespaceDecl(%p) \"%s\"",
4435 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004436 static_cast<const void*>(namespace_decl.GetNamespaceDecl()),
Greg Clayton437a1352012-04-09 22:43:43 +00004437 namespace_decl.GetQualifiedName().c_str());
4438 }
4439
Greg Clayton526e5af2010-11-13 03:52:47 +00004440 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00004441}
4442
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004443uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004444SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004445{
4446 // Remember how many sc_list are in the list before we search in case
4447 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004448 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004449
4450 const uint32_t num_die_offsets = die_offsets.size();
4451 // Parse all of the types we found from the pubtypes matches
4452 uint32_t i;
4453 uint32_t num_matches = 0;
4454 for (i = 0; i < num_die_offsets; ++i)
4455 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004456 Type *matching_type = ResolveTypeUID (die_offsets[i]);
4457 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004458 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004459 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone1cd1be2012-01-29 20:56:30 +00004460 types.InsertUnique (matching_type->shared_from_this());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004461 ++num_matches;
4462 if (num_matches >= max_matches)
4463 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004464 }
4465 }
4466
4467 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004468 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004469}
4470
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004471
4472size_t
Greg Clayton5113dc82011-08-12 06:47:54 +00004473SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
4474 clang::DeclContext *containing_decl_ctx,
Greg Clayton5113dc82011-08-12 06:47:54 +00004475 DWARFCompileUnit* dwarf_cu,
4476 const DWARFDebugInfoEntry *parent_die,
4477 bool skip_artificial,
4478 bool &is_static,
Greg Clayton03969752014-02-24 18:53:11 +00004479 bool &is_variadic,
Greg Clayton57ee3062013-07-11 22:46:58 +00004480 std::vector<ClangASTType>& function_param_types,
Greg Clayton5113dc82011-08-12 06:47:54 +00004481 std::vector<clang::ParmVarDecl*>& function_param_decls,
Greg Claytond20deac2014-04-04 18:15:18 +00004482 unsigned &type_quals) // ,
4483 // ClangASTContext::TemplateParameterInfos &template_param_infos))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004484{
4485 if (parent_die == NULL)
4486 return 0;
4487
Todd Fialaee8bfc62014-09-11 17:29:12 +00004488 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Greg Claytond88d7592010-09-15 08:33:30 +00004489
Greg Clayton7fedea22010-11-16 02:10:54 +00004490 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004491 const DWARFDebugInfoEntry *die;
4492 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
4493 {
4494 dw_tag_t tag = die->Tag();
4495 switch (tag)
4496 {
4497 case DW_TAG_formal_parameter:
4498 {
4499 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004500 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004501 if (num_attributes > 0)
4502 {
4503 const char *name = NULL;
4504 Declaration decl;
4505 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00004506 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004507 // one of None, Auto, Register, Extern, Static, PrivateExtern
4508
Sean Callanane2ef6e32010-09-23 03:01:22 +00004509 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004510 uint32_t i;
4511 for (i=0; i<num_attributes; ++i)
4512 {
4513 const dw_attr_t attr = attributes.AttributeAtIndex(i);
4514 DWARFFormValue form_value;
4515 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4516 {
4517 switch (attr)
4518 {
4519 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4520 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4521 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4522 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00004523 case DW_AT_type: param_type_die_offset = form_value.Reference(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00004524 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004525 case DW_AT_location:
4526 // if (form_value.BlockData())
4527 // {
Ed Masteeeae7212013-10-24 20:43:47 +00004528 // const DWARFDataExtractor& debug_info_data = debug_info();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004529 // uint32_t block_length = form_value.Unsigned();
Ed Masteeeae7212013-10-24 20:43:47 +00004530 // DWARFDataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004531 // }
4532 // else
4533 // {
4534 // }
4535 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004536 case DW_AT_const_value:
4537 case DW_AT_default_value:
4538 case DW_AT_description:
4539 case DW_AT_endianity:
4540 case DW_AT_is_optional:
4541 case DW_AT_segment:
4542 case DW_AT_variable_parameter:
4543 default:
4544 case DW_AT_abstract_origin:
4545 case DW_AT_sibling:
4546 break;
4547 }
4548 }
4549 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00004550
Greg Clayton0fffff52010-09-24 05:15:53 +00004551 bool skip = false;
4552 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004553 {
Greg Clayton0fffff52010-09-24 05:15:53 +00004554 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00004555 {
4556 // In order to determine if a C++ member function is
4557 // "const" we have to look at the const-ness of "this"...
4558 // Ugly, but that
4559 if (arg_idx == 0)
4560 {
Greg Claytonf0705c82011-10-22 03:33:13 +00004561 if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
Sean Callanan763d72a2011-08-02 22:21:50 +00004562 {
Greg Clayton5113dc82011-08-12 06:47:54 +00004563 // Often times compilers omit the "this" name for the
4564 // specification DIEs, so we can't rely upon the name
4565 // being in the formal parameter DIE...
4566 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton7fedea22010-11-16 02:10:54 +00004567 {
Greg Clayton5113dc82011-08-12 06:47:54 +00004568 Type *this_type = ResolveTypeUID (param_type_die_offset);
4569 if (this_type)
4570 {
4571 uint32_t encoding_mask = this_type->GetEncodingMask();
4572 if (encoding_mask & Type::eEncodingIsPointerUID)
4573 {
4574 is_static = false;
4575
4576 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
4577 type_quals |= clang::Qualifiers::Const;
4578 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
4579 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00004580 }
4581 }
4582 }
4583 }
4584 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004585 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00004586 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004587 else
4588 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004589
Greg Clayton0fffff52010-09-24 05:15:53 +00004590 // HACK: Objective C formal parameters "self" and "_cmd"
4591 // are not marked as artificial in the DWARF...
Greg Clayton53eb1c22012-04-02 22:59:12 +00004592 CompileUnit *comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
4593 if (comp_unit)
Greg Clayton0fffff52010-09-24 05:15:53 +00004594 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00004595 switch (comp_unit->GetLanguage())
4596 {
4597 case eLanguageTypeObjC:
4598 case eLanguageTypeObjC_plus_plus:
4599 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
4600 skip = true;
4601 break;
4602 default:
4603 break;
4604 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004605 }
4606 }
4607 }
4608
4609 if (!skip)
4610 {
4611 Type *type = ResolveTypeUID(param_type_die_offset);
4612 if (type)
4613 {
Greg Claytonc93237c2010-10-01 20:48:32 +00004614 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00004615
Greg Clayton42ce2f32011-12-12 21:50:19 +00004616 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name,
4617 type->GetClangForwardType(),
4618 storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00004619 assert(param_var_decl);
4620 function_param_decls.push_back(param_var_decl);
Sean Callanan60217122012-04-13 00:10:03 +00004621
Greg Claytond0029442013-03-27 01:48:02 +00004622 GetClangASTContext().SetMetadataAsUserID (param_var_decl, MakeUserID(die->GetOffset()));
Greg Clayton0fffff52010-09-24 05:15:53 +00004623 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004624 }
4625 }
Greg Clayton7fedea22010-11-16 02:10:54 +00004626 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004627 }
4628 break;
4629
Greg Clayton03969752014-02-24 18:53:11 +00004630 case DW_TAG_unspecified_parameters:
4631 is_variadic = true;
4632 break;
4633
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00004634 case DW_TAG_template_type_parameter:
4635 case DW_TAG_template_value_parameter:
Greg Claytond20deac2014-04-04 18:15:18 +00004636 // The one caller of this was never using the template_param_infos,
4637 // and the local variable was taking up a large amount of stack space
4638 // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
4639 // the template params back, we can add them back.
4640 // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00004641 break;
4642
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004643 default:
4644 break;
4645 }
4646 }
Greg Clayton7fedea22010-11-16 02:10:54 +00004647 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004648}
4649
4650size_t
4651SymbolFileDWARF::ParseChildEnumerators
4652(
4653 const SymbolContext& sc,
Greg Clayton57ee3062013-07-11 22:46:58 +00004654 lldb_private::ClangASTType &clang_type,
Greg Clayton3e067532013-03-05 23:54:39 +00004655 bool is_signed,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004656 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00004657 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004658 const DWARFDebugInfoEntry *parent_die
4659)
4660{
4661 if (parent_die == NULL)
4662 return 0;
4663
4664 size_t enumerators_added = 0;
4665 const DWARFDebugInfoEntry *die;
Todd Fialaee8bfc62014-09-11 17:29:12 +00004666 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Greg Claytond88d7592010-09-15 08:33:30 +00004667
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004668 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
4669 {
4670 const dw_tag_t tag = die->Tag();
4671 if (tag == DW_TAG_enumerator)
4672 {
4673 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004674 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004675 if (num_child_attributes > 0)
4676 {
4677 const char *name = NULL;
4678 bool got_value = false;
4679 int64_t enum_value = 0;
4680 Declaration decl;
4681
4682 uint32_t i;
4683 for (i=0; i<num_child_attributes; ++i)
4684 {
4685 const dw_attr_t attr = attributes.AttributeAtIndex(i);
4686 DWARFFormValue form_value;
4687 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4688 {
4689 switch (attr)
4690 {
4691 case DW_AT_const_value:
4692 got_value = true;
Greg Clayton3e067532013-03-05 23:54:39 +00004693 if (is_signed)
4694 enum_value = form_value.Signed();
4695 else
4696 enum_value = form_value.Unsigned();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004697 break;
4698
4699 case DW_AT_name:
4700 name = form_value.AsCString(&get_debug_str_data());
4701 break;
4702
4703 case DW_AT_description:
4704 default:
4705 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4706 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4707 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4708 case DW_AT_sibling:
4709 break;
4710 }
4711 }
4712 }
4713
4714 if (name && name[0] && got_value)
4715 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00004716 clang_type.AddEnumerationValueToEnumerationType (clang_type.GetEnumerationIntegerType(),
4717 decl,
4718 name,
4719 enum_value,
4720 enumerator_byte_size * 8);
4721 ++enumerators_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004722 }
4723 }
4724 }
4725 }
4726 return enumerators_added;
4727}
4728
4729void
4730SymbolFileDWARF::ParseChildArrayInfo
4731(
4732 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004733 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004734 const DWARFDebugInfoEntry *parent_die,
4735 int64_t& first_index,
4736 std::vector<uint64_t>& element_orders,
4737 uint32_t& byte_stride,
4738 uint32_t& bit_stride
4739)
4740{
4741 if (parent_die == NULL)
4742 return;
4743
4744 const DWARFDebugInfoEntry *die;
Todd Fialaee8bfc62014-09-11 17:29:12 +00004745 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004746 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
4747 {
4748 const dw_tag_t tag = die->Tag();
4749 switch (tag)
4750 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004751 case DW_TAG_subrange_type:
4752 {
4753 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004754 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004755 if (num_child_attributes > 0)
4756 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004757 uint64_t num_elements = 0;
4758 uint64_t lower_bound = 0;
4759 uint64_t upper_bound = 0;
Greg Clayton4ef877f2012-12-06 02:33:54 +00004760 bool upper_bound_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004761 uint32_t i;
4762 for (i=0; i<num_child_attributes; ++i)
4763 {
4764 const dw_attr_t attr = attributes.AttributeAtIndex(i);
4765 DWARFFormValue form_value;
4766 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4767 {
4768 switch (attr)
4769 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004770 case DW_AT_name:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004771 break;
4772
4773 case DW_AT_count:
4774 num_elements = form_value.Unsigned();
4775 break;
4776
4777 case DW_AT_bit_stride:
4778 bit_stride = form_value.Unsigned();
4779 break;
4780
4781 case DW_AT_byte_stride:
4782 byte_stride = form_value.Unsigned();
4783 break;
4784
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004785 case DW_AT_lower_bound:
4786 lower_bound = form_value.Unsigned();
4787 break;
4788
4789 case DW_AT_upper_bound:
Greg Clayton4ef877f2012-12-06 02:33:54 +00004790 upper_bound_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004791 upper_bound = form_value.Unsigned();
4792 break;
4793
4794 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004795 case DW_AT_abstract_origin:
4796 case DW_AT_accessibility:
4797 case DW_AT_allocated:
4798 case DW_AT_associated:
4799 case DW_AT_data_location:
4800 case DW_AT_declaration:
4801 case DW_AT_description:
4802 case DW_AT_sibling:
4803 case DW_AT_threads_scaled:
4804 case DW_AT_type:
4805 case DW_AT_visibility:
4806 break;
4807 }
4808 }
4809 }
4810
Greg Claytone6a07792012-12-05 21:59:39 +00004811 if (num_elements == 0)
4812 {
Greg Clayton4ef877f2012-12-06 02:33:54 +00004813 if (upper_bound_valid && upper_bound >= lower_bound)
Greg Claytone6a07792012-12-05 21:59:39 +00004814 num_elements = upper_bound - lower_bound + 1;
4815 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004816
Sean Callananec979ba2012-10-22 23:56:48 +00004817 element_orders.push_back (num_elements);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004818 }
4819 }
4820 break;
4821 }
4822 }
4823}
4824
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004825TypeSP
Greg Clayton53eb1c22012-04-02 22:59:12 +00004826SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004827{
4828 TypeSP type_sp;
4829 if (die != NULL)
4830 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00004831 assert(dwarf_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00004832 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004833 if (type_ptr == NULL)
4834 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00004835 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(dwarf_cu);
Greg Claytonca512b32011-01-14 04:54:56 +00004836 assert (lldb_cu);
4837 SymbolContext sc(lldb_cu);
Greg Clayton53eb1c22012-04-02 22:59:12 +00004838 type_sp = ParseType(sc, dwarf_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004839 }
4840 else if (type_ptr != DIE_IS_BEING_PARSED)
4841 {
4842 // Grab the existing type from the master types lists
Greg Claytone1cd1be2012-01-29 20:56:30 +00004843 type_sp = type_ptr->shared_from_this();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004844 }
4845
4846 }
4847 return type_sp;
4848}
4849
4850clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00004851SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004852{
4853 if (die_offset != DW_INVALID_OFFSET)
4854 {
4855 DWARFCompileUnitSP cu_sp;
4856 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Greg Claytoncb5860a2011-10-13 23:49:28 +00004857 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004858 }
4859 return NULL;
4860}
4861
Sean Callanan72e49402011-08-05 23:43:37 +00004862clang::DeclContext *
4863SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
4864{
4865 if (die_offset != DW_INVALID_OFFSET)
4866 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004867 DWARFDebugInfo* debug_info = DebugInfo();
4868 if (debug_info)
4869 {
4870 DWARFCompileUnitSP cu_sp;
4871 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
4872 if (die)
4873 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
4874 }
Sean Callanan72e49402011-08-05 23:43:37 +00004875 }
4876 return NULL;
4877}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004878
Greg Clayton96d7d742010-11-10 23:42:09 +00004879clang::NamespaceDecl *
Greg Clayton53eb1c22012-04-02 22:59:12 +00004880SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry *die)
Greg Clayton96d7d742010-11-10 23:42:09 +00004881{
Greg Clayton030a2042011-10-14 21:34:45 +00004882 if (die && die->Tag() == DW_TAG_namespace)
Greg Clayton96d7d742010-11-10 23:42:09 +00004883 {
Greg Clayton030a2042011-10-14 21:34:45 +00004884 // See if we already parsed this namespace DIE and associated it with a
4885 // uniqued namespace declaration
4886 clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
4887 if (namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00004888 return namespace_decl;
Greg Clayton030a2042011-10-14 21:34:45 +00004889 else
4890 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00004891 const char *namespace_name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL);
4892 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, NULL);
Greg Clayton9d3d6882011-10-31 23:51:19 +00004893 namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
Greg Clayton5160ce52013-03-27 23:08:40 +00004894 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton9d3d6882011-10-31 23:51:19 +00004895 if (log)
Greg Clayton030a2042011-10-14 21:34:45 +00004896 {
Greg Clayton9d3d6882011-10-31 23:51:19 +00004897 if (namespace_name)
Greg Clayton030a2042011-10-14 21:34:45 +00004898 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004899 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00004900 "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004901 static_cast<void*>(GetClangASTContext().getASTContext()),
Greg Claytone38a5ed2012-01-05 03:57:59 +00004902 MakeUserID(die->GetOffset()),
4903 namespace_name,
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004904 static_cast<void*>(namespace_decl),
4905 static_cast<void*>(namespace_decl->getOriginalNamespace()));
Greg Clayton030a2042011-10-14 21:34:45 +00004906 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00004907 else
4908 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004909 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00004910 "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004911 static_cast<void*>(GetClangASTContext().getASTContext()),
Greg Claytone38a5ed2012-01-05 03:57:59 +00004912 MakeUserID(die->GetOffset()),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004913 static_cast<void*>(namespace_decl),
4914 static_cast<void*>(namespace_decl->getOriginalNamespace()));
Greg Clayton9d3d6882011-10-31 23:51:19 +00004915 }
Greg Clayton030a2042011-10-14 21:34:45 +00004916 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00004917
4918 if (namespace_decl)
4919 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
4920 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00004921 }
4922 }
4923 return NULL;
4924}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004925
4926clang::DeclContext *
Greg Claytoncab36a32011-12-08 05:16:30 +00004927SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
Sean Callanan72e49402011-08-05 23:43:37 +00004928{
Greg Clayton5cf58b92011-10-05 22:22:08 +00004929 clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
4930 if (clang_decl_ctx)
4931 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00004932 // If this DIE has a specification, or an abstract origin, then trace to those.
4933
Greg Claytoncab36a32011-12-08 05:16:30 +00004934 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
Sean Callanan72e49402011-08-05 23:43:37 +00004935 if (die_offset != DW_INVALID_OFFSET)
4936 return GetClangDeclContextForDIEOffset (sc, die_offset);
4937
Greg Claytoncab36a32011-12-08 05:16:30 +00004938 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
Sean Callanan72e49402011-08-05 23:43:37 +00004939 if (die_offset != DW_INVALID_OFFSET)
4940 return GetClangDeclContextForDIEOffset (sc, die_offset);
4941
Greg Clayton5160ce52013-03-27 23:08:40 +00004942 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00004943 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00004944 GetObjectFile()->GetModule()->LogMessage(log, "SymbolFileDWARF::GetClangDeclContextForDIE (die = 0x%8.8x) %s '%s'", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, cu));
Sean Callanan72e49402011-08-05 23:43:37 +00004945 // This is the DIE we want. Parse it, then query our map.
Greg Claytoncab36a32011-12-08 05:16:30 +00004946 bool assert_not_being_parsed = true;
4947 ResolveTypeUID (cu, die, assert_not_being_parsed);
4948
Greg Clayton5cf58b92011-10-05 22:22:08 +00004949 clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
4950
4951 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00004952}
4953
4954clang::DeclContext *
Greg Claytoncb5860a2011-10-13 23:49:28 +00004955SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004956{
Greg Claytonca512b32011-01-14 04:54:56 +00004957 if (m_clang_tu_decl == NULL)
4958 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004959
Greg Clayton2bc22f82011-09-30 03:20:47 +00004960 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
Greg Claytoncb5860a2011-10-13 23:49:28 +00004961
4962 if (decl_ctx_die_copy)
4963 *decl_ctx_die_copy = decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00004964
4965 if (decl_ctx_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004966 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00004967
Greg Clayton2bc22f82011-09-30 03:20:47 +00004968 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
4969 if (pos != m_die_to_decl_ctx.end())
4970 return pos->second;
4971
4972 switch (decl_ctx_die->Tag())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004973 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00004974 case DW_TAG_compile_unit:
4975 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004976
Greg Clayton2bc22f82011-09-30 03:20:47 +00004977 case DW_TAG_namespace:
Greg Clayton030a2042011-10-14 21:34:45 +00004978 return ResolveNamespaceDIE (cu, decl_ctx_die);
Greg Clayton2bc22f82011-09-30 03:20:47 +00004979 break;
4980
4981 case DW_TAG_structure_type:
4982 case DW_TAG_union_type:
4983 case DW_TAG_class_type:
4984 {
4985 Type* type = ResolveType (cu, decl_ctx_die);
4986 if (type)
4987 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00004988 clang::DeclContext *decl_ctx = type->GetClangForwardType().GetDeclContextForType ();
Greg Clayton2bc22f82011-09-30 03:20:47 +00004989 if (decl_ctx)
Greg Claytonca512b32011-01-14 04:54:56 +00004990 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00004991 LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
4992 if (decl_ctx)
4993 return decl_ctx;
Greg Claytonca512b32011-01-14 04:54:56 +00004994 }
4995 }
Greg Claytonca512b32011-01-14 04:54:56 +00004996 }
Greg Clayton2bc22f82011-09-30 03:20:47 +00004997 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004998
Greg Clayton2bc22f82011-09-30 03:20:47 +00004999 default:
5000 break;
Greg Claytonca512b32011-01-14 04:54:56 +00005001 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005002 }
Greg Clayton7a345282010-11-09 23:46:37 +00005003 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005004}
5005
Greg Clayton2bc22f82011-09-30 03:20:47 +00005006
5007const DWARFDebugInfoEntry *
5008SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
5009{
5010 if (cu && die)
5011 {
5012 const DWARFDebugInfoEntry * const decl_die = die;
5013
5014 while (die != NULL)
5015 {
5016 // If this is the original DIE that we are searching for a declaration
5017 // for, then don't look in the cache as we don't want our own decl
5018 // context to be our decl context...
5019 if (decl_die != die)
5020 {
5021 switch (die->Tag())
5022 {
5023 case DW_TAG_compile_unit:
5024 case DW_TAG_namespace:
5025 case DW_TAG_structure_type:
5026 case DW_TAG_union_type:
5027 case DW_TAG_class_type:
5028 return die;
5029
5030 default:
5031 break;
5032 }
5033 }
5034
5035 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
5036 if (die_offset != DW_INVALID_OFFSET)
5037 {
5038 DWARFCompileUnit *spec_cu = cu;
5039 const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
5040 const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
5041 if (spec_die_decl_ctx_die)
5042 return spec_die_decl_ctx_die;
5043 }
5044
5045 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
5046 if (die_offset != DW_INVALID_OFFSET)
5047 {
5048 DWARFCompileUnit *abs_cu = cu;
5049 const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
5050 const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
5051 if (abs_die_decl_ctx_die)
5052 return abs_die_decl_ctx_die;
5053 }
5054
5055 die = die->GetParent();
5056 }
5057 }
5058 return NULL;
5059}
5060
5061
Greg Clayton901c5ca2011-12-03 04:40:03 +00005062Symbol *
5063SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
5064{
5065 Symbol *objc_class_symbol = NULL;
5066 if (m_obj_file)
5067 {
Greg Clayton3046e662013-07-10 01:23:25 +00005068 Symtab *symtab = m_obj_file->GetSymtab ();
Greg Clayton901c5ca2011-12-03 04:40:03 +00005069 if (symtab)
5070 {
5071 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
5072 eSymbolTypeObjCClass,
5073 Symtab::eDebugNo,
5074 Symtab::eVisibilityAny);
5075 }
5076 }
5077 return objc_class_symbol;
5078}
5079
Greg Claytonc7f03b62012-01-12 04:33:28 +00005080// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
5081// then we can end up looking through all class types for a complete type and never find
5082// the full definition. We need to know if this attribute is supported, so we determine
5083// this here and cache th result. We also need to worry about the debug map DWARF file
5084// if we are doing darwin DWARF in .o file debugging.
5085bool
5086SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
5087{
5088 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
5089 {
5090 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
5091 if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
5092 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
5093 else
5094 {
5095 DWARFDebugInfo* debug_info = DebugInfo();
5096 const uint32_t num_compile_units = GetNumCompileUnits();
5097 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
5098 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00005099 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
5100 if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
Greg Claytonc7f03b62012-01-12 04:33:28 +00005101 {
5102 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
5103 break;
5104 }
5105 }
5106 }
Greg Clayton1f746072012-08-29 21:13:06 +00005107 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
Greg Claytonc7f03b62012-01-12 04:33:28 +00005108 return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
5109 }
5110 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
5111}
Greg Clayton901c5ca2011-12-03 04:40:03 +00005112
5113// This function can be used when a DIE is found that is a forward declaration
5114// DIE and we want to try and find a type that has the complete definition.
5115TypeSP
Greg Claytonc7f03b62012-01-12 04:33:28 +00005116SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
5117 const ConstString &type_name,
5118 bool must_be_implementation)
Greg Clayton901c5ca2011-12-03 04:40:03 +00005119{
5120
5121 TypeSP type_sp;
5122
Greg Claytonc7f03b62012-01-12 04:33:28 +00005123 if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
Greg Clayton901c5ca2011-12-03 04:40:03 +00005124 return type_sp;
5125
5126 DIEArray die_offsets;
5127
5128 if (m_using_apple_tables)
5129 {
5130 if (m_apple_types_ap.get())
5131 {
5132 const char *name_cstr = type_name.GetCString();
Greg Clayton68221ec2012-01-18 20:58:12 +00005133 m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
Greg Clayton901c5ca2011-12-03 04:40:03 +00005134 }
5135 }
5136 else
5137 {
5138 if (!m_indexed)
5139 Index ();
5140
5141 m_type_index.Find (type_name, die_offsets);
5142 }
5143
Greg Clayton901c5ca2011-12-03 04:40:03 +00005144 const size_t num_matches = die_offsets.size();
5145
Greg Clayton901c5ca2011-12-03 04:40:03 +00005146 DWARFCompileUnit* type_cu = NULL;
5147 const DWARFDebugInfoEntry* type_die = NULL;
5148 if (num_matches)
5149 {
5150 DWARFDebugInfo* debug_info = DebugInfo();
5151 for (size_t i=0; i<num_matches; ++i)
5152 {
5153 const dw_offset_t die_offset = die_offsets[i];
5154 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
5155
5156 if (type_die)
5157 {
5158 bool try_resolving_type = false;
5159
5160 // Don't try and resolve the DIE we are looking for with the DIE itself!
5161 if (type_die != die)
5162 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00005163 switch (type_die->Tag())
Greg Clayton901c5ca2011-12-03 04:40:03 +00005164 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00005165 case DW_TAG_class_type:
5166 case DW_TAG_structure_type:
5167 try_resolving_type = true;
5168 break;
5169 default:
5170 break;
Greg Clayton901c5ca2011-12-03 04:40:03 +00005171 }
5172 }
5173
5174 if (try_resolving_type)
5175 {
Ed Maste4c24b122013-10-17 20:13:14 +00005176 if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type())
5177 try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0);
Greg Clayton901c5ca2011-12-03 04:40:03 +00005178
5179 if (try_resolving_type)
5180 {
5181 Type *resolved_type = ResolveType (type_cu, type_die, false);
5182 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
5183 {
Ed Mastea0191d12013-10-17 20:42:56 +00005184 DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
Greg Clayton901c5ca2011-12-03 04:40:03 +00005185 MakeUserID(die->GetOffset()),
Jim Ingham4af59612014-12-19 19:20:44 +00005186 m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
Greg Clayton901c5ca2011-12-03 04:40:03 +00005187 MakeUserID(type_die->GetOffset()),
5188 MakeUserID(type_cu->GetOffset()));
5189
Greg Claytonc7f03b62012-01-12 04:33:28 +00005190 if (die)
5191 m_die_to_type[die] = resolved_type;
Greg Claytone1cd1be2012-01-29 20:56:30 +00005192 type_sp = resolved_type->shared_from_this();
Greg Clayton901c5ca2011-12-03 04:40:03 +00005193 break;
5194 }
5195 }
5196 }
5197 }
5198 else
5199 {
5200 if (m_using_apple_tables)
5201 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00005202 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
5203 die_offset, type_name.GetCString());
Greg Clayton901c5ca2011-12-03 04:40:03 +00005204 }
5205 }
5206
5207 }
5208 }
5209 return type_sp;
5210}
5211
Greg Claytona8022fa2012-04-24 21:22:41 +00005212
Greg Clayton80c26302012-02-05 06:12:47 +00005213//----------------------------------------------------------------------
5214// This function helps to ensure that the declaration contexts match for
5215// two different DIEs. Often times debug information will refer to a
5216// forward declaration of a type (the equivalent of "struct my_struct;".
5217// There will often be a declaration of that type elsewhere that has the
5218// full definition. When we go looking for the full type "my_struct", we
5219// will find one or more matches in the accelerator tables and we will
5220// then need to make sure the type was in the same declaration context
5221// as the original DIE. This function can efficiently compare two DIEs
5222// and will return true when the declaration context matches, and false
5223// when they don't.
5224//----------------------------------------------------------------------
Greg Clayton890ff562012-02-02 05:48:16 +00005225bool
5226SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1,
5227 DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2)
5228{
Greg Claytona8022fa2012-04-24 21:22:41 +00005229 if (die1 == die2)
5230 return true;
5231
5232#if defined (LLDB_CONFIGURATION_DEBUG)
5233 // You can't and shouldn't call this function with a compile unit from
5234 // two different SymbolFileDWARF instances.
5235 assert (DebugInfo()->ContainsCompileUnit (cu1));
5236 assert (DebugInfo()->ContainsCompileUnit (cu2));
5237#endif
5238
Greg Clayton890ff562012-02-02 05:48:16 +00005239 DWARFDIECollection decl_ctx_1;
5240 DWARFDIECollection decl_ctx_2;
Greg Clayton80c26302012-02-05 06:12:47 +00005241 //The declaration DIE stack is a stack of the declaration context
5242 // DIEs all the way back to the compile unit. If a type "T" is
5243 // declared inside a class "B", and class "B" is declared inside
5244 // a class "A" and class "A" is in a namespace "lldb", and the
5245 // namespace is in a compile unit, there will be a stack of DIEs:
5246 //
5247 // [0] DW_TAG_class_type for "B"
5248 // [1] DW_TAG_class_type for "A"
5249 // [2] DW_TAG_namespace for "lldb"
5250 // [3] DW_TAG_compile_unit for the source file.
5251 //
5252 // We grab both contexts and make sure that everything matches
5253 // all the way back to the compiler unit.
5254
5255 // First lets grab the decl contexts for both DIEs
Greg Clayton890ff562012-02-02 05:48:16 +00005256 die1->GetDeclContextDIEs (this, cu1, decl_ctx_1);
Sean Callanan5b26f272012-02-04 08:49:35 +00005257 die2->GetDeclContextDIEs (this, cu2, decl_ctx_2);
Greg Clayton80c26302012-02-05 06:12:47 +00005258 // Make sure the context arrays have the same size, otherwise
5259 // we are done
Greg Clayton890ff562012-02-02 05:48:16 +00005260 const size_t count1 = decl_ctx_1.Size();
5261 const size_t count2 = decl_ctx_2.Size();
5262 if (count1 != count2)
5263 return false;
Greg Clayton80c26302012-02-05 06:12:47 +00005264
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00005265 // Make sure the DW_TAG values match all the way back up the
Greg Clayton80c26302012-02-05 06:12:47 +00005266 // compile unit. If they don't, then we are done.
Greg Clayton890ff562012-02-02 05:48:16 +00005267 const DWARFDebugInfoEntry *decl_ctx_die1;
5268 const DWARFDebugInfoEntry *decl_ctx_die2;
5269 size_t i;
5270 for (i=0; i<count1; i++)
5271 {
5272 decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
5273 decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
5274 if (decl_ctx_die1->Tag() != decl_ctx_die2->Tag())
5275 return false;
5276 }
Greg Clayton890ff562012-02-02 05:48:16 +00005277#if defined LLDB_CONFIGURATION_DEBUG
Greg Clayton80c26302012-02-05 06:12:47 +00005278
5279 // Make sure the top item in the decl context die array is always
5280 // DW_TAG_compile_unit. If it isn't then something went wrong in
5281 // the DWARFDebugInfoEntry::GetDeclContextDIEs() function...
Greg Clayton890ff562012-02-02 05:48:16 +00005282 assert (decl_ctx_1.GetDIEPtrAtIndex (count1 - 1)->Tag() == DW_TAG_compile_unit);
Greg Clayton80c26302012-02-05 06:12:47 +00005283
Greg Clayton890ff562012-02-02 05:48:16 +00005284#endif
5285 // Always skip the compile unit when comparing by only iterating up to
Greg Clayton80c26302012-02-05 06:12:47 +00005286 // "count - 1". Here we compare the names as we go.
Greg Clayton890ff562012-02-02 05:48:16 +00005287 for (i=0; i<count1 - 1; i++)
5288 {
5289 decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
5290 decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
5291 const char *name1 = decl_ctx_die1->GetName(this, cu1);
Sean Callanan5b26f272012-02-04 08:49:35 +00005292 const char *name2 = decl_ctx_die2->GetName(this, cu2);
Greg Clayton890ff562012-02-02 05:48:16 +00005293 // If the string was from a DW_FORM_strp, then the pointer will often
5294 // be the same!
Greg Clayton5569e642012-02-06 01:44:54 +00005295 if (name1 == name2)
5296 continue;
5297
5298 // Name pointers are not equal, so only compare the strings
5299 // if both are not NULL.
5300 if (name1 && name2)
Greg Clayton890ff562012-02-02 05:48:16 +00005301 {
Greg Clayton5569e642012-02-06 01:44:54 +00005302 // If the strings don't compare, we are done...
5303 if (strcmp(name1, name2) != 0)
Greg Clayton890ff562012-02-02 05:48:16 +00005304 return false;
Greg Clayton5569e642012-02-06 01:44:54 +00005305 }
5306 else
5307 {
5308 // One name was NULL while the other wasn't
5309 return false;
Greg Clayton890ff562012-02-02 05:48:16 +00005310 }
5311 }
Greg Clayton80c26302012-02-05 06:12:47 +00005312 // We made it through all of the checks and the declaration contexts
5313 // are equal.
Greg Clayton890ff562012-02-02 05:48:16 +00005314 return true;
5315}
Greg Clayton220a0072011-12-09 08:48:30 +00005316
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00005317
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005318TypeSP
Greg Claytona8022fa2012-04-24 21:22:41 +00005319SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
5320{
5321 TypeSP type_sp;
5322
5323 const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
5324 if (dwarf_decl_ctx_count > 0)
5325 {
5326 const ConstString type_name(dwarf_decl_ctx[0].name);
5327 const dw_tag_t tag = dwarf_decl_ctx[0].tag;
5328
5329 if (type_name)
5330 {
Greg Clayton5160ce52013-03-27 23:08:40 +00005331 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
Greg Claytona8022fa2012-04-24 21:22:41 +00005332 if (log)
5333 {
Greg Clayton5160ce52013-03-27 23:08:40 +00005334 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00005335 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
5336 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
5337 dwarf_decl_ctx.GetQualifiedName());
5338 }
5339
5340 DIEArray die_offsets;
5341
5342 if (m_using_apple_tables)
5343 {
5344 if (m_apple_types_ap.get())
5345 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00005346 const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
5347 const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
5348 if (has_tag && has_qualified_name_hash)
Greg Claytona8022fa2012-04-24 21:22:41 +00005349 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00005350 const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
5351 const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
5352 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005353 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00005354 m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
5355 }
5356 else if (has_tag)
5357 {
5358 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005359 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
Greg Claytona8022fa2012-04-24 21:22:41 +00005360 m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
5361 }
5362 else
5363 {
5364 m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
5365 }
5366 }
5367 }
5368 else
5369 {
5370 if (!m_indexed)
5371 Index ();
5372
5373 m_type_index.Find (type_name, die_offsets);
5374 }
5375
5376 const size_t num_matches = die_offsets.size();
5377
5378
5379 DWARFCompileUnit* type_cu = NULL;
5380 const DWARFDebugInfoEntry* type_die = NULL;
5381 if (num_matches)
5382 {
5383 DWARFDebugInfo* debug_info = DebugInfo();
5384 for (size_t i=0; i<num_matches; ++i)
5385 {
5386 const dw_offset_t die_offset = die_offsets[i];
5387 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
5388
5389 if (type_die)
5390 {
5391 bool try_resolving_type = false;
5392
5393 // Don't try and resolve the DIE we are looking for with the DIE itself!
5394 const dw_tag_t type_tag = type_die->Tag();
5395 // Make sure the tags match
5396 if (type_tag == tag)
5397 {
5398 // The tags match, lets try resolving this type
5399 try_resolving_type = true;
5400 }
5401 else
5402 {
5403 // The tags don't match, but we need to watch our for a
5404 // forward declaration for a struct and ("struct foo")
5405 // ends up being a class ("class foo { ... };") or
5406 // vice versa.
5407 switch (type_tag)
5408 {
5409 case DW_TAG_class_type:
5410 // We had a "class foo", see if we ended up with a "struct foo { ... };"
5411 try_resolving_type = (tag == DW_TAG_structure_type);
5412 break;
5413 case DW_TAG_structure_type:
5414 // We had a "struct foo", see if we ended up with a "class foo { ... };"
5415 try_resolving_type = (tag == DW_TAG_class_type);
5416 break;
5417 default:
5418 // Tags don't match, don't event try to resolve
5419 // using this type whose name matches....
5420 break;
5421 }
5422 }
5423
5424 if (try_resolving_type)
5425 {
5426 DWARFDeclContext type_dwarf_decl_ctx;
5427 type_die->GetDWARFDeclContext (this, type_cu, type_dwarf_decl_ctx);
5428
5429 if (log)
5430 {
Greg Clayton5160ce52013-03-27 23:08:40 +00005431 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00005432 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
5433 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
5434 dwarf_decl_ctx.GetQualifiedName(),
5435 type_die->GetOffset(),
5436 type_dwarf_decl_ctx.GetQualifiedName());
5437 }
5438
5439 // Make sure the decl contexts match all the way up
5440 if (dwarf_decl_ctx == type_dwarf_decl_ctx)
5441 {
5442 Type *resolved_type = ResolveType (type_cu, type_die, false);
5443 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
5444 {
5445 type_sp = resolved_type->shared_from_this();
5446 break;
5447 }
5448 }
5449 }
5450 else
5451 {
5452 if (log)
5453 {
5454 std::string qualified_name;
5455 type_die->GetQualifiedName(this, type_cu, qualified_name);
Greg Clayton5160ce52013-03-27 23:08:40 +00005456 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00005457 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
5458 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
5459 dwarf_decl_ctx.GetQualifiedName(),
5460 type_die->GetOffset(),
5461 qualified_name.c_str());
5462 }
5463 }
5464 }
5465 else
5466 {
5467 if (m_using_apple_tables)
5468 {
5469 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
5470 die_offset, type_name.GetCString());
5471 }
5472 }
5473
5474 }
5475 }
5476 }
5477 }
5478 return type_sp;
5479}
5480
Greg Clayton4116e932012-05-15 02:33:01 +00005481bool
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005482SymbolFileDWARF::CopyUniqueClassMethodTypes (SymbolFileDWARF *src_symfile,
Sean Callanan2367f8a2013-02-26 01:12:25 +00005483 Type *class_type,
Greg Clayton4116e932012-05-15 02:33:01 +00005484 DWARFCompileUnit* src_cu,
5485 const DWARFDebugInfoEntry *src_class_die,
5486 DWARFCompileUnit* dst_cu,
Sean Callanan2367f8a2013-02-26 01:12:25 +00005487 const DWARFDebugInfoEntry *dst_class_die,
Greg Claytond20deac2014-04-04 18:15:18 +00005488 DWARFDIECollection &failures)
Greg Clayton4116e932012-05-15 02:33:01 +00005489{
5490 if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
5491 return false;
5492 if (src_class_die->Tag() != dst_class_die->Tag())
5493 return false;
5494
5495 // We need to complete the class type so we can get all of the method types
5496 // parsed so we can then unique those types to their equivalent counterparts
5497 // in "dst_cu" and "dst_class_die"
5498 class_type->GetClangFullType();
5499
5500 const DWARFDebugInfoEntry *src_die;
5501 const DWARFDebugInfoEntry *dst_die;
5502 UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die;
5503 UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die;
Greg Clayton65ec1032012-11-12 21:27:20 +00005504 UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die_artificial;
5505 UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die_artificial;
Greg Clayton4116e932012-05-15 02:33:01 +00005506 for (src_die = src_class_die->GetFirstChild(); src_die != NULL; src_die = src_die->GetSibling())
5507 {
5508 if (src_die->Tag() == DW_TAG_subprogram)
5509 {
Greg Clayton84afacd2012-11-07 23:09:32 +00005510 // Make sure this is a declaration and not a concrete instance by looking
5511 // for DW_AT_declaration set to 1. Sometimes concrete function instances
5512 // are placed inside the class definitions and shouldn't be included in
5513 // the list of things are are tracking here.
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005514 if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_declaration, 0) == 1)
Greg Clayton84afacd2012-11-07 23:09:32 +00005515 {
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005516 const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
Greg Clayton84afacd2012-11-07 23:09:32 +00005517 if (src_name)
Greg Clayton65ec1032012-11-12 21:27:20 +00005518 {
5519 ConstString src_const_name(src_name);
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005520 if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_artificial, 0))
Greg Clayton65ec1032012-11-12 21:27:20 +00005521 src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
5522 else
5523 src_name_to_die.Append(src_const_name.GetCString(), src_die);
5524 }
Greg Clayton84afacd2012-11-07 23:09:32 +00005525 }
Greg Clayton4116e932012-05-15 02:33:01 +00005526 }
5527 }
5528 for (dst_die = dst_class_die->GetFirstChild(); dst_die != NULL; dst_die = dst_die->GetSibling())
5529 {
5530 if (dst_die->Tag() == DW_TAG_subprogram)
5531 {
Greg Clayton84afacd2012-11-07 23:09:32 +00005532 // Make sure this is a declaration and not a concrete instance by looking
5533 // for DW_AT_declaration set to 1. Sometimes concrete function instances
5534 // are placed inside the class definitions and shouldn't be included in
5535 // the list of things are are tracking here.
5536 if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_declaration, 0) == 1)
5537 {
5538 const char *dst_name = dst_die->GetMangledName (this, dst_cu);
5539 if (dst_name)
Greg Clayton65ec1032012-11-12 21:27:20 +00005540 {
5541 ConstString dst_const_name(dst_name);
5542 if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_artificial, 0))
5543 dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die);
5544 else
5545 dst_name_to_die.Append(dst_const_name.GetCString(), dst_die);
5546 }
Greg Clayton84afacd2012-11-07 23:09:32 +00005547 }
Greg Clayton4116e932012-05-15 02:33:01 +00005548 }
5549 }
5550 const uint32_t src_size = src_name_to_die.GetSize ();
5551 const uint32_t dst_size = dst_name_to_die.GetSize ();
Greg Clayton5160ce52013-03-27 23:08:40 +00005552 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
Sean Callanan2367f8a2013-02-26 01:12:25 +00005553
5554 // Is everything kosher so we can go through the members at top speed?
5555 bool fast_path = true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005556
Sean Callanan2367f8a2013-02-26 01:12:25 +00005557 if (src_size != dst_size)
Greg Clayton4116e932012-05-15 02:33:01 +00005558 {
Sean Callanan2367f8a2013-02-26 01:12:25 +00005559 if (src_size != 0 && dst_size != 0)
5560 {
5561 if (log)
5562 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)",
5563 src_class_die->GetOffset(),
5564 dst_class_die->GetOffset(),
5565 src_size,
5566 dst_size);
5567 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005568
Sean Callanan2367f8a2013-02-26 01:12:25 +00005569 fast_path = false;
5570 }
5571
5572 uint32_t idx;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005573
Sean Callanan2367f8a2013-02-26 01:12:25 +00005574 if (fast_path)
5575 {
Greg Clayton4116e932012-05-15 02:33:01 +00005576 for (idx = 0; idx < src_size; ++idx)
5577 {
5578 src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
5579 dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
5580
5581 if (src_die->Tag() != dst_die->Tag())
5582 {
5583 if (log)
5584 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)",
5585 src_class_die->GetOffset(),
5586 dst_class_die->GetOffset(),
5587 src_die->GetOffset(),
5588 DW_TAG_value_to_name(src_die->Tag()),
5589 dst_die->GetOffset(),
5590 DW_TAG_value_to_name(src_die->Tag()));
Sean Callanan2367f8a2013-02-26 01:12:25 +00005591 fast_path = false;
Greg Clayton4116e932012-05-15 02:33:01 +00005592 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005593
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005594 const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
Greg Clayton4116e932012-05-15 02:33:01 +00005595 const char *dst_name = dst_die->GetMangledName (this, dst_cu);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005596
Greg Clayton4116e932012-05-15 02:33:01 +00005597 // Make sure the names match
5598 if (src_name == dst_name || (strcmp (src_name, dst_name) == 0))
5599 continue;
5600
5601 if (log)
5602 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)",
5603 src_class_die->GetOffset(),
5604 dst_class_die->GetOffset(),
5605 src_die->GetOffset(),
5606 src_name,
5607 dst_die->GetOffset(),
5608 dst_name);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005609
Sean Callanan2367f8a2013-02-26 01:12:25 +00005610 fast_path = false;
Greg Clayton4116e932012-05-15 02:33:01 +00005611 }
Sean Callanan2367f8a2013-02-26 01:12:25 +00005612 }
Greg Clayton4116e932012-05-15 02:33:01 +00005613
Sean Callanan2367f8a2013-02-26 01:12:25 +00005614 // Now do the work of linking the DeclContexts and Types.
5615 if (fast_path)
5616 {
5617 // We can do this quickly. Just run across the tables index-for-index since
5618 // we know each node has matching names and tags.
Greg Clayton4116e932012-05-15 02:33:01 +00005619 for (idx = 0; idx < src_size; ++idx)
5620 {
5621 src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
5622 dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005623
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005624 clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
Greg Clayton4116e932012-05-15 02:33:01 +00005625 if (src_decl_ctx)
5626 {
5627 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005628 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
5629 static_cast<void*>(src_decl_ctx),
5630 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton4116e932012-05-15 02:33:01 +00005631 LinkDeclContextToDIE (src_decl_ctx, dst_die);
5632 }
5633 else
5634 {
5635 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005636 log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found",
5637 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton4116e932012-05-15 02:33:01 +00005638 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005639
Greg Clayton4116e932012-05-15 02:33:01 +00005640 Type *src_child_type = m_die_to_type[src_die];
5641 if (src_child_type)
5642 {
5643 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005644 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
5645 static_cast<void*>(src_child_type),
5646 src_child_type->GetID(),
5647 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton4116e932012-05-15 02:33:01 +00005648 m_die_to_type[dst_die] = src_child_type;
5649 }
5650 else
5651 {
5652 if (log)
Greg Clayton65ec1032012-11-12 21:27:20 +00005653 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());
5654 }
5655 }
Sean Callanan2367f8a2013-02-26 01:12:25 +00005656 }
5657 else
5658 {
5659 // We must do this slowly. For each member of the destination, look
5660 // up a member in the source with the same name, check its tag, and
5661 // unique them if everything matches up. Report failures.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005662
Sean Callanan2367f8a2013-02-26 01:12:25 +00005663 if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
5664 {
5665 src_name_to_die.Sort();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005666
Sean Callanan2367f8a2013-02-26 01:12:25 +00005667 for (idx = 0; idx < dst_size; ++idx)
5668 {
5669 const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
5670 dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
5671 src_die = src_name_to_die.Find(dst_name, NULL);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005672
Sean Callanan2367f8a2013-02-26 01:12:25 +00005673 if (src_die && (src_die->Tag() == dst_die->Tag()))
5674 {
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005675 clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
Sean Callanan2367f8a2013-02-26 01:12:25 +00005676 if (src_decl_ctx)
5677 {
5678 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005679 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
5680 static_cast<void*>(src_decl_ctx),
5681 src_die->GetOffset(),
5682 dst_die->GetOffset());
Sean Callanan2367f8a2013-02-26 01:12:25 +00005683 LinkDeclContextToDIE (src_decl_ctx, dst_die);
5684 }
5685 else
5686 {
5687 if (log)
5688 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());
5689 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005690
Sean Callanan2367f8a2013-02-26 01:12:25 +00005691 Type *src_child_type = m_die_to_type[src_die];
5692 if (src_child_type)
5693 {
5694 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005695 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
5696 static_cast<void*>(src_child_type),
5697 src_child_type->GetID(),
5698 src_die->GetOffset(),
5699 dst_die->GetOffset());
Sean Callanan2367f8a2013-02-26 01:12:25 +00005700 m_die_to_type[dst_die] = src_child_type;
5701 }
5702 else
5703 {
5704 if (log)
5705 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());
5706 }
5707 }
5708 else
5709 {
5710 if (log)
5711 log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die->GetOffset());
Greg Clayton65ec1032012-11-12 21:27:20 +00005712
Greg Claytond20deac2014-04-04 18:15:18 +00005713 failures.Append(dst_die);
Sean Callanan2367f8a2013-02-26 01:12:25 +00005714 }
5715 }
5716 }
5717 }
5718
5719 const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
5720 const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
5721
5722 UniqueCStringMap<const DWARFDebugInfoEntry *> name_to_die_artificial_not_in_src;
5723
5724 if (src_size_artificial && dst_size_artificial)
5725 {
5726 dst_name_to_die_artificial.Sort();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005727
Greg Clayton65ec1032012-11-12 21:27:20 +00005728 for (idx = 0; idx < src_size_artificial; ++idx)
5729 {
5730 const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
5731 src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
5732 dst_die = dst_name_to_die_artificial.Find(src_name_artificial, NULL);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005733
Greg Clayton65ec1032012-11-12 21:27:20 +00005734 if (dst_die)
5735 {
Greg Clayton65ec1032012-11-12 21:27:20 +00005736 // Both classes have the artificial types, link them
5737 clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
5738 if (src_decl_ctx)
5739 {
5740 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005741 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
5742 static_cast<void*>(src_decl_ctx),
5743 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton65ec1032012-11-12 21:27:20 +00005744 LinkDeclContextToDIE (src_decl_ctx, dst_die);
5745 }
5746 else
5747 {
5748 if (log)
5749 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());
5750 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005751
Greg Clayton65ec1032012-11-12 21:27:20 +00005752 Type *src_child_type = m_die_to_type[src_die];
5753 if (src_child_type)
5754 {
5755 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005756 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
5757 static_cast<void*>(src_child_type),
5758 src_child_type->GetID(),
5759 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton65ec1032012-11-12 21:27:20 +00005760 m_die_to_type[dst_die] = src_child_type;
5761 }
5762 else
5763 {
5764 if (log)
5765 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());
5766 }
5767 }
5768 }
Sean Callanan2367f8a2013-02-26 01:12:25 +00005769 }
Greg Clayton65ec1032012-11-12 21:27:20 +00005770
Sean Callanan2367f8a2013-02-26 01:12:25 +00005771 if (dst_size_artificial)
Greg Clayton4116e932012-05-15 02:33:01 +00005772 {
Sean Callanan2367f8a2013-02-26 01:12:25 +00005773 for (idx = 0; idx < dst_size_artificial; ++idx)
5774 {
5775 const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
5776 dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
5777 if (log)
5778 log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
5779
Greg Claytond20deac2014-04-04 18:15:18 +00005780 failures.Append(dst_die);
Sean Callanan2367f8a2013-02-26 01:12:25 +00005781 }
Greg Clayton4116e932012-05-15 02:33:01 +00005782 }
Sean Callanan2367f8a2013-02-26 01:12:25 +00005783
Greg Claytond20deac2014-04-04 18:15:18 +00005784 return (failures.Size() != 0);
Greg Clayton4116e932012-05-15 02:33:01 +00005785}
Greg Claytona8022fa2012-04-24 21:22:41 +00005786
5787TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00005788SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005789{
5790 TypeSP type_sp;
5791
Greg Clayton1be10fc2010-09-29 01:12:09 +00005792 if (type_is_new_ptr)
5793 *type_is_new_ptr = false;
Greg Clayton1fba87112012-02-09 20:03:49 +00005794
Todd Fiala0a70a842014-05-28 16:43:26 +00005795#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
Greg Clayton1fba87112012-02-09 20:03:49 +00005796 static DIEStack g_die_stack;
5797 DIEStack::ScopedPopper scoped_die_logger(g_die_stack);
5798#endif
Greg Clayton1be10fc2010-09-29 01:12:09 +00005799
Sean Callananc7fbf732010-08-06 00:32:49 +00005800 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005801 if (die != NULL)
5802 {
Greg Clayton5160ce52013-03-27 23:08:40 +00005803 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00005804 if (log)
Sean Callanan5b26f272012-02-04 08:49:35 +00005805 {
5806 const DWARFDebugInfoEntry *context_die;
5807 clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005808
Greg Clayton5160ce52013-03-27 23:08:40 +00005809 GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005810 die->GetOffset(),
5811 static_cast<void*>(context),
5812 context_die->GetOffset(),
5813 DW_TAG_value_to_name(die->Tag()),
5814 die->GetName(this, dwarf_cu));
5815
Todd Fiala0a70a842014-05-28 16:43:26 +00005816#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
Greg Clayton1fba87112012-02-09 20:03:49 +00005817 scoped_die_logger.Push (dwarf_cu, die);
Greg Clayton5160ce52013-03-27 23:08:40 +00005818 g_die_stack.LogDIEs(log, this);
Greg Clayton1fba87112012-02-09 20:03:49 +00005819#endif
Sean Callanan5b26f272012-02-04 08:49:35 +00005820 }
Greg Clayton3bffb082011-12-10 02:15:28 +00005821//
Greg Clayton5160ce52013-03-27 23:08:40 +00005822// Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00005823// if (log && dwarf_cu)
5824// {
5825// StreamString s;
5826// die->DumpLocation (this, dwarf_cu, s);
Greg Clayton5160ce52013-03-27 23:08:40 +00005827// GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
Greg Clayton3bffb082011-12-10 02:15:28 +00005828//
5829// }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005830
Greg Clayton594e5ed2010-09-27 21:07:38 +00005831 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00005832 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00005833 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005834 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00005835 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00005836 if (type_is_new_ptr)
5837 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005838
Greg Clayton594e5ed2010-09-27 21:07:38 +00005839 const dw_tag_t tag = die->Tag();
5840
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005841 bool is_forward_declaration = false;
5842 DWARFDebugInfoEntry::Attributes attributes;
5843 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00005844 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00005845 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
Greg Claytonfaac1112013-03-14 18:31:44 +00005846 uint64_t byte_size = 0;
Greg Clayton526e5af2010-11-13 03:52:47 +00005847 Declaration decl;
5848
Greg Clayton4957bf62010-09-30 21:49:03 +00005849 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton57ee3062013-07-11 22:46:58 +00005850 ClangASTType clang_type;
Greg Claytond20deac2014-04-04 18:15:18 +00005851 DWARFFormValue form_value;
5852
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005853 dw_attr_t attr;
5854
5855 switch (tag)
5856 {
5857 case DW_TAG_base_type:
5858 case DW_TAG_pointer_type:
5859 case DW_TAG_reference_type:
Sean Callanance8af862012-05-21 23:31:51 +00005860 case DW_TAG_rvalue_reference_type:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005861 case DW_TAG_typedef:
5862 case DW_TAG_const_type:
5863 case DW_TAG_restrict_type:
5864 case DW_TAG_volatile_type:
Greg Claytond4436412011-10-28 21:00:00 +00005865 case DW_TAG_unspecified_type:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005866 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005867 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00005868 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005869
Greg Claytond88d7592010-09-15 08:33:30 +00005870 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005871 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005872 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
5873
5874 if (num_attributes > 0)
5875 {
5876 uint32_t i;
5877 for (i=0; i<num_attributes; ++i)
5878 {
5879 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005880 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
5881 {
5882 switch (attr)
5883 {
5884 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
5885 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
5886 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
5887 case DW_AT_name:
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005888
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005889 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00005890 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
5891 // include the "&"...
5892 if (tag == DW_TAG_reference_type)
5893 {
5894 if (strchr (type_name_cstr, '&') == NULL)
5895 type_name_cstr = NULL;
5896 }
5897 if (type_name_cstr)
5898 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005899 break;
Greg Clayton23f59502012-07-17 03:23:13 +00005900 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005901 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
Greg Clayton54166af2014-11-22 01:58:59 +00005902 case DW_AT_type: encoding_uid = form_value.Reference(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005903 default:
5904 case DW_AT_sibling:
5905 break;
5906 }
5907 }
5908 }
5909 }
5910
Ed Mastea0191d12013-10-17 20:42:56 +00005911 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
Greg Claytonc93237c2010-10-01 20:48:32 +00005912
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005913 switch (tag)
5914 {
5915 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00005916 break;
5917
Greg Claytond4436412011-10-28 21:00:00 +00005918 case DW_TAG_unspecified_type:
Greg Clayton7fba2632013-07-01 21:01:52 +00005919 if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
5920 strcmp(type_name_cstr, "decltype(nullptr)") == 0 )
Greg Claytond4436412011-10-28 21:00:00 +00005921 {
5922 resolve_state = Type::eResolveStateFull;
Greg Clayton57ee3062013-07-11 22:46:58 +00005923 clang_type = ast.GetBasicType(eBasicTypeNullPtr);
Greg Claytond4436412011-10-28 21:00:00 +00005924 break;
5925 }
5926 // Fall through to base type below in case we can handle the type there...
5927
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005928 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00005929 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00005930 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
5931 encoding,
5932 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005933 break;
5934
Sean Callanance8af862012-05-21 23:31:51 +00005935 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
5936 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
5937 case DW_TAG_rvalue_reference_type: encoding_data_type = Type::eEncodingIsRValueReferenceUID; break;
5938 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
5939 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
5940 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
5941 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005942 }
5943
Greg Clayton57ee3062013-07-11 22:46:58 +00005944 if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00005945 {
Sean Callanan82587052013-01-03 00:05:56 +00005946 bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005947
Sean Callanan82587052013-01-03 00:05:56 +00005948 if (translation_unit_is_objc)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00005949 {
Sean Callanan82587052013-01-03 00:05:56 +00005950 if (type_name_cstr != NULL)
Greg Claytonc7f03b62012-01-12 04:33:28 +00005951 {
Sean Callanan82587052013-01-03 00:05:56 +00005952 static ConstString g_objc_type_name_id("id");
5953 static ConstString g_objc_type_name_Class("Class");
5954 static ConstString g_objc_type_name_selector("SEL");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005955
Sean Callanan82587052013-01-03 00:05:56 +00005956 if (type_name_const_str == g_objc_type_name_id)
5957 {
5958 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005959 GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
Sean Callanan82587052013-01-03 00:05:56 +00005960 die->GetOffset(),
5961 DW_TAG_value_to_name(die->Tag()),
5962 die->GetName(this, dwarf_cu));
Greg Clayton57ee3062013-07-11 22:46:58 +00005963 clang_type = ast.GetBasicType(eBasicTypeObjCID);
Sean Callanan82587052013-01-03 00:05:56 +00005964 encoding_data_type = Type::eEncodingIsUID;
5965 encoding_uid = LLDB_INVALID_UID;
5966 resolve_state = Type::eResolveStateFull;
Greg Clayton526e5af2010-11-13 03:52:47 +00005967
Sean Callanan82587052013-01-03 00:05:56 +00005968 }
5969 else if (type_name_const_str == g_objc_type_name_Class)
5970 {
5971 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005972 GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
Sean Callanan82587052013-01-03 00:05:56 +00005973 die->GetOffset(),
5974 DW_TAG_value_to_name(die->Tag()),
5975 die->GetName(this, dwarf_cu));
Greg Clayton57ee3062013-07-11 22:46:58 +00005976 clang_type = ast.GetBasicType(eBasicTypeObjCClass);
Sean Callanan82587052013-01-03 00:05:56 +00005977 encoding_data_type = Type::eEncodingIsUID;
5978 encoding_uid = LLDB_INVALID_UID;
5979 resolve_state = Type::eResolveStateFull;
5980 }
5981 else if (type_name_const_str == g_objc_type_name_selector)
5982 {
5983 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005984 GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
Sean Callanan82587052013-01-03 00:05:56 +00005985 die->GetOffset(),
5986 DW_TAG_value_to_name(die->Tag()),
5987 die->GetName(this, dwarf_cu));
Greg Clayton57ee3062013-07-11 22:46:58 +00005988 clang_type = ast.GetBasicType(eBasicTypeObjCSel);
Sean Callanan82587052013-01-03 00:05:56 +00005989 encoding_data_type = Type::eEncodingIsUID;
5990 encoding_uid = LLDB_INVALID_UID;
5991 resolve_state = Type::eResolveStateFull;
5992 }
Greg Claytonc7f03b62012-01-12 04:33:28 +00005993 }
Sean Callanan82587052013-01-03 00:05:56 +00005994 else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
Greg Claytonc7f03b62012-01-12 04:33:28 +00005995 {
Sean Callanan82587052013-01-03 00:05:56 +00005996 // Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id".
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005997
Sean Callanan82587052013-01-03 00:05:56 +00005998 DWARFDebugInfoEntry* encoding_die = dwarf_cu->GetDIEPtr(encoding_uid);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005999
Sean Callanan82587052013-01-03 00:05:56 +00006000 if (encoding_die && encoding_die->Tag() == DW_TAG_structure_type)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006001 {
Sean Callanan82587052013-01-03 00:05:56 +00006002 if (const char *struct_name = encoding_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL))
6003 {
6004 if (!strcmp(struct_name, "objc_object"))
6005 {
6006 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00006007 GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.",
Sean Callanan82587052013-01-03 00:05:56 +00006008 die->GetOffset(),
6009 DW_TAG_value_to_name(die->Tag()),
6010 die->GetName(this, dwarf_cu));
Greg Clayton57ee3062013-07-11 22:46:58 +00006011 clang_type = ast.GetBasicType(eBasicTypeObjCID);
Sean Callanan82587052013-01-03 00:05:56 +00006012 encoding_data_type = Type::eEncodingIsUID;
6013 encoding_uid = LLDB_INVALID_UID;
6014 resolve_state = Type::eResolveStateFull;
6015 }
6016 }
6017 }
Greg Claytonc7f03b62012-01-12 04:33:28 +00006018 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00006019 }
6020 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006021
Greg Clayton81c22f62011-10-19 18:09:39 +00006022 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006023 this,
6024 type_name_const_str,
6025 byte_size,
6026 NULL,
6027 encoding_uid,
6028 encoding_data_type,
6029 &decl,
6030 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00006031 resolve_state));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006032
Greg Clayton594e5ed2010-09-27 21:07:38 +00006033 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006034
6035// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
6036// if (encoding_type != NULL)
6037// {
6038// if (encoding_type != DIE_IS_BEING_PARSED)
6039// type_sp->SetEncodingType(encoding_type);
6040// else
6041// m_indirect_fixups.push_back(type_sp.get());
6042// }
6043 }
6044 break;
6045
6046 case DW_TAG_structure_type:
6047 case DW_TAG_union_type:
6048 case DW_TAG_class_type:
6049 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006050 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00006051 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Greg Clayton23f59502012-07-17 03:23:13 +00006052 bool byte_size_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006053
Greg Clayton9e409562010-07-28 02:04:09 +00006054 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton18774842011-11-29 23:40:34 +00006055 bool is_complete_objc_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006056 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00006057 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006058 if (num_attributes > 0)
6059 {
6060 uint32_t i;
6061 for (i=0; i<num_attributes; ++i)
6062 {
6063 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006064 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
6065 {
6066 switch (attr)
6067 {
Greg Clayton9e409562010-07-28 02:04:09 +00006068 case DW_AT_decl_file:
Greg Claytonc7f03b62012-01-12 04:33:28 +00006069 if (dwarf_cu->DW_AT_decl_file_attributes_are_invalid())
Ed Maste4c24b122013-10-17 20:13:14 +00006070 {
6071 // llvm-gcc outputs invalid DW_AT_decl_file attributes that always
6072 // point to the compile unit file, so we clear this invalid value
6073 // so that we can still unique types efficiently.
Greg Claytonc7f03b62012-01-12 04:33:28 +00006074 decl.SetFile(FileSpec ("<invalid>", false));
Ed Maste4c24b122013-10-17 20:13:14 +00006075 }
Greg Claytonc7f03b62012-01-12 04:33:28 +00006076 else
6077 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
Greg Clayton9e409562010-07-28 02:04:09 +00006078 break;
6079
6080 case DW_AT_decl_line:
6081 decl.SetLine(form_value.Unsigned());
6082 break;
6083
6084 case DW_AT_decl_column:
6085 decl.SetColumn(form_value.Unsigned());
6086 break;
6087
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006088 case DW_AT_name:
6089 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00006090 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006091 break;
Greg Clayton9e409562010-07-28 02:04:09 +00006092
6093 case DW_AT_byte_size:
6094 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00006095 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00006096 break;
6097
6098 case DW_AT_accessibility:
6099 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
6100 break;
6101
6102 case DW_AT_declaration:
Greg Clayton1c8ef472013-04-05 23:27:21 +00006103 is_forward_declaration = form_value.Boolean();
Greg Clayton9e409562010-07-28 02:04:09 +00006104 break;
6105
6106 case DW_AT_APPLE_runtime_class:
6107 class_language = (LanguageType)form_value.Signed();
6108 break;
6109
Greg Clayton18774842011-11-29 23:40:34 +00006110 case DW_AT_APPLE_objc_complete_type:
6111 is_complete_objc_class = form_value.Signed();
6112 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006113
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006114 case DW_AT_allocated:
6115 case DW_AT_associated:
6116 case DW_AT_data_location:
6117 case DW_AT_description:
6118 case DW_AT_start_scope:
6119 case DW_AT_visibility:
6120 default:
6121 case DW_AT_sibling:
6122 break;
6123 }
6124 }
6125 }
6126 }
Greg Claytond20deac2014-04-04 18:15:18 +00006127
6128 // UniqueDWARFASTType is large, so don't create a local variables on the
6129 // stack, put it on the heap. This function is often called recursively
6130 // and clang isn't good and sharing the stack space for variables in different blocks.
6131 std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());
Sean Callanan8e8072d2012-02-07 21:13:38 +00006132
Greg Clayton123edca2012-03-02 00:07:15 +00006133 // Only try and unique the type if it has a name.
6134 if (type_name_const_str &&
6135 GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Sean Callanan8e8072d2012-02-07 21:13:38 +00006136 this,
6137 dwarf_cu,
6138 die,
6139 decl,
6140 byte_size_valid ? byte_size : -1,
Greg Claytond20deac2014-04-04 18:15:18 +00006141 *unique_ast_entry_ap))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006142 {
Sean Callanan8e8072d2012-02-07 21:13:38 +00006143 // We have already parsed this type or from another
6144 // compile unit. GCC loves to use the "one definition
6145 // rule" which can result in multiple definitions
6146 // of the same class over and over in each compile
6147 // unit.
Greg Claytond20deac2014-04-04 18:15:18 +00006148 type_sp = unique_ast_entry_ap->m_type_sp;
Sean Callanan8e8072d2012-02-07 21:13:38 +00006149 if (type_sp)
Greg Claytonc615ce42010-11-09 04:42:43 +00006150 {
Sean Callanan8e8072d2012-02-07 21:13:38 +00006151 m_die_to_type[die] = type_sp.get();
6152 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00006153 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006154 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006155
Daniel Malead01b2952012-11-29 21:49:15 +00006156 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006157
6158 int tag_decl_kind = -1;
6159 AccessType default_accessibility = eAccessNone;
6160 if (tag == DW_TAG_structure_type)
6161 {
6162 tag_decl_kind = clang::TTK_Struct;
6163 default_accessibility = eAccessPublic;
6164 }
6165 else if (tag == DW_TAG_union_type)
6166 {
6167 tag_decl_kind = clang::TTK_Union;
6168 default_accessibility = eAccessPublic;
6169 }
6170 else if (tag == DW_TAG_class_type)
6171 {
6172 tag_decl_kind = clang::TTK_Class;
6173 default_accessibility = eAccessPrivate;
6174 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006175
Greg Clayton3a5f29a2011-11-30 02:48:28 +00006176 if (byte_size_valid && byte_size == 0 && type_name_cstr &&
6177 die->HasChildren() == false &&
6178 sc.comp_unit->GetLanguage() == eLanguageTypeObjC)
6179 {
6180 // Work around an issue with clang at the moment where
6181 // forward declarations for objective C classes are emitted
6182 // as:
6183 // DW_TAG_structure_type [2]
6184 // DW_AT_name( "ForwardObjcClass" )
6185 // DW_AT_byte_size( 0x00 )
6186 // DW_AT_decl_file( "..." )
6187 // DW_AT_decl_line( 1 )
6188 //
6189 // Note that there is no DW_AT_declaration and there are
6190 // no children, and the byte size is zero.
6191 is_forward_declaration = true;
6192 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006193
Sean Callanan7457f8d2012-04-25 01:03:57 +00006194 if (class_language == eLanguageTypeObjC ||
6195 class_language == eLanguageTypeObjC_plus_plus)
Greg Clayton18774842011-11-29 23:40:34 +00006196 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00006197 if (!is_complete_objc_class && Supports_DW_AT_APPLE_objc_complete_type(dwarf_cu))
Greg Clayton901c5ca2011-12-03 04:40:03 +00006198 {
6199 // We have a valid eSymbolTypeObjCClass class symbol whose
6200 // name matches the current objective C class that we
6201 // are trying to find and this DIE isn't the complete
6202 // definition (we checked is_complete_objc_class above and
6203 // know it is false), so the real definition is in here somewhere
Greg Claytonc7f03b62012-01-12 04:33:28 +00006204 type_sp = FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006205
Greg Clayton1f746072012-08-29 21:13:06 +00006206 if (!type_sp && GetDebugMapSymfile ())
Greg Clayton901c5ca2011-12-03 04:40:03 +00006207 {
6208 // We weren't able to find a full declaration in
6209 // this DWARF, see if we have a declaration anywhere
6210 // else...
Greg Claytonc7f03b62012-01-12 04:33:28 +00006211 type_sp = m_debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
Greg Clayton901c5ca2011-12-03 04:40:03 +00006212 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006213
Greg Clayton901c5ca2011-12-03 04:40:03 +00006214 if (type_sp)
6215 {
6216 if (log)
6217 {
Greg Clayton5160ce52013-03-27 23:08:40 +00006218 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00006219 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8" PRIx64,
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006220 static_cast<void*>(this),
Greg Claytone38a5ed2012-01-05 03:57:59 +00006221 die->GetOffset(),
6222 DW_TAG_value_to_name(tag),
6223 type_name_cstr,
6224 type_sp->GetID());
Greg Clayton901c5ca2011-12-03 04:40:03 +00006225 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006226
Greg Clayton901c5ca2011-12-03 04:40:03 +00006227 // We found a real definition for this type elsewhere
6228 // so lets use it and cache the fact that we found
6229 // a complete type for this die
6230 m_die_to_type[die] = type_sp.get();
6231 return type_sp;
6232 }
6233 }
6234 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006235
Greg Clayton901c5ca2011-12-03 04:40:03 +00006236
6237 if (is_forward_declaration)
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006238 {
6239 // We have a forward declaration to a type and we need
6240 // to try and find a full declaration. We look in the
6241 // current type index just in case we have a forward
6242 // declaration followed by an actual declarations in the
6243 // DWARF. If this fails, we need to look elsewhere...
Greg Claytonc982b3d2011-11-28 01:45:00 +00006244 if (log)
6245 {
Greg Clayton5160ce52013-03-27 23:08:40 +00006246 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00006247 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006248 static_cast<void*>(this),
Greg Claytone38a5ed2012-01-05 03:57:59 +00006249 die->GetOffset(),
6250 DW_TAG_value_to_name(tag),
6251 type_name_cstr);
Greg Claytonc982b3d2011-11-28 01:45:00 +00006252 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006253
Greg Claytona8022fa2012-04-24 21:22:41 +00006254 DWARFDeclContext die_decl_ctx;
6255 die->GetDWARFDeclContext(this, dwarf_cu, die_decl_ctx);
6256
6257 //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
6258 type_sp = FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006259
Greg Clayton1f746072012-08-29 21:13:06 +00006260 if (!type_sp && GetDebugMapSymfile ())
Greg Clayton4272cc72011-02-02 02:24:04 +00006261 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006262 // We weren't able to find a full declaration in
6263 // this DWARF, see if we have a declaration anywhere
6264 // else...
Greg Claytona8022fa2012-04-24 21:22:41 +00006265 type_sp = m_debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
Greg Clayton4272cc72011-02-02 02:24:04 +00006266 }
6267
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006268 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00006269 {
Greg Claytonc982b3d2011-11-28 01:45:00 +00006270 if (log)
6271 {
Greg Clayton5160ce52013-03-27 23:08:40 +00006272 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00006273 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006274 static_cast<void*>(this),
Greg Claytone38a5ed2012-01-05 03:57:59 +00006275 die->GetOffset(),
6276 DW_TAG_value_to_name(tag),
6277 type_name_cstr,
6278 type_sp->GetID());
Greg Claytonc982b3d2011-11-28 01:45:00 +00006279 }
6280
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006281 // We found a real definition for this type elsewhere
6282 // so lets use it and cache the fact that we found
6283 // a complete type for this die
6284 m_die_to_type[die] = type_sp.get();
6285 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00006286 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006287 }
6288 assert (tag_decl_kind != -1);
6289 bool clang_type_was_created = false;
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006290 clang_type.SetClangType(ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
Greg Clayton57ee3062013-07-11 22:46:58 +00006291 if (!clang_type)
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006292 {
Sean Callanan4d04c6a2012-02-09 22:54:11 +00006293 const DWARFDebugInfoEntry *decl_ctx_die;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006294
Sean Callanan4d04c6a2012-02-09 22:54:11 +00006295 clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
Greg Clayton55561e92011-10-26 03:31:36 +00006296 if (accessibility == eAccessNone && decl_ctx)
6297 {
6298 // Check the decl context that contains this class/struct/union.
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00006299 // If it is a class we must give it an accessibility.
Greg Clayton55561e92011-10-26 03:31:36 +00006300 const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
6301 if (DeclKindIsCXXClass (containing_decl_kind))
6302 accessibility = default_accessibility;
6303 }
6304
Greg Claytonc4ffd662013-03-08 01:37:30 +00006305 ClangASTMetadata metadata;
6306 metadata.SetUserID(MakeUserID(die->GetOffset()));
6307 metadata.SetIsDynamicCXXType(ClassOrStructIsVirtual (dwarf_cu, die));
6308
Greg Claytonf0705c82011-10-22 03:33:13 +00006309 if (type_name_cstr && strchr (type_name_cstr, '<'))
6310 {
6311 ClangASTContext::TemplateParameterInfos template_param_infos;
6312 if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos))
6313 {
6314 clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00006315 accessibility,
Greg Claytonf0705c82011-10-22 03:33:13 +00006316 type_name_cstr,
6317 tag_decl_kind,
6318 template_param_infos);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006319
Greg Claytonf0705c82011-10-22 03:33:13 +00006320 clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx,
6321 class_template_decl,
6322 tag_decl_kind,
6323 template_param_infos);
6324 clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
6325 clang_type_was_created = true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006326
Greg Claytond0029442013-03-27 01:48:02 +00006327 GetClangASTContext().SetMetadata (class_template_decl, metadata);
6328 GetClangASTContext().SetMetadata (class_specialization_decl, metadata);
Greg Claytonf0705c82011-10-22 03:33:13 +00006329 }
6330 }
6331
6332 if (!clang_type_was_created)
6333 {
6334 clang_type_was_created = true;
Greg Clayton55561e92011-10-26 03:31:36 +00006335 clang_type = ast.CreateRecordType (decl_ctx,
6336 accessibility,
6337 type_name_cstr,
Greg Claytonf0705c82011-10-22 03:33:13 +00006338 tag_decl_kind,
Sean Callanan60217122012-04-13 00:10:03 +00006339 class_language,
Jim Ingham379397632012-10-27 02:54:13 +00006340 &metadata);
Greg Claytonf0705c82011-10-22 03:33:13 +00006341 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006342 }
6343
6344 // Store a forward declaration to this class type in case any
6345 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00006346 // types for function prototypes.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006347 LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
Greg Clayton81c22f62011-10-19 18:09:39 +00006348 type_sp.reset (new Type (MakeUserID(die->GetOffset()),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006349 this,
6350 type_name_const_str,
6351 byte_size,
6352 NULL,
6353 LLDB_INVALID_UID,
6354 Type::eEncodingIsUID,
6355 &decl,
6356 clang_type,
6357 Type::eResolveStateForward));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006358
Sean Callanan72772842012-02-22 23:57:45 +00006359 type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006360
6361
6362 // Add our type to the unique type map so we don't
6363 // end up creating many copies of the same type over
6364 // and over in the ASTContext for our module
Greg Claytond20deac2014-04-04 18:15:18 +00006365 unique_ast_entry_ap->m_type_sp = type_sp;
6366 unique_ast_entry_ap->m_symfile = this;
6367 unique_ast_entry_ap->m_cu = dwarf_cu;
6368 unique_ast_entry_ap->m_die = die;
6369 unique_ast_entry_ap->m_declaration = decl;
6370 unique_ast_entry_ap->m_byte_size = byte_size;
Greg Claytone576ab22011-02-15 00:19:15 +00006371 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
Greg Claytond20deac2014-04-04 18:15:18 +00006372 *unique_ast_entry_ap);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006373
Greg Clayton0ec71a02013-08-10 00:09:35 +00006374 if (is_forward_declaration && die->HasChildren())
6375 {
6376 // Check to see if the DIE actually has a definition, some version of GCC will
6377 // emit DIEs with DW_AT_declaration set to true, but yet still have subprogram,
6378 // members, or inheritance, so we can't trust it
6379 const DWARFDebugInfoEntry *child_die = die->GetFirstChild();
6380 while (child_die)
6381 {
6382 switch (child_die->Tag())
6383 {
6384 case DW_TAG_inheritance:
6385 case DW_TAG_subprogram:
6386 case DW_TAG_member:
6387 case DW_TAG_APPLE_property:
Greg Clayton4c484ec2014-02-07 19:21:56 +00006388 case DW_TAG_class_type:
6389 case DW_TAG_structure_type:
6390 case DW_TAG_enumeration_type:
6391 case DW_TAG_typedef:
6392 case DW_TAG_union_type:
Greg Clayton0ec71a02013-08-10 00:09:35 +00006393 child_die = NULL;
6394 is_forward_declaration = false;
6395 break;
6396 default:
6397 child_die = child_die->GetSibling();
6398 break;
6399 }
6400 }
6401 }
6402
Sean Callanan12014a02011-12-08 23:45:45 +00006403 if (!is_forward_declaration)
Greg Clayton219cf312012-03-30 00:51:13 +00006404 {
6405 // Always start the definition for a class type so that
6406 // if the class has child classes or types that require
6407 // the class to be created for use as their decl contexts
6408 // the class will be ready to accept these child definitions.
Sean Callanan12014a02011-12-08 23:45:45 +00006409 if (die->HasChildren() == false)
6410 {
6411 // No children for this struct/union/class, lets finish it
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006412 clang_type.StartTagDeclarationDefinition ();
6413 clang_type.CompleteTagDeclarationDefinition ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006414
Sean Callanan433cd222012-10-19 01:37:25 +00006415 if (tag == DW_TAG_structure_type) // this only applies in C
6416 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006417 clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006418
Greg Clayton57ee3062013-07-11 22:46:58 +00006419 if (record_decl)
Greg Claytond20deac2014-04-04 18:15:18 +00006420 m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
Sean Callanan433cd222012-10-19 01:37:25 +00006421 }
Sean Callanan12014a02011-12-08 23:45:45 +00006422 }
6423 else if (clang_type_was_created)
6424 {
Greg Clayton219cf312012-03-30 00:51:13 +00006425 // Start the definition if the class is not objective C since
6426 // the underlying decls respond to isCompleteDefinition(). Objective
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +00006427 // C decls don't respond to isCompleteDefinition() so we can't
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00006428 // start the declaration definition right away. For C++ class/union/structs
Greg Clayton219cf312012-03-30 00:51:13 +00006429 // we want to start the definition in case the class is needed as the
6430 // declaration context for a contained class or type without the need
6431 // to complete that type..
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006432
Sean Callanan7457f8d2012-04-25 01:03:57 +00006433 if (class_language != eLanguageTypeObjC &&
6434 class_language != eLanguageTypeObjC_plus_plus)
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006435 clang_type.StartTagDeclarationDefinition ();
Greg Clayton219cf312012-03-30 00:51:13 +00006436
Sean Callanan12014a02011-12-08 23:45:45 +00006437 // Leave this as a forward declaration until we need
6438 // to know the details of the type. lldb_private::Type
6439 // will automatically call the SymbolFile virtual function
6440 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
6441 // When the definition needs to be defined.
Greg Clayton57ee3062013-07-11 22:46:58 +00006442 m_forward_decl_die_to_clang_type[die] = clang_type.GetOpaqueQualType();
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006443 m_forward_decl_clang_type_to_die[clang_type.RemoveFastQualifiers().GetOpaqueQualType()] = die;
6444 clang_type.SetHasExternalStorage (true);
Sean Callanan12014a02011-12-08 23:45:45 +00006445 }
Greg Claytonc615ce42010-11-09 04:42:43 +00006446 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006447
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006448 }
6449 break;
6450
6451 case DW_TAG_enumeration_type:
6452 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006453 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00006454 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006455
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006456 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006457
Greg Claytond88d7592010-09-15 08:33:30 +00006458 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006459 if (num_attributes > 0)
6460 {
6461 uint32_t i;
6462
6463 for (i=0; i<num_attributes; ++i)
6464 {
6465 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006466 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
6467 {
6468 switch (attr)
6469 {
Greg Clayton7a345282010-11-09 23:46:37 +00006470 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
6471 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
6472 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006473 case DW_AT_name:
6474 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00006475 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006476 break;
Greg Clayton54166af2014-11-22 01:58:59 +00006477 case DW_AT_type: encoding_uid = form_value.Reference(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00006478 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
6479 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00006480 case DW_AT_declaration: break; //is_forward_declaration = form_value.Boolean(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006481 case DW_AT_allocated:
6482 case DW_AT_associated:
6483 case DW_AT_bit_stride:
6484 case DW_AT_byte_stride:
6485 case DW_AT_data_location:
6486 case DW_AT_description:
6487 case DW_AT_start_scope:
6488 case DW_AT_visibility:
6489 case DW_AT_specification:
6490 case DW_AT_abstract_origin:
6491 case DW_AT_sibling:
6492 break;
6493 }
6494 }
6495 }
6496
Daniel Malead01b2952012-11-29 21:49:15 +00006497 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00006498
Greg Clayton57ee3062013-07-11 22:46:58 +00006499 ClangASTType enumerator_clang_type;
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006500 clang_type.SetClangType (ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
Greg Clayton57ee3062013-07-11 22:46:58 +00006501 if (!clang_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00006502 {
Greg Clayton5d14fc02013-03-06 06:23:54 +00006503 if (encoding_uid != DW_INVALID_OFFSET)
6504 {
6505 Type *enumerator_type = ResolveTypeUID(encoding_uid);
6506 if (enumerator_type)
6507 enumerator_clang_type = enumerator_type->GetClangFullType();
6508 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006509
Greg Clayton57ee3062013-07-11 22:46:58 +00006510 if (!enumerator_clang_type)
Greg Clayton5d14fc02013-03-06 06:23:54 +00006511 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
6512 DW_ATE_signed,
6513 byte_size * 8);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006514
Greg Claytonca512b32011-01-14 04:54:56 +00006515 clang_type = ast.CreateEnumerationType (type_name_cstr,
Greg Claytoncb5860a2011-10-13 23:49:28 +00006516 GetClangDeclContextContainingDIE (dwarf_cu, die, NULL),
Greg Claytonca512b32011-01-14 04:54:56 +00006517 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006518 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00006519 }
6520 else
6521 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006522 enumerator_clang_type = clang_type.GetEnumerationIntegerType ();
Greg Clayton1be10fc2010-09-29 01:12:09 +00006523 }
6524
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006525 LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006526
Greg Clayton81c22f62011-10-19 18:09:39 +00006527 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006528 this,
6529 type_name_const_str,
6530 byte_size,
6531 NULL,
6532 encoding_uid,
6533 Type::eEncodingIsUID,
6534 &decl,
6535 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00006536 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006537
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006538 clang_type.StartTagDeclarationDefinition ();
Greg Clayton6beaaa62011-01-17 03:46:26 +00006539 if (die->HasChildren())
6540 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00006541 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
Greg Clayton3e067532013-03-05 23:54:39 +00006542 bool is_signed = false;
Greg Clayton57ee3062013-07-11 22:46:58 +00006543 enumerator_clang_type.IsIntegerType(is_signed);
Greg Clayton3e067532013-03-05 23:54:39 +00006544 ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00006545 }
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006546 clang_type.CompleteTagDeclarationDefinition ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006547 }
6548 }
6549 break;
6550
Jim Inghamb0be4422010-08-12 01:20:14 +00006551 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006552 case DW_TAG_subprogram:
6553 case DW_TAG_subroutine_type:
6554 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006555 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00006556 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006557
Greg Clayton23f59502012-07-17 03:23:13 +00006558 //const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006559 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00006560 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006561 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00006562 bool is_static = false;
6563 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00006564 bool is_explicit = false;
Sean Callanandbb58392011-11-02 01:38:59 +00006565 bool is_artificial = false;
Greg Clayton72da3972011-08-16 18:40:23 +00006566 dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
6567 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
Jim Ingham379397632012-10-27 02:54:13 +00006568 dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
Greg Clayton0fffff52010-09-24 05:15:53 +00006569
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006570 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00006571 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006572
6573
Greg Claytond88d7592010-09-15 08:33:30 +00006574 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006575 if (num_attributes > 0)
6576 {
6577 uint32_t i;
6578 for (i=0; i<num_attributes; ++i)
6579 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00006580 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006581 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
6582 {
6583 switch (attr)
6584 {
6585 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
6586 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
6587 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
6588 case DW_AT_name:
6589 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00006590 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006591 break;
6592
Greg Clayton71415542012-12-08 00:24:40 +00006593 case DW_AT_linkage_name:
Greg Clayton23f59502012-07-17 03:23:13 +00006594 case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00006595 case DW_AT_type: type_die_offset = form_value.Reference(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00006596 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00006597 case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
6598 case DW_AT_inline: is_inline = form_value.Boolean(); break;
6599 case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
6600 case DW_AT_explicit: is_explicit = form_value.Boolean(); break;
6601 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006602
Greg Claytonf51de672010-10-01 02:31:07 +00006603
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006604 case DW_AT_external:
6605 if (form_value.Unsigned())
6606 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00006607 if (storage == clang::SC_None)
6608 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006609 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00006610 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006611 }
6612 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006613
Greg Clayton72da3972011-08-16 18:40:23 +00006614 case DW_AT_specification:
Greg Clayton54166af2014-11-22 01:58:59 +00006615 specification_die_offset = form_value.Reference();
Greg Clayton72da3972011-08-16 18:40:23 +00006616 break;
6617
6618 case DW_AT_abstract_origin:
Greg Clayton54166af2014-11-22 01:58:59 +00006619 abstract_origin_die_offset = form_value.Reference();
Greg Clayton72da3972011-08-16 18:40:23 +00006620 break;
6621
Jim Ingham379397632012-10-27 02:54:13 +00006622 case DW_AT_object_pointer:
Greg Clayton54166af2014-11-22 01:58:59 +00006623 object_pointer_die_offset = form_value.Reference();
Jim Ingham379397632012-10-27 02:54:13 +00006624 break;
6625
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006626 case DW_AT_allocated:
6627 case DW_AT_associated:
6628 case DW_AT_address_class:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006629 case DW_AT_calling_convention:
6630 case DW_AT_data_location:
6631 case DW_AT_elemental:
6632 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006633 case DW_AT_frame_base:
6634 case DW_AT_high_pc:
6635 case DW_AT_low_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006636 case DW_AT_prototyped:
6637 case DW_AT_pure:
6638 case DW_AT_ranges:
6639 case DW_AT_recursive:
6640 case DW_AT_return_addr:
6641 case DW_AT_segment:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006642 case DW_AT_start_scope:
6643 case DW_AT_static_link:
6644 case DW_AT_trampoline:
6645 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006646 case DW_AT_vtable_elem_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006647 case DW_AT_description:
6648 case DW_AT_sibling:
6649 break;
6650 }
6651 }
6652 }
Greg Clayton24739922010-10-13 03:15:28 +00006653 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006654
Jim Ingham379397632012-10-27 02:54:13 +00006655 std::string object_pointer_name;
6656 if (object_pointer_die_offset != DW_INVALID_OFFSET)
6657 {
6658 // Get the name from the object pointer die
6659 StreamString s;
6660 if (DWARFDebugInfoEntry::GetName (this, dwarf_cu, object_pointer_die_offset, s))
6661 {
6662 object_pointer_name.assign(s.GetData());
6663 }
6664 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006665
Daniel Malead01b2952012-11-29 21:49:15 +00006666 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00006667
Greg Clayton57ee3062013-07-11 22:46:58 +00006668 ClangASTType return_clang_type;
Greg Clayton24739922010-10-13 03:15:28 +00006669 Type *func_type = NULL;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006670
Greg Clayton24739922010-10-13 03:15:28 +00006671 if (type_die_offset != DW_INVALID_OFFSET)
6672 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00006673
Greg Clayton24739922010-10-13 03:15:28 +00006674 if (func_type)
Greg Clayton42ce2f32011-12-12 21:50:19 +00006675 return_clang_type = func_type->GetClangForwardType();
Greg Clayton24739922010-10-13 03:15:28 +00006676 else
Greg Clayton57ee3062013-07-11 22:46:58 +00006677 return_clang_type = ast.GetBasicType(eBasicTypeVoid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006678
Greg Claytonf51de672010-10-01 02:31:07 +00006679
Greg Clayton57ee3062013-07-11 22:46:58 +00006680 std::vector<ClangASTType> function_param_types;
Greg Clayton24739922010-10-13 03:15:28 +00006681 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006682
Greg Clayton24739922010-10-13 03:15:28 +00006683 // Parse the function children for the parameters
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006684
Greg Claytoncb5860a2011-10-13 23:49:28 +00006685 const DWARFDebugInfoEntry *decl_ctx_die = NULL;
6686 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
Greg Clayton5113dc82011-08-12 06:47:54 +00006687 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
6688
Greg Claytonf0705c82011-10-22 03:33:13 +00006689 const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
Greg Clayton5113dc82011-08-12 06:47:54 +00006690 // Start off static. This will be set to false in ParseChildParameters(...)
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00006691 // if we find a "this" parameters as the first parameter
Greg Clayton5113dc82011-08-12 06:47:54 +00006692 if (is_cxx_method)
Sean Callanan763d72a2011-08-02 22:21:50 +00006693 is_static = true;
Greg Claytond20deac2014-04-04 18:15:18 +00006694
Greg Clayton24739922010-10-13 03:15:28 +00006695 if (die->HasChildren())
6696 {
Greg Clayton0fffff52010-09-24 05:15:53 +00006697 bool skip_artificial = true;
Jim Ingham379397632012-10-27 02:54:13 +00006698 ParseChildParameters (sc,
Greg Clayton5113dc82011-08-12 06:47:54 +00006699 containing_decl_ctx,
Jim Ingham379397632012-10-27 02:54:13 +00006700 dwarf_cu,
6701 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00006702 skip_artificial,
6703 is_static,
Greg Clayton03969752014-02-24 18:53:11 +00006704 is_variadic,
Jim Ingham379397632012-10-27 02:54:13 +00006705 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00006706 function_param_decls,
Greg Claytond20deac2014-04-04 18:15:18 +00006707 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00006708 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006709
Greg Clayton24739922010-10-13 03:15:28 +00006710 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006711 clang_type = ast.CreateFunctionType (return_clang_type,
Greg Clayton9cb25c42012-10-30 17:02:18 +00006712 function_param_types.data(),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006713 function_param_types.size(),
6714 is_variadic,
6715 type_quals);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006716
Sean Callanande9ce872013-05-09 23:13:13 +00006717 bool ignore_containing_context = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006718
Greg Clayton24739922010-10-13 03:15:28 +00006719 if (type_name_cstr)
6720 {
6721 bool type_handled = false;
Greg Clayton24739922010-10-13 03:15:28 +00006722 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006723 {
Greg Clayton1b3815c2013-01-30 00:18:29 +00006724 ObjCLanguageRuntime::MethodName objc_method (type_name_cstr, true);
6725 if (objc_method.IsValid(true))
Greg Clayton0fffff52010-09-24 05:15:53 +00006726 {
Greg Clayton57ee3062013-07-11 22:46:58 +00006727 ClangASTType class_opaque_type;
Greg Clayton1b3815c2013-01-30 00:18:29 +00006728 ConstString class_name(objc_method.GetClassName());
Greg Clayton7c810422012-01-18 23:40:49 +00006729 if (class_name)
Greg Clayton0fffff52010-09-24 05:15:53 +00006730 {
Greg Clayton278a16b2012-01-19 00:52:59 +00006731 TypeSP complete_objc_class_type_sp (FindCompleteObjCDefinitionTypeForDIE (NULL, class_name, false));
Greg Claytonc7f03b62012-01-12 04:33:28 +00006732
6733 if (complete_objc_class_type_sp)
Greg Clayton0fffff52010-09-24 05:15:53 +00006734 {
Greg Clayton57ee3062013-07-11 22:46:58 +00006735 ClangASTType type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006736 if (type_clang_forward_type.IsObjCObjectOrInterfaceType ())
Greg Claytonc7f03b62012-01-12 04:33:28 +00006737 class_opaque_type = type_clang_forward_type;
Greg Clayton0fffff52010-09-24 05:15:53 +00006738 }
Greg Clayton24739922010-10-13 03:15:28 +00006739 }
Greg Clayton0fffff52010-09-24 05:15:53 +00006740
Greg Clayton24739922010-10-13 03:15:28 +00006741 if (class_opaque_type)
6742 {
6743 // If accessibility isn't set to anything valid, assume public for
6744 // now...
6745 if (accessibility == eAccessNone)
6746 accessibility = eAccessPublic;
6747
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006748 clang::ObjCMethodDecl *objc_method_decl = class_opaque_type.AddMethodToObjCObjectType (type_name_cstr,
6749 clang_type,
6750 accessibility,
6751 is_artificial);
Greg Clayton24739922010-10-13 03:15:28 +00006752 type_handled = objc_method_decl != NULL;
Sean Callanan464a5b52012-10-04 22:06:29 +00006753 if (type_handled)
6754 {
6755 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Claytond0029442013-03-27 01:48:02 +00006756 GetClangASTContext().SetMetadataAsUserID (objc_method_decl, MakeUserID(die->GetOffset()));
Sean Callanan464a5b52012-10-04 22:06:29 +00006757 }
Sean Callananc3a1d562013-02-06 23:21:59 +00006758 else
6759 {
Jason Molendac1a65832013-03-07 22:44:42 +00006760 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",
Sean Callananc3a1d562013-02-06 23:21:59 +00006761 die->GetOffset(),
6762 tag,
6763 DW_TAG_value_to_name(tag));
6764 }
Greg Clayton24739922010-10-13 03:15:28 +00006765 }
6766 }
Greg Clayton5113dc82011-08-12 06:47:54 +00006767 else if (is_cxx_method)
Greg Clayton24739922010-10-13 03:15:28 +00006768 {
6769 // Look at the parent of this DIE and see if is is
6770 // a class or struct and see if this is actually a
6771 // C++ method
Greg Claytoncb5860a2011-10-13 23:49:28 +00006772 Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
Greg Clayton24739922010-10-13 03:15:28 +00006773 if (class_type)
6774 {
Greg Clayton4116e932012-05-15 02:33:01 +00006775 if (class_type->GetID() != MakeUserID(decl_ctx_die->GetOffset()))
6776 {
6777 // We uniqued the parent class of this function to another class
6778 // so we now need to associate all dies under "decl_ctx_die" to
6779 // DIEs in the DIE for "class_type"...
Greg Clayton5d650c6a2013-02-26 01:31:37 +00006780 SymbolFileDWARF *class_symfile = NULL;
Greg Clayton4116e932012-05-15 02:33:01 +00006781 DWARFCompileUnitSP class_type_cu_sp;
Greg Clayton5d650c6a2013-02-26 01:31:37 +00006782 const DWARFDebugInfoEntry *class_type_die = NULL;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006783
Sean Callanan2367f8a2013-02-26 01:12:25 +00006784 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
6785 if (debug_map_symfile)
6786 {
6787 class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
6788 class_type_die = class_symfile->DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
6789 }
6790 else
6791 {
6792 class_symfile = this;
6793 class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
6794 }
Greg Clayton4116e932012-05-15 02:33:01 +00006795 if (class_type_die)
6796 {
Greg Claytond20deac2014-04-04 18:15:18 +00006797 DWARFDIECollection failures;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006798
Sean Callanan2367f8a2013-02-26 01:12:25 +00006799 CopyUniqueClassMethodTypes (class_symfile,
6800 class_type,
6801 class_type_cu_sp.get(),
6802 class_type_die,
6803 dwarf_cu,
6804 decl_ctx_die,
6805 failures);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006806
Sean Callanan2367f8a2013-02-26 01:12:25 +00006807 // FIXME do something with these failures that's smarter than
6808 // just dropping them on the ground. Unfortunately classes don't
6809 // like having stuff added to them after their definitions are
6810 // complete...
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006811
Sean Callanan2367f8a2013-02-26 01:12:25 +00006812 type_ptr = m_die_to_type[die];
6813 if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
Greg Clayton4116e932012-05-15 02:33:01 +00006814 {
Sean Callanan2367f8a2013-02-26 01:12:25 +00006815 type_sp = type_ptr->shared_from_this();
6816 break;
Greg Clayton4116e932012-05-15 02:33:01 +00006817 }
6818 }
6819 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006820
Greg Clayton72da3972011-08-16 18:40:23 +00006821 if (specification_die_offset != DW_INVALID_OFFSET)
Greg Clayton0fffff52010-09-24 05:15:53 +00006822 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00006823 // We have a specification which we are going to base our function
6824 // prototype off of, so we need this type to be completed so that the
6825 // m_die_to_decl_ctx for the method in the specification has a valid
6826 // clang decl context.
Greg Clayton8eb732e2011-12-13 04:34:06 +00006827 class_type->GetClangForwardType();
Greg Clayton72da3972011-08-16 18:40:23 +00006828 // If we have a specification, then the function type should have been
6829 // made with the specification and not with this die.
6830 DWARFCompileUnitSP spec_cu_sp;
6831 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
Eric Christopher6cc6e602012-03-25 19:37:33 +00006832 clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, spec_die);
Greg Clayton5cf58b92011-10-05 22:22:08 +00006833 if (spec_clang_decl_ctx)
6834 {
6835 LinkDeclContextToDIE(spec_clang_decl_ctx, die);
6836 }
6837 else
Jim Inghamc1663042011-09-29 22:12:35 +00006838 {
Daniel Malead01b2952012-11-29 21:49:15 +00006839 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x) has no decl\n",
Greg Claytone38a5ed2012-01-05 03:57:59 +00006840 MakeUserID(die->GetOffset()),
6841 specification_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00006842 }
Greg Clayton72da3972011-08-16 18:40:23 +00006843 type_handled = true;
6844 }
6845 else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
6846 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00006847 // We have a specification which we are going to base our function
6848 // prototype off of, so we need this type to be completed so that the
6849 // m_die_to_decl_ctx for the method in the abstract origin has a valid
6850 // clang decl context.
Greg Clayton8eb732e2011-12-13 04:34:06 +00006851 class_type->GetClangForwardType();
Greg Clayton5cf58b92011-10-05 22:22:08 +00006852
Greg Clayton72da3972011-08-16 18:40:23 +00006853 DWARFCompileUnitSP abs_cu_sp;
6854 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
Eric Christopher6cc6e602012-03-25 19:37:33 +00006855 clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, abs_die);
Greg Clayton5cf58b92011-10-05 22:22:08 +00006856 if (abs_clang_decl_ctx)
6857 {
6858 LinkDeclContextToDIE (abs_clang_decl_ctx, die);
6859 }
6860 else
Jim Inghamc1663042011-09-29 22:12:35 +00006861 {
Daniel Malead01b2952012-11-29 21:49:15 +00006862 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x) has no decl\n",
Greg Claytone38a5ed2012-01-05 03:57:59 +00006863 MakeUserID(die->GetOffset()),
6864 abstract_origin_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00006865 }
Greg Clayton72da3972011-08-16 18:40:23 +00006866 type_handled = true;
6867 }
6868 else
6869 {
Greg Clayton57ee3062013-07-11 22:46:58 +00006870 ClangASTType class_opaque_type = class_type->GetClangForwardType();
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006871 if (class_opaque_type.IsCXXClassType ())
Greg Clayton931180e2011-01-27 06:44:37 +00006872 {
Greg Clayton57ee3062013-07-11 22:46:58 +00006873 if (class_opaque_type.IsBeingDefined ())
Greg Clayton72da3972011-08-16 18:40:23 +00006874 {
Greg Clayton20568dd2011-10-13 23:13:20 +00006875 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
6876 // in the DWARF for C++ methods... Default to public for now...
6877 if (accessibility == eAccessNone)
6878 accessibility = eAccessPublic;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006879
Greg Clayton20568dd2011-10-13 23:13:20 +00006880 if (!is_static && !die->HasChildren())
6881 {
6882 // We have a C++ member function with no children (this pointer!)
6883 // and clang will get mad if we try and make a function that isn't
6884 // well formed in the DWARF, so we will just skip it...
6885 type_handled = true;
6886 }
6887 else
6888 {
6889 clang::CXXMethodDecl *cxx_method_decl;
6890 // REMOVE THE CRASH DESCRIPTION BELOW
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00006891 Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s",
Greg Clayton20568dd2011-10-13 23:13:20 +00006892 type_name_cstr,
6893 class_type->GetName().GetCString(),
Greg Clayton81c22f62011-10-19 18:09:39 +00006894 MakeUserID(die->GetOffset()),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00006895 m_obj_file->GetFileSpec().GetPath().c_str());
Greg Clayton20568dd2011-10-13 23:13:20 +00006896
Sean Callananc1b732d2011-11-01 18:07:13 +00006897 const bool is_attr_used = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006898
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006899 cxx_method_decl = class_opaque_type.AddMethodToCXXRecordType (type_name_cstr,
6900 clang_type,
6901 accessibility,
6902 is_virtual,
6903 is_static,
6904 is_inline,
6905 is_explicit,
6906 is_attr_used,
6907 is_artificial);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006908
Greg Clayton20568dd2011-10-13 23:13:20 +00006909 type_handled = cxx_method_decl != NULL;
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006910
6911 if (type_handled)
Jim Ingham379397632012-10-27 02:54:13 +00006912 {
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006913 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
6914
6915 Host::SetCrashDescription (NULL);
6916
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006917
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006918 ClangASTMetadata metadata;
6919 metadata.SetUserID(MakeUserID(die->GetOffset()));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006920
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006921 if (!object_pointer_name.empty())
6922 {
6923 metadata.SetObjectPtrName(object_pointer_name.c_str());
6924 if (log)
Greg Claytond0029442013-03-27 01:48:02 +00006925 log->Printf ("Setting object pointer name: %s on method object %p.\n",
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006926 object_pointer_name.c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006927 static_cast<void*>(cxx_method_decl));
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006928 }
Greg Claytond0029442013-03-27 01:48:02 +00006929 GetClangASTContext().SetMetadata (cxx_method_decl, metadata);
Jim Ingham379397632012-10-27 02:54:13 +00006930 }
Sean Callananb0640dc2013-04-09 23:22:08 +00006931 else
6932 {
Sean Callanande9ce872013-05-09 23:13:13 +00006933 ignore_containing_context = true;
Sean Callananb0640dc2013-04-09 23:22:08 +00006934 }
Greg Clayton20568dd2011-10-13 23:13:20 +00006935 }
Greg Clayton72da3972011-08-16 18:40:23 +00006936 }
6937 else
6938 {
Greg Clayton20568dd2011-10-13 23:13:20 +00006939 // We were asked to parse the type for a method in a class, yet the
6940 // class hasn't been asked to complete itself through the
6941 // clang::ExternalASTSource protocol, so we need to just have the
6942 // class complete itself and do things the right way, then our
6943 // DIE should then have an entry in the m_die_to_type map. First
6944 // we need to modify the m_die_to_type so it doesn't think we are
6945 // trying to parse this DIE anymore...
6946 m_die_to_type[die] = NULL;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006947
Greg Clayton20568dd2011-10-13 23:13:20 +00006948 // Now we get the full type to force our class type to complete itself
6949 // using the clang::ExternalASTSource protocol which will parse all
6950 // base classes and all methods (including the method for this DIE).
6951 class_type->GetClangFullType();
Greg Clayton2c5f0e92011-08-04 21:02:57 +00006952
Greg Clayton20568dd2011-10-13 23:13:20 +00006953 // The type for this DIE should have been filled in the function call above
6954 type_ptr = m_die_to_type[die];
Greg Claytone5476db2012-06-01 20:32:35 +00006955 if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
Greg Clayton20568dd2011-10-13 23:13:20 +00006956 {
Greg Claytone1cd1be2012-01-29 20:56:30 +00006957 type_sp = type_ptr->shared_from_this();
Greg Clayton20568dd2011-10-13 23:13:20 +00006958 break;
6959 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006960
Sean Callanan02eee4d2012-04-12 23:10:00 +00006961 // FIXME This is fixing some even uglier behavior but we really need to
6962 // uniq the methods of each class as well as the class itself.
6963 // <rdar://problem/11240464>
6964 type_handled = true;
Greg Clayton72da3972011-08-16 18:40:23 +00006965 }
Greg Clayton931180e2011-01-27 06:44:37 +00006966 }
Greg Clayton0fffff52010-09-24 05:15:53 +00006967 }
6968 }
Greg Clayton0fffff52010-09-24 05:15:53 +00006969 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006970 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006971
Greg Clayton24739922010-10-13 03:15:28 +00006972 if (!type_handled)
6973 {
6974 // We just have a function that isn't part of a class
Sean Callanande9ce872013-05-09 23:13:13 +00006975 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (ignore_containing_context ? GetClangASTContext().GetTranslationUnitDecl() : containing_decl_ctx,
Greg Clayton147e1fa2011-10-14 22:47:18 +00006976 type_name_cstr,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006977 clang_type,
6978 storage,
6979 is_inline);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00006980
6981// if (template_param_infos.GetSize() > 0)
6982// {
6983// clang::FunctionTemplateDecl *func_template_decl = ast.CreateFunctionTemplateDecl (containing_decl_ctx,
6984// function_decl,
6985// type_name_cstr,
6986// template_param_infos);
6987//
6988// ast.CreateFunctionTemplateSpecializationInfo (function_decl,
6989// func_template_decl,
6990// template_param_infos);
6991// }
Greg Clayton24739922010-10-13 03:15:28 +00006992 // Add the decl to our DIE to decl context map
6993 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00006994 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00006995 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006996 ast.SetFunctionParameters (function_decl,
6997 &function_param_decls.front(),
6998 function_param_decls.size());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006999
Jim Ingham379397632012-10-27 02:54:13 +00007000 ClangASTMetadata metadata;
7001 metadata.SetUserID(MakeUserID(die->GetOffset()));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007002
Jim Ingham379397632012-10-27 02:54:13 +00007003 if (!object_pointer_name.empty())
7004 {
7005 metadata.SetObjectPtrName(object_pointer_name.c_str());
Jim Ingham2cffda3f2012-10-30 23:34:07 +00007006 if (log)
Greg Claytond0029442013-03-27 01:48:02 +00007007 log->Printf ("Setting object pointer name: %s on function object %p.",
Jim Ingham2cffda3f2012-10-30 23:34:07 +00007008 object_pointer_name.c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007009 static_cast<void*>(function_decl));
Jim Ingham379397632012-10-27 02:54:13 +00007010 }
Greg Claytond0029442013-03-27 01:48:02 +00007011 GetClangASTContext().SetMetadata (function_decl, metadata);
Greg Clayton24739922010-10-13 03:15:28 +00007012 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007013 }
Greg Clayton81c22f62011-10-19 18:09:39 +00007014 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00007015 this,
7016 type_name_const_str,
7017 0,
7018 NULL,
7019 LLDB_INVALID_UID,
7020 Type::eEncodingIsUID,
7021 &decl,
7022 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00007023 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00007024 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007025 }
7026 break;
7027
7028 case DW_TAG_array_type:
7029 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007030 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00007031 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007032
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007033 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007034 int64_t first_index = 0;
7035 uint32_t byte_stride = 0;
7036 uint32_t bit_stride = 0;
Greg Clayton1c8ef472013-04-05 23:27:21 +00007037 bool is_vector = false;
Greg Claytond88d7592010-09-15 08:33:30 +00007038 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007039
7040 if (num_attributes > 0)
7041 {
7042 uint32_t i;
7043 for (i=0; i<num_attributes; ++i)
7044 {
7045 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007046 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
7047 {
7048 switch (attr)
7049 {
7050 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
7051 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
7052 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
7053 case DW_AT_name:
7054 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00007055 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007056 break;
7057
Greg Clayton54166af2014-11-22 01:58:59 +00007058 case DW_AT_type: type_die_offset = form_value.Reference(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00007059 case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007060 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
7061 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00007062 case DW_AT_GNU_vector: is_vector = form_value.Boolean(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00007063 case DW_AT_accessibility: break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00007064 case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007065 case DW_AT_allocated:
7066 case DW_AT_associated:
7067 case DW_AT_data_location:
7068 case DW_AT_description:
7069 case DW_AT_ordering:
7070 case DW_AT_start_scope:
7071 case DW_AT_visibility:
7072 case DW_AT_specification:
7073 case DW_AT_abstract_origin:
7074 case DW_AT_sibling:
7075 break;
7076 }
7077 }
7078 }
7079
Daniel Malead01b2952012-11-29 21:49:15 +00007080 DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00007081
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007082 Type *element_type = ResolveTypeUID(type_die_offset);
7083
7084 if (element_type)
7085 {
7086 std::vector<uint64_t> element_orders;
7087 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
7088 if (byte_stride == 0 && bit_stride == 0)
7089 byte_stride = element_type->GetByteSize();
Greg Clayton57ee3062013-07-11 22:46:58 +00007090 ClangASTType array_element_type = element_type->GetClangForwardType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007091 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
Siva Chandra89ce9552015-01-05 23:06:14 +00007092 if (element_orders.size() > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007093 {
Siva Chandra89ce9552015-01-05 23:06:14 +00007094 uint64_t num_elements = 0;
7095 std::vector<uint64_t>::const_reverse_iterator pos;
7096 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
7097 for (pos = element_orders.rbegin(); pos != end; ++pos)
7098 {
7099 num_elements = *pos;
7100 clang_type = ast.CreateArrayType (array_element_type,
7101 num_elements,
7102 is_vector);
7103 array_element_type = clang_type;
7104 array_element_bit_stride = num_elements ?
7105 array_element_bit_stride * num_elements :
7106 array_element_bit_stride;
7107 }
7108 }
7109 else
7110 {
7111 clang_type = ast.CreateArrayType (array_element_type, 0, is_vector);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007112 }
7113 ConstString empty_name;
Greg Clayton81c22f62011-10-19 18:09:39 +00007114 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00007115 this,
7116 empty_name,
7117 array_element_bit_stride / 8,
7118 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00007119 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00007120 Type::eEncodingIsUID,
7121 &decl,
7122 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00007123 Type::eResolveStateFull));
7124 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007125 }
7126 }
7127 }
7128 break;
7129
Greg Clayton9b81a312010-06-12 01:20:30 +00007130 case DW_TAG_ptr_to_member_type:
7131 {
7132 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
7133 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
7134
Greg Claytond88d7592010-09-15 08:33:30 +00007135 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007136
Greg Clayton9b81a312010-06-12 01:20:30 +00007137 if (num_attributes > 0) {
7138 uint32_t i;
7139 for (i=0; i<num_attributes; ++i)
7140 {
7141 attr = attributes.AttributeAtIndex(i);
Greg Clayton9b81a312010-06-12 01:20:30 +00007142 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
7143 {
7144 switch (attr)
7145 {
7146 case DW_AT_type:
Greg Clayton54166af2014-11-22 01:58:59 +00007147 type_die_offset = form_value.Reference(); break;
Greg Clayton9b81a312010-06-12 01:20:30 +00007148 case DW_AT_containing_type:
Greg Clayton54166af2014-11-22 01:58:59 +00007149 containing_type_die_offset = form_value.Reference(); break;
Greg Clayton9b81a312010-06-12 01:20:30 +00007150 }
7151 }
7152 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007153
Greg Clayton9b81a312010-06-12 01:20:30 +00007154 Type *pointee_type = ResolveTypeUID(type_die_offset);
7155 Type *class_type = ResolveTypeUID(containing_type_die_offset);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007156
Greg Clayton57ee3062013-07-11 22:46:58 +00007157 ClangASTType pointee_clang_type = pointee_type->GetClangForwardType();
7158 ClangASTType class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00007159
Pavel Labathc7c30eb2015-06-08 23:38:06 +00007160 clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00007161
Enrico Granata1cd5e922015-01-28 00:07:51 +00007162 byte_size = clang_type.GetByteSize(nullptr);
Greg Clayton9b81a312010-06-12 01:20:30 +00007163
Greg Clayton81c22f62011-10-19 18:09:39 +00007164 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00007165 this,
7166 type_name_const_str,
7167 byte_size,
7168 NULL,
7169 LLDB_INVALID_UID,
7170 Type::eEncodingIsUID,
7171 NULL,
7172 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00007173 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00007174 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007175
Greg Clayton9b81a312010-06-12 01:20:30 +00007176 break;
7177 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007178 default:
Greg Clayton84afacd2012-11-07 23:09:32 +00007179 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",
7180 die->GetOffset(),
7181 tag,
7182 DW_TAG_value_to_name(tag));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007183 break;
7184 }
7185
7186 if (type_sp.get())
7187 {
7188 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
7189 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
7190
7191 SymbolContextScope * symbol_context_scope = NULL;
7192 if (sc_parent_tag == DW_TAG_compile_unit)
7193 {
7194 symbol_context_scope = sc.comp_unit;
7195 }
Jason Molenda60db6e42014-10-16 01:40:16 +00007196 else if (sc.function != NULL && sc_parent_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007197 {
Greg Clayton81c22f62011-10-19 18:09:39 +00007198 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007199 if (symbol_context_scope == NULL)
7200 symbol_context_scope = sc.function;
7201 }
7202
7203 if (symbol_context_scope != NULL)
7204 {
7205 type_sp->SetSymbolContextScope(symbol_context_scope);
7206 }
7207
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00007208 // We are ready to put this type into the uniqued list up at the module level
7209 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00007210
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00007211 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007212 }
7213 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00007214 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007215 {
Greg Claytone1cd1be2012-01-29 20:56:30 +00007216 type_sp = type_ptr->shared_from_this();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007217 }
7218 }
7219 return type_sp;
7220}
7221
7222size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00007223SymbolFileDWARF::ParseTypes
7224(
7225 const SymbolContext& sc,
7226 DWARFCompileUnit* dwarf_cu,
7227 const DWARFDebugInfoEntry *die,
7228 bool parse_siblings,
7229 bool parse_children
7230)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007231{
7232 size_t types_added = 0;
7233 while (die != NULL)
7234 {
7235 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00007236 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007237 {
7238 if (type_is_new)
7239 ++types_added;
7240 }
7241
7242 if (parse_children && die->HasChildren())
7243 {
7244 if (die->Tag() == DW_TAG_subprogram)
7245 {
7246 SymbolContext child_sc(sc);
Greg Clayton81c22f62011-10-19 18:09:39 +00007247 child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007248 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
7249 }
7250 else
7251 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
7252 }
7253
7254 if (parse_siblings)
7255 die = die->GetSibling();
7256 else
7257 die = NULL;
7258 }
7259 return types_added;
7260}
7261
7262
7263size_t
7264SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
7265{
7266 assert(sc.comp_unit && sc.function);
7267 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00007268 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007269 if (dwarf_cu)
7270 {
7271 dw_offset_t function_die_offset = sc.function->GetID();
7272 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
7273 if (function_die)
7274 {
Greg Claytondd7feaf2011-08-12 17:54:33 +00007275 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007276 }
7277 }
7278
7279 return functions_added;
7280}
7281
7282
7283size_t
7284SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
7285{
7286 // At least a compile unit must be valid
7287 assert(sc.comp_unit);
7288 size_t types_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00007289 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007290 if (dwarf_cu)
7291 {
7292 if (sc.function)
7293 {
7294 dw_offset_t function_die_offset = sc.function->GetID();
7295 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
7296 if (func_die && func_die->HasChildren())
7297 {
7298 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
7299 }
7300 }
7301 else
7302 {
7303 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
7304 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
7305 {
7306 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
7307 }
7308 }
7309 }
7310
7311 return types_added;
7312}
7313
7314size_t
7315SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
7316{
7317 if (sc.comp_unit != NULL)
7318 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00007319 DWARFDebugInfo* info = DebugInfo();
7320 if (info == NULL)
7321 return 0;
7322
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007323 if (sc.function)
7324 {
Greg Clayton9422dd62013-03-04 21:46:16 +00007325 DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get();
7326
7327 if (dwarf_cu == NULL)
7328 return 0;
7329
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007330 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00007331
Greg Claytonc7bece562013-01-25 18:06:21 +00007332 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
7333 if (func_lo_pc != LLDB_INVALID_ADDRESS)
Greg Claytone38a5ed2012-01-05 03:57:59 +00007334 {
7335 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Greg Claytonc662ec82011-06-17 22:10:16 +00007336
Greg Claytone38a5ed2012-01-05 03:57:59 +00007337 // Let all blocks know they have parse all their variables
7338 sc.function->GetBlock (false).SetDidParseVariables (true, true);
7339 return num_variables;
7340 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007341 }
7342 else if (sc.comp_unit)
7343 {
Greg Clayton9422dd62013-03-04 21:46:16 +00007344 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get();
7345
7346 if (dwarf_cu == NULL)
7347 return 0;
7348
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007349 uint32_t vars_added = 0;
7350 VariableListSP variables (sc.comp_unit->GetVariableList(false));
7351
7352 if (variables.get() == NULL)
7353 {
7354 variables.reset(new VariableList());
7355 sc.comp_unit->SetVariableList(variables);
7356
Greg Claytond4a2b372011-09-12 23:21:58 +00007357 DWARFCompileUnit* match_dwarf_cu = NULL;
7358 const DWARFDebugInfoEntry* die = NULL;
7359 DIEArray die_offsets;
Greg Clayton97fbc342011-10-20 22:30:33 +00007360 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00007361 {
Greg Clayton97fbc342011-10-20 22:30:33 +00007362 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00007363 {
7364 DWARFMappedHash::DIEInfoArray hash_data_array;
7365 if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
7366 dwarf_cu->GetNextCompileUnitOffset(),
7367 hash_data_array))
7368 {
7369 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
7370 }
7371 }
Greg Clayton7f995132011-10-04 22:41:51 +00007372 }
7373 else
7374 {
7375 // Index if we already haven't to make sure the compile units
7376 // get indexed and make their global DIE index list
7377 if (!m_indexed)
7378 Index ();
7379
7380 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
7381 dwarf_cu->GetNextCompileUnitOffset(),
7382 die_offsets);
7383 }
7384
7385 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00007386 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007387 {
Greg Claytond4a2b372011-09-12 23:21:58 +00007388 DWARFDebugInfo* debug_info = DebugInfo();
7389 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007390 {
Greg Claytond4a2b372011-09-12 23:21:58 +00007391 const dw_offset_t die_offset = die_offsets[i];
7392 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
Greg Clayton95d87902011-11-11 03:16:25 +00007393 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00007394 {
Greg Clayton95d87902011-11-11 03:16:25 +00007395 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
7396 if (var_sp)
7397 {
7398 variables->AddVariableIfUnique (var_sp);
7399 ++vars_added;
7400 }
Greg Claytond4a2b372011-09-12 23:21:58 +00007401 }
Greg Clayton95d87902011-11-11 03:16:25 +00007402 else
7403 {
7404 if (m_using_apple_tables)
7405 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00007406 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_offset);
Greg Clayton95d87902011-11-11 03:16:25 +00007407 }
7408 }
7409
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007410 }
7411 }
7412 }
7413 return vars_added;
7414 }
7415 }
7416 return 0;
7417}
7418
7419
7420VariableSP
7421SymbolFileDWARF::ParseVariableDIE
7422(
7423 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00007424 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00007425 const DWARFDebugInfoEntry *die,
7426 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007427)
7428{
Greg Clayton83c5cd92010-11-14 22:13:40 +00007429 VariableSP var_sp (m_die_to_variable_sp[die]);
7430 if (var_sp)
7431 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007432
7433 const dw_tag_t tag = die->Tag();
Richard Mitton0a558352013-10-17 21:14:00 +00007434 ModuleSP module = GetObjectFile()->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00007435
7436 if ((tag == DW_TAG_variable) ||
7437 (tag == DW_TAG_constant) ||
7438 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007439 {
Greg Clayton7f995132011-10-04 22:41:51 +00007440 DWARFDebugInfoEntry::Attributes attributes;
7441 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
7442 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007443 {
Greg Clayton7f995132011-10-04 22:41:51 +00007444 const char *name = NULL;
7445 const char *mangled = NULL;
7446 Declaration decl;
7447 uint32_t i;
Greg Claytond1767f02011-12-08 02:13:16 +00007448 lldb::user_id_t type_uid = LLDB_INVALID_UID;
Greg Clayton7f995132011-10-04 22:41:51 +00007449 DWARFExpression location;
7450 bool is_external = false;
7451 bool is_artificial = false;
7452 bool location_is_const_value_data = false;
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007453 bool has_explicit_location = false;
Enrico Granata4ec130d2014-08-11 19:16:35 +00007454 DWARFFormValue const_value;
Greg Clayton23f59502012-07-17 03:23:13 +00007455 //AccessType accessibility = eAccessNone;
Greg Clayton7f995132011-10-04 22:41:51 +00007456
7457 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007458 {
Greg Clayton7f995132011-10-04 22:41:51 +00007459 dw_attr_t attr = attributes.AttributeAtIndex(i);
7460 DWARFFormValue form_value;
Greg Clayton54166af2014-11-22 01:58:59 +00007461
Greg Clayton7f995132011-10-04 22:41:51 +00007462 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007463 {
Greg Clayton7f995132011-10-04 22:41:51 +00007464 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007465 {
Greg Clayton7f995132011-10-04 22:41:51 +00007466 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
7467 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
7468 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
7469 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton71415542012-12-08 00:24:40 +00007470 case DW_AT_linkage_name:
Greg Clayton7f995132011-10-04 22:41:51 +00007471 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00007472 case DW_AT_type: type_uid = form_value.Reference(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00007473 case DW_AT_external: is_external = form_value.Boolean(); break;
Greg Clayton7f995132011-10-04 22:41:51 +00007474 case DW_AT_const_value:
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007475 // If we have already found a DW_AT_location attribute, ignore this attribute.
7476 if (!has_explicit_location)
7477 {
7478 location_is_const_value_data = true;
7479 // The constant value will be either a block, a data value or a string.
Ed Masteeeae7212013-10-24 20:43:47 +00007480 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007481 if (DWARFFormValue::IsBlockForm(form_value.Form()))
7482 {
7483 // Retrieve the value as a block expression.
7484 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
7485 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00007486 location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007487 }
7488 else if (DWARFFormValue::IsDataForm(form_value.Form()))
7489 {
7490 // Retrieve the value as a data expression.
Greg Clayton54166af2014-11-22 01:58:59 +00007491 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007492 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
7493 uint32_t data_length = fixed_form_sizes[form_value.Form()];
Enrico Granata4ec130d2014-08-11 19:16:35 +00007494 if (data_length == 0)
7495 {
7496 const uint8_t *data_pointer = form_value.BlockData();
7497 if (data_pointer)
7498 {
Jason Molenda18f5fd32014-10-16 07:52:17 +00007499 form_value.Unsigned();
Enrico Granata4ec130d2014-08-11 19:16:35 +00007500 }
7501 else if (DWARFFormValue::IsDataForm(form_value.Form()))
7502 {
7503 // we need to get the byte size of the type later after we create the variable
7504 const_value = form_value;
7505 }
7506 }
7507 else
7508 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007509 }
7510 else
7511 {
7512 // Retrieve the value as a string expression.
7513 if (form_value.Form() == DW_FORM_strp)
7514 {
Greg Clayton54166af2014-11-22 01:58:59 +00007515 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007516 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
7517 uint32_t data_length = fixed_form_sizes[form_value.Form()];
Richard Mitton0a558352013-10-17 21:14:00 +00007518 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007519 }
7520 else
7521 {
7522 const char *str = form_value.AsCString(&debug_info_data);
7523 uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
7524 uint32_t string_length = strlen(str) + 1;
Richard Mitton0a558352013-10-17 21:14:00 +00007525 location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007526 }
7527 }
7528 }
7529 break;
Greg Clayton7f995132011-10-04 22:41:51 +00007530 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007531 {
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007532 location_is_const_value_data = false;
7533 has_explicit_location = true;
Greg Clayton7f995132011-10-04 22:41:51 +00007534 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007535 {
Ed Masteeeae7212013-10-24 20:43:47 +00007536 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Clayton7f995132011-10-04 22:41:51 +00007537
7538 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
7539 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00007540 location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
Greg Clayton7f995132011-10-04 22:41:51 +00007541 }
7542 else
7543 {
Ed Masteeeae7212013-10-24 20:43:47 +00007544 const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
Greg Clayton7f995132011-10-04 22:41:51 +00007545 const dw_offset_t debug_loc_offset = form_value.Unsigned();
7546
7547 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
7548 if (loc_list_length > 0)
7549 {
Richard Mitton0a558352013-10-17 21:14:00 +00007550 location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
Greg Clayton7f995132011-10-04 22:41:51 +00007551 assert (func_low_pc != LLDB_INVALID_ADDRESS);
Greg Clayton54166af2014-11-22 01:58:59 +00007552 location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
Greg Clayton7f995132011-10-04 22:41:51 +00007553 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007554 }
7555 }
Greg Clayton7f995132011-10-04 22:41:51 +00007556 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007557
Greg Clayton1c8ef472013-04-05 23:27:21 +00007558 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00007559 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7f995132011-10-04 22:41:51 +00007560 case DW_AT_declaration:
7561 case DW_AT_description:
7562 case DW_AT_endianity:
7563 case DW_AT_segment:
7564 case DW_AT_start_scope:
7565 case DW_AT_visibility:
7566 default:
7567 case DW_AT_abstract_origin:
7568 case DW_AT_sibling:
7569 case DW_AT_specification:
7570 break;
7571 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007572 }
7573 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007574
Greg Clayton9e9f2192013-05-17 00:55:28 +00007575 ValueType scope = eValueTypeInvalid;
7576
7577 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
7578 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
7579 SymbolContextScope * symbol_context_scope = NULL;
7580
Siva Chandra0783ab92015-03-24 18:32:27 +00007581 if (!mangled)
7582 {
7583 // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
7584 // generate fully qualified names of global variables with commands like "frame var j".
7585 // For example, if j were an int variable holding a value 4 and declared in a namespace
7586 // B which in turn is contained in a namespace A, the command "frame var j" returns
7587 // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
7588 // to generate a fully qualified name from the declaration context.
7589 if (die->GetParent()->Tag() == DW_TAG_compile_unit &&
7590 LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()))
7591 {
7592 DWARFDeclContext decl_ctx;
7593
7594 die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx);
7595 mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
7596 }
7597 }
7598
Greg Clayton9e9f2192013-05-17 00:55:28 +00007599 // DWARF doesn't specify if a DW_TAG_variable is a local, global
7600 // or static variable, so we have to do a little digging by
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00007601 // looking at the location of a variable to see if it contains
Greg Clayton9e9f2192013-05-17 00:55:28 +00007602 // a DW_OP_addr opcode _somewhere_ in the definition. I say
7603 // somewhere because clang likes to combine small global variables
7604 // into the same symbol and have locations like:
7605 // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
7606 // So if we don't have a DW_TAG_formal_parameter, we can look at
7607 // the location to see if it contains a DW_OP_addr opcode, and
7608 // then we can correctly classify our variables.
7609 if (tag == DW_TAG_formal_parameter)
7610 scope = eValueTypeVariableArgument;
7611 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007612 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007613 bool op_error = false;
7614 // Check if the location has a DW_OP_addr with any address value...
7615 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
7616 if (!location_is_const_value_data)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007617 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007618 location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
7619 if (op_error)
Greg Clayton96c09682012-01-04 22:56:43 +00007620 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007621 StreamString strm;
7622 location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
7623 GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str());
Greg Clayton96c09682012-01-04 22:56:43 +00007624 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00007625 }
Greg Claytond1767f02011-12-08 02:13:16 +00007626
Greg Clayton9e9f2192013-05-17 00:55:28 +00007627 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
7628 {
7629 if (is_external)
7630 scope = eValueTypeVariableGlobal;
7631 else
7632 scope = eValueTypeVariableStatic;
7633
7634
7635 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
7636
7637 if (debug_map_symfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007638 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007639 // When leaving the DWARF in the .o files on darwin,
7640 // when we have a global variable that wasn't initialized,
7641 // the .o file might not have allocated a virtual
7642 // address for the global variable. In this case it will
7643 // have created a symbol for the global variable
7644 // that is undefined/data and external and the value will
7645 // be the byte size of the variable. When we do the
7646 // address map in SymbolFileDWARFDebugMap we rely on
7647 // having an address, we need to do some magic here
7648 // so we can get the correct address for our global
7649 // variable. The address for all of these entries
7650 // will be zero, and there will be an undefined symbol
7651 // in this object file, and the executable will have
7652 // a matching symbol with a good address. So here we
7653 // dig up the correct address and replace it in the
7654 // location for the variable, and set the variable's
7655 // symbol context scope to be that of the main executable
7656 // so the file address will resolve correctly.
7657 bool linked_oso_file_addr = false;
7658 if (is_external && location_DW_OP_addr == 0)
Greg Clayton9422dd62013-03-04 21:46:16 +00007659 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007660 // we have a possible uninitialized extern global
7661 ConstString const_name(mangled ? mangled : name);
7662 ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
7663 if (debug_map_objfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007664 {
Greg Clayton3046e662013-07-10 01:23:25 +00007665 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
Greg Clayton9e9f2192013-05-17 00:55:28 +00007666 if (debug_map_symtab)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007667 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007668 Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
7669 eSymbolTypeData,
7670 Symtab::eDebugYes,
7671 Symtab::eVisibilityExtern);
7672 if (exe_symbol)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007673 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007674 if (exe_symbol->ValueIsAddress())
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007675 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00007676 const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
Greg Clayton9e9f2192013-05-17 00:55:28 +00007677 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007678 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007679 if (location.Update_DW_OP_addr (exe_file_addr))
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007680 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007681 linked_oso_file_addr = true;
7682 symbol_context_scope = exe_symbol;
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007683 }
7684 }
7685 }
7686 }
7687 }
7688 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00007689 }
Greg Clayton9422dd62013-03-04 21:46:16 +00007690
Greg Clayton9e9f2192013-05-17 00:55:28 +00007691 if (!linked_oso_file_addr)
7692 {
7693 // The DW_OP_addr is not zero, but it contains a .o file address which
7694 // needs to be linked up correctly.
7695 const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
7696 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton9422dd62013-03-04 21:46:16 +00007697 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007698 // Update the file address for this variable
7699 location.Update_DW_OP_addr (exe_file_addr);
7700 }
7701 else
7702 {
7703 // Variable didn't make it into the final executable
7704 return var_sp;
Greg Clayton9422dd62013-03-04 21:46:16 +00007705 }
Greg Claytond1767f02011-12-08 02:13:16 +00007706 }
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007707 }
Greg Clayton5cf58b92011-10-05 22:22:08 +00007708 }
7709 else
7710 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007711 scope = eValueTypeVariableLocal;
Greg Clayton5cf58b92011-10-05 22:22:08 +00007712 }
Greg Clayton7f995132011-10-04 22:41:51 +00007713 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00007714
7715 if (symbol_context_scope == NULL)
7716 {
7717 switch (parent_tag)
7718 {
7719 case DW_TAG_subprogram:
7720 case DW_TAG_inlined_subroutine:
7721 case DW_TAG_lexical_block:
7722 if (sc.function)
7723 {
7724 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
7725 if (symbol_context_scope == NULL)
7726 symbol_context_scope = sc.function;
7727 }
7728 break;
7729
7730 default:
7731 symbol_context_scope = sc.comp_unit;
7732 break;
7733 }
7734 }
7735
7736 if (symbol_context_scope)
7737 {
Enrico Granata4ec130d2014-08-11 19:16:35 +00007738 SymbolFileTypeSP type_sp(new SymbolFileType(*this, type_uid));
7739
7740 if (const_value.Form() && type_sp && type_sp->GetType())
7741 location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), dwarf_cu->GetAddressByteSize());
7742
Greg Clayton9e9f2192013-05-17 00:55:28 +00007743 var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
7744 name,
7745 mangled,
Enrico Granata4ec130d2014-08-11 19:16:35 +00007746 type_sp,
Greg Clayton9e9f2192013-05-17 00:55:28 +00007747 scope,
7748 symbol_context_scope,
7749 &decl,
7750 location,
7751 is_external,
7752 is_artificial));
7753
7754 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
7755 }
7756 else
7757 {
7758 // Not ready to parse this variable yet. It might be a global
7759 // or static variable that is in a function scope and the function
7760 // in the symbol context wasn't filled in yet
7761 return var_sp;
7762 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007763 }
Greg Clayton7f995132011-10-04 22:41:51 +00007764 // Cache var_sp even if NULL (the variable was just a specification or
7765 // was missing vital information to be able to be displayed in the debugger
7766 // (missing location due to optimization, etc)) so we don't re-parse
7767 // this DIE over and over later...
7768 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007769 }
7770 return var_sp;
7771}
7772
Greg Claytonc662ec82011-06-17 22:10:16 +00007773
7774const DWARFDebugInfoEntry *
7775SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
7776 dw_offset_t spec_block_die_offset,
7777 DWARFCompileUnit **result_die_cu_handle)
7778{
7779 // Give the concrete function die specified by "func_die_offset", find the
7780 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
7781 // to "spec_block_die_offset"
7782 DWARFDebugInfo* info = DebugInfo();
7783
7784 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
7785 if (die)
7786 {
7787 assert (*result_die_cu_handle);
7788 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
7789 }
7790 return NULL;
7791}
7792
7793
7794const DWARFDebugInfoEntry *
7795SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
7796 const DWARFDebugInfoEntry *die,
7797 dw_offset_t spec_block_die_offset,
7798 DWARFCompileUnit **result_die_cu_handle)
7799{
7800 if (die)
7801 {
7802 switch (die->Tag())
7803 {
7804 case DW_TAG_subprogram:
7805 case DW_TAG_inlined_subroutine:
7806 case DW_TAG_lexical_block:
7807 {
7808 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
7809 {
7810 *result_die_cu_handle = dwarf_cu;
7811 return die;
7812 }
7813
7814 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
7815 {
7816 *result_die_cu_handle = dwarf_cu;
7817 return die;
7818 }
7819 }
7820 break;
7821 }
7822
7823 // Give the concrete function die specified by "func_die_offset", find the
7824 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
7825 // to "spec_block_die_offset"
7826 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
7827 {
7828 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
7829 child_die,
7830 spec_block_die_offset,
7831 result_die_cu_handle);
7832 if (result_die)
7833 return result_die;
7834 }
7835 }
7836
7837 *result_die_cu_handle = NULL;
7838 return NULL;
7839}
7840
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007841size_t
7842SymbolFileDWARF::ParseVariables
7843(
7844 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00007845 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00007846 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007847 const DWARFDebugInfoEntry *orig_die,
7848 bool parse_siblings,
7849 bool parse_children,
7850 VariableList* cc_variable_list
7851)
7852{
7853 if (orig_die == NULL)
7854 return 0;
7855
Greg Claytonc662ec82011-06-17 22:10:16 +00007856 VariableListSP variable_list_sp;
7857
7858 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007859 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00007860 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007861 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007862 dw_tag_t tag = die->Tag();
7863
7864 // Check to see if we have already parsed this variable or constant?
7865 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007866 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007867 if (cc_variable_list)
7868 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007869 }
7870 else
7871 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007872 // We haven't already parsed it, lets do that now.
7873 if ((tag == DW_TAG_variable) ||
7874 (tag == DW_TAG_constant) ||
7875 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007876 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007877 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00007878 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007879 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
7880 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
7881 switch (parent_tag)
7882 {
7883 case DW_TAG_compile_unit:
7884 if (sc.comp_unit != NULL)
7885 {
7886 variable_list_sp = sc.comp_unit->GetVariableList(false);
7887 if (variable_list_sp.get() == NULL)
7888 {
7889 variable_list_sp.reset(new VariableList());
7890 sc.comp_unit->SetVariableList(variable_list_sp);
7891 }
7892 }
7893 else
7894 {
Daniel Malead01b2952012-11-29 21:49:15 +00007895 GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
Greg Claytone38a5ed2012-01-05 03:57:59 +00007896 MakeUserID(sc_parent_die->GetOffset()),
7897 DW_TAG_value_to_name (parent_tag),
7898 MakeUserID(orig_die->GetOffset()),
7899 DW_TAG_value_to_name (orig_die->Tag()));
Greg Claytonc662ec82011-06-17 22:10:16 +00007900 }
7901 break;
7902
7903 case DW_TAG_subprogram:
7904 case DW_TAG_inlined_subroutine:
7905 case DW_TAG_lexical_block:
7906 if (sc.function != NULL)
7907 {
7908 // Check to see if we already have parsed the variables for the given scope
7909
Greg Clayton81c22f62011-10-19 18:09:39 +00007910 Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Greg Claytonc662ec82011-06-17 22:10:16 +00007911 if (block == NULL)
7912 {
7913 // This must be a specification or abstract origin with
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00007914 // a concrete block counterpart in the current function. We need
Greg Claytonc662ec82011-06-17 22:10:16 +00007915 // to find the concrete block so we can correctly add the
7916 // variable to it
7917 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
7918 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
7919 sc_parent_die->GetOffset(),
7920 &concrete_block_die_cu);
7921 if (concrete_block_die)
Greg Clayton81c22f62011-10-19 18:09:39 +00007922 block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset()));
Greg Claytonc662ec82011-06-17 22:10:16 +00007923 }
7924
7925 if (block != NULL)
7926 {
7927 const bool can_create = false;
7928 variable_list_sp = block->GetBlockVariableList (can_create);
7929 if (variable_list_sp.get() == NULL)
7930 {
7931 variable_list_sp.reset(new VariableList());
7932 block->SetVariableList(variable_list_sp);
7933 }
7934 }
7935 }
7936 break;
7937
7938 default:
Daniel Malead01b2952012-11-29 21:49:15 +00007939 GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
Greg Claytone38a5ed2012-01-05 03:57:59 +00007940 MakeUserID(orig_die->GetOffset()),
7941 DW_TAG_value_to_name (orig_die->Tag()));
Greg Claytonc662ec82011-06-17 22:10:16 +00007942 break;
7943 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00007944 }
Greg Claytonc662ec82011-06-17 22:10:16 +00007945
7946 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007947 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00007948 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
7949 if (var_sp)
7950 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007951 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00007952 if (cc_variable_list)
7953 cc_variable_list->AddVariableIfUnique (var_sp);
7954 ++vars_added;
7955 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007956 }
7957 }
7958 }
Greg Claytonc662ec82011-06-17 22:10:16 +00007959
7960 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
7961
7962 if (!skip_children && parse_children && die->HasChildren())
7963 {
7964 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
7965 }
7966
7967 if (parse_siblings)
7968 die = die->GetSibling();
7969 else
7970 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007971 }
Greg Claytonc662ec82011-06-17 22:10:16 +00007972 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007973}
7974
7975//------------------------------------------------------------------
7976// PluginInterface protocol
7977//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00007978ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007979SymbolFileDWARF::GetPluginName()
7980{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007981 return GetPluginNameStatic();
7982}
7983
7984uint32_t
7985SymbolFileDWARF::GetPluginVersion()
7986{
7987 return 1;
7988}
7989
7990void
Greg Clayton6beaaa62011-01-17 03:46:26 +00007991SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
7992{
7993 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
Greg Clayton57ee3062013-07-11 22:46:58 +00007994 ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00007995 if (clang_type)
7996 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
7997}
7998
7999void
8000SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
8001{
8002 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
Greg Clayton57ee3062013-07-11 22:46:58 +00008003 ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00008004 if (clang_type)
8005 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
8006}
8007
Greg Claytona2721472011-06-25 00:44:06 +00008008void
Sean Callanancc427fa2011-07-30 02:42:06 +00008009SymbolFileDWARF::DumpIndexes ()
8010{
8011 StreamFile s(stdout, false);
8012
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00008013 s.Printf ("DWARF index for (%s) '%s':",
Sean Callanancc427fa2011-07-30 02:42:06 +00008014 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00008015 GetObjectFile()->GetFileSpec().GetPath().c_str());
Sean Callanancc427fa2011-07-30 02:42:06 +00008016 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
8017 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
8018 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
8019 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
8020 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
8021 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
8022 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Bruce Mitchenere171da52015-07-22 00:16:02 +00008023 s.Printf("\nNamespaces:\n"); m_namespace_index.Dump (&s);
Sean Callanancc427fa2011-07-30 02:42:06 +00008024}
8025
8026void
8027SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
8028 const char *name,
8029 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00008030{
Sean Callanancc427fa2011-07-30 02:42:06 +00008031 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00008032
8033 if (iter == m_decl_ctx_to_die.end())
8034 return;
8035
Greg Claytoncb5860a2011-10-13 23:49:28 +00008036 for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos)
Greg Claytona2721472011-06-25 00:44:06 +00008037 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00008038 const DWARFDebugInfoEntry *context_die = *pos;
8039
8040 if (!results)
8041 return;
8042
8043 DWARFDebugInfo* info = DebugInfo();
8044
8045 DIEArray die_offsets;
8046
8047 DWARFCompileUnit* dwarf_cu = NULL;
8048 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton220a0072011-12-09 08:48:30 +00008049
8050 if (m_using_apple_tables)
8051 {
8052 if (m_apple_types_ap.get())
8053 m_apple_types_ap->FindByName (name, die_offsets);
8054 }
8055 else
8056 {
8057 if (!m_indexed)
8058 Index ();
8059
8060 m_type_index.Find (ConstString(name), die_offsets);
8061 }
8062
Greg Clayton220a0072011-12-09 08:48:30 +00008063 const size_t num_matches = die_offsets.size();
Greg Claytoncb5860a2011-10-13 23:49:28 +00008064
8065 if (num_matches)
Greg Claytona2721472011-06-25 00:44:06 +00008066 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00008067 for (size_t i = 0; i < num_matches; ++i)
8068 {
8069 const dw_offset_t die_offset = die_offsets[i];
8070 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Greg Claytond4a2b372011-09-12 23:21:58 +00008071
Greg Claytoncb5860a2011-10-13 23:49:28 +00008072 if (die->GetParent() != context_die)
8073 continue;
8074
8075 Type *matching_type = ResolveType (dwarf_cu, die);
8076
Pavel Labathc7c30eb2015-06-08 23:38:06 +00008077 clang::QualType qual_type = matching_type->GetClangForwardType().GetQualType();
Greg Claytoncb5860a2011-10-13 23:49:28 +00008078
8079 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
8080 {
8081 clang::TagDecl *tag_decl = tag_type->getDecl();
8082 results->push_back(tag_decl);
8083 }
8084 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
8085 {
8086 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
8087 results->push_back(typedef_decl);
8088 }
Greg Claytona2721472011-06-25 00:44:06 +00008089 }
8090 }
8091 }
8092}
8093
8094void
8095SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
Greg Clayton85ae2e12011-10-18 23:36:41 +00008096 const clang::DeclContext *decl_context,
8097 clang::DeclarationName decl_name,
Greg Claytona2721472011-06-25 00:44:06 +00008098 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
8099{
Greg Clayton85ae2e12011-10-18 23:36:41 +00008100
8101 switch (decl_context->getDeclKind())
8102 {
8103 case clang::Decl::Namespace:
8104 case clang::Decl::TranslationUnit:
8105 {
8106 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
8107 symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results);
8108 }
8109 break;
8110 default:
8111 break;
8112 }
Greg Claytona2721472011-06-25 00:44:06 +00008113}
Greg Claytoncaab74e2012-01-28 00:48:57 +00008114
Zachary Turner504f38d2015-03-24 16:24:50 +00008115bool
8116SymbolFileDWARF::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size,
8117 uint64_t &alignment,
Zachary Turnera98fac22015-03-24 18:56:08 +00008118 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
8119 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
8120 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
Greg Claytoncaab74e2012-01-28 00:48:57 +00008121{
8122 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
8123 return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets);
8124}
8125
Zachary Turner504f38d2015-03-24 16:24:50 +00008126bool
8127SymbolFileDWARF::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
Zachary Turnera98fac22015-03-24 18:56:08 +00008128 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
8129 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
8130 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
Greg Claytoncaab74e2012-01-28 00:48:57 +00008131{
Greg Clayton5160ce52013-03-27 23:08:40 +00008132 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Claytoncaab74e2012-01-28 00:48:57 +00008133 RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
8134 bool success = false;
8135 base_offsets.clear();
8136 vbase_offsets.clear();
8137 if (pos != m_record_decl_to_layout_map.end())
8138 {
8139 bit_size = pos->second.bit_size;
8140 alignment = pos->second.alignment;
8141 field_offsets.swap(pos->second.field_offsets);
Greg Clayton2508b9b2012-11-01 23:20:02 +00008142 base_offsets.swap (pos->second.base_offsets);
8143 vbase_offsets.swap (pos->second.vbase_offsets);
Greg Claytoncaab74e2012-01-28 00:48:57 +00008144 m_record_decl_to_layout_map.erase(pos);
8145 success = true;
8146 }
8147 else
8148 {
8149 bit_size = 0;
8150 alignment = 0;
8151 field_offsets.clear();
8152 }
8153
8154 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00008155 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00008156 "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00008157 static_cast<const void*>(record_decl),
8158 bit_size, alignment,
8159 static_cast<uint32_t>(field_offsets.size()),
8160 static_cast<uint32_t>(base_offsets.size()),
8161 static_cast<uint32_t>(vbase_offsets.size()),
Greg Claytoncaab74e2012-01-28 00:48:57 +00008162 success);
8163 return success;
8164}
8165
8166
Greg Clayton1f746072012-08-29 21:13:06 +00008167SymbolFileDWARFDebugMap *
8168SymbolFileDWARF::GetDebugMapSymfile ()
8169{
8170 if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
8171 {
8172 lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
8173 if (module_sp)
8174 {
8175 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
8176 if (sym_vendor)
8177 m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
8178 }
8179 }
8180 return m_debug_map_symfile;
8181}
8182
Greg Claytoncaab74e2012-01-28 00:48:57 +00008183