blob: 9785627ba9493e65f2090fd48add0a75977b2713 [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 }
129
130 const char *colon_pos = strchr(path_from_dwarf, ':');
131 if (!colon_pos)
132 {
133 return path_from_dwarf;
134 }
135
136 // check whether we have a windows path, and so the first character
137 // is a drive-letter not a hostname.
138 if (
139 colon_pos == path_from_dwarf + 1 &&
140 isalpha(*path_from_dwarf) &&
141 strlen(path_from_dwarf) > 2 &&
142 '\\' == path_from_dwarf[2])
143 {
144 return path_from_dwarf;
145 }
146
147 return colon_pos + 1;
148}
149
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +0000150// DW_AT_comp_dir can be overridden by setting compiler's PWD environment
151// variable - for example, set to "/proc/self/cwd" in order to cope with
152// distributed builds.
153static const char* comp_dir_symlinks[] = {"/proc/self/cwd"};
154
155static const char*
156resolveCompDir(const char* path_from_dwarf)
157{
158 if (!path_from_dwarf)
159 return nullptr;
160
161 // DWARF2/3 suggests the form hostname:pathname for compilation directory.
162 // Remove the host part if present.
163 const char* local_path = removeHostnameFromPathname(path_from_dwarf);
164 if (!local_path)
165 return nullptr;
166
167 bool is_symlink = false;
168 for (unsigned long i = 0; i < sizeof(comp_dir_symlinks)/sizeof(comp_dir_symlinks[0]) && !is_symlink; ++i)
169 is_symlink = !strcmp(comp_dir_symlinks[i], local_path);
170
171 if (!is_symlink)
172 return local_path;
173
174 const FileSpec local_path_spec(local_path, true);
175 if (!local_path_spec.IsSymbolicLink())
176 return local_path;
177
178 FileSpec resolved_local_path_spec;
179 const auto error = FileSystem::Readlink(local_path_spec, resolved_local_path_spec);
180 if (error.Success())
181 return resolved_local_path_spec.GetCString();
182
183 return nullptr;
184}
185
186
Todd Fiala0a70a842014-05-28 16:43:26 +0000187#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
Greg Clayton1fba87112012-02-09 20:03:49 +0000188
189class DIEStack
190{
191public:
192
193 void Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
194 {
195 m_dies.push_back (DIEInfo(cu, die));
196 }
197
198
199 void LogDIEs (Log *log, SymbolFileDWARF *dwarf)
200 {
201 StreamString log_strm;
202 const size_t n = m_dies.size();
Daniel Malead01b2952012-11-29 21:49:15 +0000203 log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
Greg Clayton1fba87112012-02-09 20:03:49 +0000204 for (size_t i=0; i<n; i++)
205 {
206 DWARFCompileUnit *cu = m_dies[i].cu;
207 const DWARFDebugInfoEntry *die = m_dies[i].die;
208 std::string qualified_name;
209 die->GetQualifiedName(dwarf, cu, qualified_name);
Daniel Malead01b2952012-11-29 21:49:15 +0000210 log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n",
Greg Clayton43e0af02012-09-18 18:04:04 +0000211 (uint64_t)i,
Greg Clayton1fba87112012-02-09 20:03:49 +0000212 die->GetOffset(),
213 DW_TAG_value_to_name(die->Tag()),
214 qualified_name.c_str());
215 }
216 log->PutCString(log_strm.GetData());
217 }
218 void Pop ()
219 {
220 m_dies.pop_back();
221 }
222
223 class ScopedPopper
224 {
225 public:
226 ScopedPopper (DIEStack &die_stack) :
227 m_die_stack (die_stack),
228 m_valid (false)
229 {
230 }
231
232 void
233 Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
234 {
235 m_valid = true;
236 m_die_stack.Push (cu, die);
237 }
238
239 ~ScopedPopper ()
240 {
241 if (m_valid)
242 m_die_stack.Pop();
243 }
244
245
246
247 protected:
248 DIEStack &m_die_stack;
249 bool m_valid;
250 };
251
252protected:
253 struct DIEInfo {
254 DIEInfo (DWARFCompileUnit *c, const DWARFDebugInfoEntry *d) :
255 cu(c),
256 die(d)
257 {
258 }
259 DWARFCompileUnit *cu;
260 const DWARFDebugInfoEntry *die;
261 };
262 typedef std::vector<DIEInfo> Stack;
263 Stack m_dies;
264};
265#endif
266
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267void
268SymbolFileDWARF::Initialize()
269{
270 LogChannelDWARF::Initialize();
271 PluginManager::RegisterPlugin (GetPluginNameStatic(),
272 GetPluginDescriptionStatic(),
273 CreateInstance);
274}
275
276void
277SymbolFileDWARF::Terminate()
278{
279 PluginManager::UnregisterPlugin (CreateInstance);
280 LogChannelDWARF::Initialize();
281}
282
283
Greg Clayton57abc5d2013-05-10 21:47:16 +0000284lldb_private::ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285SymbolFileDWARF::GetPluginNameStatic()
286{
Greg Clayton57abc5d2013-05-10 21:47:16 +0000287 static ConstString g_name("dwarf");
288 return g_name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289}
290
291const char *
292SymbolFileDWARF::GetPluginDescriptionStatic()
293{
294 return "DWARF and DWARF3 debug symbol file reader.";
295}
296
297
298SymbolFile*
299SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
300{
301 return new SymbolFileDWARF(obj_file);
302}
303
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000304TypeList *
305SymbolFileDWARF::GetTypeList ()
306{
Greg Clayton1f746072012-08-29 21:13:06 +0000307 if (GetDebugMapSymfile ())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000308 return m_debug_map_symfile->GetTypeList();
309 return m_obj_file->GetModule()->GetTypeList();
310
311}
Greg Claytonf02500c2013-06-18 22:51:05 +0000312void
313SymbolFileDWARF::GetTypes (DWARFCompileUnit* cu,
314 const DWARFDebugInfoEntry *die,
315 dw_offset_t min_die_offset,
316 dw_offset_t max_die_offset,
317 uint32_t type_mask,
318 TypeSet &type_set)
319{
320 if (cu)
321 {
322 if (die)
323 {
324 const dw_offset_t die_offset = die->GetOffset();
325
326 if (die_offset >= max_die_offset)
327 return;
328
329 if (die_offset >= min_die_offset)
330 {
331 const dw_tag_t tag = die->Tag();
332
333 bool add_type = false;
334
335 switch (tag)
336 {
337 case DW_TAG_array_type: add_type = (type_mask & eTypeClassArray ) != 0; break;
338 case DW_TAG_unspecified_type:
339 case DW_TAG_base_type: add_type = (type_mask & eTypeClassBuiltin ) != 0; break;
340 case DW_TAG_class_type: add_type = (type_mask & eTypeClassClass ) != 0; break;
341 case DW_TAG_structure_type: add_type = (type_mask & eTypeClassStruct ) != 0; break;
342 case DW_TAG_union_type: add_type = (type_mask & eTypeClassUnion ) != 0; break;
343 case DW_TAG_enumeration_type: add_type = (type_mask & eTypeClassEnumeration ) != 0; break;
344 case DW_TAG_subroutine_type:
345 case DW_TAG_subprogram:
346 case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction ) != 0; break;
347 case DW_TAG_pointer_type: add_type = (type_mask & eTypeClassPointer ) != 0; break;
348 case DW_TAG_rvalue_reference_type:
349 case DW_TAG_reference_type: add_type = (type_mask & eTypeClassReference ) != 0; break;
350 case DW_TAG_typedef: add_type = (type_mask & eTypeClassTypedef ) != 0; break;
351 case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
352 }
353
354 if (add_type)
355 {
356 const bool assert_not_being_parsed = true;
357 Type *type = ResolveTypeUID (cu, die, assert_not_being_parsed);
358 if (type)
359 {
360 if (type_set.find(type) == type_set.end())
361 type_set.insert(type);
362 }
363 }
364 }
365
366 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild();
367 child_die != NULL;
368 child_die = child_die->GetSibling())
369 {
370 GetTypes (cu, child_die, min_die_offset, max_die_offset, type_mask, type_set);
371 }
372 }
373 }
374}
375
376size_t
377SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
378 uint32_t type_mask,
379 TypeList &type_list)
380
381{
382 TypeSet type_set;
383
384 CompileUnit *comp_unit = NULL;
385 DWARFCompileUnit* dwarf_cu = NULL;
386 if (sc_scope)
387 comp_unit = sc_scope->CalculateSymbolContextCompileUnit();
388
389 if (comp_unit)
390 {
391 dwarf_cu = GetDWARFCompileUnit(comp_unit);
392 if (dwarf_cu == 0)
393 return 0;
394 GetTypes (dwarf_cu,
395 dwarf_cu->DIE(),
396 dwarf_cu->GetOffset(),
397 dwarf_cu->GetNextCompileUnitOffset(),
398 type_mask,
399 type_set);
400 }
401 else
402 {
403 DWARFDebugInfo* info = DebugInfo();
404 if (info)
405 {
406 const size_t num_cus = info->GetNumCompileUnits();
407 for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
408 {
409 dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
410 if (dwarf_cu)
411 {
412 GetTypes (dwarf_cu,
413 dwarf_cu->DIE(),
414 0,
415 UINT32_MAX,
416 type_mask,
417 type_set);
418 }
419 }
420 }
421 }
422// if (m_using_apple_tables)
423// {
424// DWARFMappedHash::MemoryTable *apple_types = m_apple_types_ap.get();
425// if (apple_types)
426// {
427// apple_types->ForEach([this, &type_set, apple_types, type_mask](const DWARFMappedHash::DIEInfoArray &die_info_array) -> bool {
428//
429// for (auto die_info: die_info_array)
430// {
431// bool add_type = TagMatchesTypeMask (type_mask, 0);
432// if (!add_type)
433// {
434// dw_tag_t tag = die_info.tag;
435// if (tag == 0)
436// {
437// const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtr(die_info.offset, NULL);
438// tag = die->Tag();
439// }
440// add_type = TagMatchesTypeMask (type_mask, tag);
441// }
442// if (add_type)
443// {
444// Type *type = ResolveTypeUID(die_info.offset);
445//
446// if (type_set.find(type) == type_set.end())
447// type_set.insert(type);
448// }
449// }
450// return true; // Keep iterating
451// });
452// }
453// }
454// else
455// {
456// if (!m_indexed)
457// Index ();
458//
459// m_type_index.ForEach([this, &type_set, type_mask](const char *name, uint32_t die_offset) -> bool {
460//
461// bool add_type = TagMatchesTypeMask (type_mask, 0);
462//
463// if (!add_type)
464// {
465// const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtr(die_offset, NULL);
466// if (die)
467// {
468// const dw_tag_t tag = die->Tag();
469// add_type = TagMatchesTypeMask (type_mask, tag);
470// }
471// }
472//
473// if (add_type)
474// {
475// Type *type = ResolveTypeUID(die_offset);
476//
477// if (type_set.find(type) == type_set.end())
478// type_set.insert(type);
479// }
480// return true; // Keep iterating
481// });
482// }
483
Greg Clayton57ee3062013-07-11 22:46:58 +0000484 std::set<ClangASTType> clang_type_set;
Greg Claytonf02500c2013-06-18 22:51:05 +0000485 size_t num_types_added = 0;
486 for (Type *type : type_set)
487 {
Greg Clayton57ee3062013-07-11 22:46:58 +0000488 ClangASTType clang_type = type->GetClangForwardType();
Greg Clayton0fc4f312013-06-20 01:23:18 +0000489 if (clang_type_set.find(clang_type) == clang_type_set.end())
490 {
491 clang_type_set.insert(clang_type);
492 type_list.Insert (type->shared_from_this());
493 ++num_types_added;
494 }
Greg Claytonf02500c2013-06-18 22:51:05 +0000495 }
496 return num_types_added;
497}
498
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000499
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000500//----------------------------------------------------------------------
501// Gets the first parent that is a lexical block, function or inlined
502// subroutine, or compile unit.
503//----------------------------------------------------------------------
504static const DWARFDebugInfoEntry *
505GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
506{
507 const DWARFDebugInfoEntry *die;
508 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
509 {
510 dw_tag_t tag = die->Tag();
511
512 switch (tag)
513 {
514 case DW_TAG_compile_unit:
515 case DW_TAG_subprogram:
516 case DW_TAG_inlined_subroutine:
517 case DW_TAG_lexical_block:
518 return die;
519 }
520 }
521 return NULL;
522}
523
524
Greg Clayton450e3f32010-10-12 02:24:53 +0000525SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
526 SymbolFile (objfile),
Greg Clayton81c22f62011-10-19 18:09:39 +0000527 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 +0000528 m_debug_map_module_wp (),
Greg Clayton450e3f32010-10-12 02:24:53 +0000529 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000530 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000531 m_flags(),
Greg Claytond4a2b372011-09-12 23:21:58 +0000532 m_data_debug_abbrev (),
533 m_data_debug_aranges (),
534 m_data_debug_frame (),
535 m_data_debug_info (),
536 m_data_debug_line (),
537 m_data_debug_loc (),
538 m_data_debug_ranges (),
539 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000540 m_data_apple_names (),
541 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000542 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000543 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000544 m_info(),
545 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000546 m_apple_names_ap (),
547 m_apple_types_ap (),
548 m_apple_namespaces_ap (),
Greg Clayton5009f9d2011-10-27 17:55:14 +0000549 m_apple_objc_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000550 m_function_basename_index(),
551 m_function_fullname_index(),
552 m_function_method_index(),
553 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000554 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000555 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000556 m_type_index(),
557 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000558 m_indexed (false),
559 m_is_external_ast_source (false),
Greg Clayton97fbc342011-10-20 22:30:33 +0000560 m_using_apple_tables (false),
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000561 m_fetched_external_modules (false),
Greg Claytonc7f03b62012-01-12 04:33:28 +0000562 m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000563 m_ranges(),
564 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000565{
566}
567
568SymbolFileDWARF::~SymbolFileDWARF()
569{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000570 if (m_is_external_ast_source)
Greg Claytone72dfb32012-02-24 01:59:29 +0000571 {
572 ModuleSP module_sp (m_obj_file->GetModule());
573 if (module_sp)
574 module_sp->GetClangASTContext().RemoveExternalSource ();
575 }
Greg Clayton6beaaa62011-01-17 03:46:26 +0000576}
577
578static const ConstString &
579GetDWARFMachOSegmentName ()
580{
581 static ConstString g_dwarf_section_name ("__DWARF");
582 return g_dwarf_section_name;
583}
584
Greg Claytone576ab22011-02-15 00:19:15 +0000585UniqueDWARFASTTypeMap &
586SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
587{
Greg Clayton1f746072012-08-29 21:13:06 +0000588 if (GetDebugMapSymfile ())
Greg Claytone576ab22011-02-15 00:19:15 +0000589 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
590 return m_unique_ast_type_map;
591}
592
Greg Clayton6beaaa62011-01-17 03:46:26 +0000593ClangASTContext &
594SymbolFileDWARF::GetClangASTContext ()
595{
Greg Clayton1f746072012-08-29 21:13:06 +0000596 if (GetDebugMapSymfile ())
Greg Clayton6beaaa62011-01-17 03:46:26 +0000597 return m_debug_map_symfile->GetClangASTContext ();
598
599 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
600 if (!m_is_external_ast_source)
601 {
602 m_is_external_ast_source = true;
Todd Fiala955fe6f2014-02-27 17:18:23 +0000603 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap (
Greg Clayton6beaaa62011-01-17 03:46:26 +0000604 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
605 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000606 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Claytoncaab74e2012-01-28 00:48:57 +0000607 SymbolFileDWARF::LayoutRecordType,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000608 this));
Greg Clayton6beaaa62011-01-17 03:46:26 +0000609 ast.SetExternalSource (ast_source_ap);
610 }
611 return ast;
612}
613
614void
615SymbolFileDWARF::InitializeObject()
616{
617 // Install our external AST source callbacks so we can complete Clang types.
Greg Claytone72dfb32012-02-24 01:59:29 +0000618 ModuleSP module_sp (m_obj_file->GetModule());
619 if (module_sp)
Greg Clayton6beaaa62011-01-17 03:46:26 +0000620 {
Greg Clayton3046e662013-07-10 01:23:25 +0000621 const SectionList *section_list = module_sp->GetSectionList();
Greg Clayton6beaaa62011-01-17 03:46:26 +0000622
623 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
624
625 // Memory map the DWARF mach-o segment so we have everything mmap'ed
626 // to keep our heap memory usage down.
627 if (section)
Greg Claytonc9660542012-02-05 02:38:54 +0000628 m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000629 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000630 get_apple_names_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000631 if (m_data_apple_names.GetByteSize() > 0)
632 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000633 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
634 if (m_apple_names_ap->IsValid())
635 m_using_apple_tables = true;
636 else
Greg Clayton7f995132011-10-04 22:41:51 +0000637 m_apple_names_ap.reset();
638 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000639 get_apple_types_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000640 if (m_data_apple_types.GetByteSize() > 0)
641 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000642 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
643 if (m_apple_types_ap->IsValid())
644 m_using_apple_tables = true;
645 else
Greg Clayton7f995132011-10-04 22:41:51 +0000646 m_apple_types_ap.reset();
647 }
648
649 get_apple_namespaces_data();
650 if (m_data_apple_namespaces.GetByteSize() > 0)
651 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000652 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
653 if (m_apple_namespaces_ap->IsValid())
654 m_using_apple_tables = true;
655 else
Greg Clayton7f995132011-10-04 22:41:51 +0000656 m_apple_namespaces_ap.reset();
657 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000658
Greg Clayton5009f9d2011-10-27 17:55:14 +0000659 get_apple_objc_data();
660 if (m_data_apple_objc.GetByteSize() > 0)
661 {
662 m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
663 if (m_apple_objc_ap->IsValid())
664 m_using_apple_tables = true;
665 else
666 m_apple_objc_ap.reset();
667 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000668}
669
670bool
671SymbolFileDWARF::SupportedVersion(uint16_t version)
672{
Greg Claytonabcbfe52013-04-04 00:00:36 +0000673 return version == 2 || version == 3 || version == 4;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000674}
675
676uint32_t
Sean Callananbfaf54d2011-12-03 04:38:43 +0000677SymbolFileDWARF::CalculateAbilities ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000678{
679 uint32_t abilities = 0;
680 if (m_obj_file != NULL)
681 {
682 const Section* section = NULL;
683 const SectionList *section_list = m_obj_file->GetSectionList();
684 if (section_list == NULL)
685 return 0;
686
687 uint64_t debug_abbrev_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000688 uint64_t debug_info_file_size = 0;
689 uint64_t debug_line_file_size = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000690
Greg Clayton6beaaa62011-01-17 03:46:26 +0000691 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000692
693 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000694 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000695
Greg Clayton4ceb9982010-07-21 22:54:26 +0000696 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697 if (section != NULL)
698 {
Greg Clayton47037bc2012-03-27 02:40:46 +0000699 debug_info_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700
Greg Clayton4ceb9982010-07-21 22:54:26 +0000701 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000703 debug_abbrev_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704 else
705 m_flags.Set (flagsGotDebugAbbrevData);
706
Greg Clayton4ceb9982010-07-21 22:54:26 +0000707 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000708 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000709 m_flags.Set (flagsGotDebugArangesData);
710
Greg Clayton4ceb9982010-07-21 22:54:26 +0000711 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000712 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000713 m_flags.Set (flagsGotDebugFrameData);
714
Greg Clayton4ceb9982010-07-21 22:54:26 +0000715 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000716 if (section)
Greg Clayton47037bc2012-03-27 02:40:46 +0000717 debug_line_file_size = section->GetFileSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 else
719 m_flags.Set (flagsGotDebugLineData);
720
Greg Clayton4ceb9982010-07-21 22:54:26 +0000721 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000722 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000723 m_flags.Set (flagsGotDebugLocData);
724
Greg Clayton4ceb9982010-07-21 22:54:26 +0000725 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000726 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727 m_flags.Set (flagsGotDebugMacInfoData);
728
Greg Clayton4ceb9982010-07-21 22:54:26 +0000729 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000730 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731 m_flags.Set (flagsGotDebugPubNamesData);
732
Greg Clayton4ceb9982010-07-21 22:54:26 +0000733 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000734 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000735 m_flags.Set (flagsGotDebugPubTypesData);
736
Greg Clayton4ceb9982010-07-21 22:54:26 +0000737 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000738 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000739 m_flags.Set (flagsGotDebugRangesData);
740
Greg Clayton4ceb9982010-07-21 22:54:26 +0000741 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Greg Clayton23f59502012-07-17 03:23:13 +0000742 if (!section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000743 m_flags.Set (flagsGotDebugStrData);
744 }
Greg Clayton6c596612012-05-18 21:47:20 +0000745 else
746 {
747 const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
748 if (symfile_dir_cstr)
749 {
750 if (strcasestr(symfile_dir_cstr, ".dsym"))
751 {
752 if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
753 {
754 // We have a dSYM file that didn't have a any debug info.
755 // If the string table has a size of 1, then it was made from
756 // an executable with no debug info, or from an executable that
757 // was stripped.
758 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
759 if (section && section->GetFileSize() == 1)
760 {
761 m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
762 }
763 }
764 }
765 }
766 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000767
768 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
769 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
770
771 if (debug_line_file_size > 0)
772 abilities |= LineTables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000773 }
774 return abilities;
775}
776
Ed Masteeeae7212013-10-24 20:43:47 +0000777const DWARFDataExtractor&
778SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779{
780 if (m_flags.IsClear (got_flag))
781 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000782 ModuleSP module_sp (m_obj_file->GetModule());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000783 m_flags.Set (got_flag);
Greg Clayton3046e662013-07-10 01:23:25 +0000784 const SectionList *section_list = module_sp->GetSectionList();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000785 if (section_list)
786 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000787 SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
788 if (section_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000789 {
790 // See if we memory mapped the DWARF segment?
791 if (m_dwarf_data.GetByteSize())
792 {
Greg Clayton47037bc2012-03-27 02:40:46 +0000793 data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000794 }
795 else
796 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000797 if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000798 data.Clear();
799 }
800 }
801 }
802 }
803 return data;
804}
805
Ed Masteeeae7212013-10-24 20:43:47 +0000806const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000807SymbolFileDWARF::get_debug_abbrev_data()
808{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000809 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000810}
811
Ed Masteeeae7212013-10-24 20:43:47 +0000812const DWARFDataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000813SymbolFileDWARF::get_debug_aranges_data()
814{
815 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
816}
817
Ed Masteeeae7212013-10-24 20:43:47 +0000818const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000819SymbolFileDWARF::get_debug_frame_data()
820{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000821 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000822}
823
Ed Masteeeae7212013-10-24 20:43:47 +0000824const DWARFDataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000825SymbolFileDWARF::get_debug_info_data()
826{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000827 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
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_line_data()
832{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000833 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
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_loc_data()
838{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000839 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
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_ranges_data()
844{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000845 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
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_str_data()
850{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000851 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000852}
853
Ed Masteeeae7212013-10-24 20:43:47 +0000854const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000855SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000856{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000857 return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000858}
859
Ed Masteeeae7212013-10-24 20:43:47 +0000860const DWARFDataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000861SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000862{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000863 return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000864}
865
Ed Masteeeae7212013-10-24 20:43:47 +0000866const DWARFDataExtractor&
Greg Clayton7f995132011-10-04 22:41:51 +0000867SymbolFileDWARF::get_apple_namespaces_data()
868{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000869 return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
870}
871
Ed Masteeeae7212013-10-24 20:43:47 +0000872const DWARFDataExtractor&
Greg Clayton5009f9d2011-10-27 17:55:14 +0000873SymbolFileDWARF::get_apple_objc_data()
874{
875 return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
Greg Clayton7f995132011-10-04 22:41:51 +0000876}
877
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000878
879DWARFDebugAbbrev*
880SymbolFileDWARF::DebugAbbrev()
881{
882 if (m_abbr.get() == NULL)
883 {
Ed Masteeeae7212013-10-24 20:43:47 +0000884 const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000885 if (debug_abbrev_data.GetByteSize() > 0)
886 {
887 m_abbr.reset(new DWARFDebugAbbrev());
888 if (m_abbr.get())
889 m_abbr->Parse(debug_abbrev_data);
890 }
891 }
892 return m_abbr.get();
893}
894
895const DWARFDebugAbbrev*
896SymbolFileDWARF::DebugAbbrev() const
897{
898 return m_abbr.get();
899}
900
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000901
902DWARFDebugInfo*
903SymbolFileDWARF::DebugInfo()
904{
905 if (m_info.get() == NULL)
906 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000907 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
908 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000909 if (get_debug_info_data().GetByteSize() > 0)
910 {
911 m_info.reset(new DWARFDebugInfo());
912 if (m_info.get())
913 {
914 m_info->SetDwarfData(this);
915 }
916 }
917 }
918 return m_info.get();
919}
920
921const DWARFDebugInfo*
922SymbolFileDWARF::DebugInfo() const
923{
924 return m_info.get();
925}
926
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000927DWARFCompileUnit*
Greg Clayton1f746072012-08-29 21:13:06 +0000928SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000929{
930 DWARFDebugInfo* info = DebugInfo();
Greg Clayton1f746072012-08-29 21:13:06 +0000931 if (info)
932 {
933 if (GetDebugMapSymfile ())
934 {
935 // The debug map symbol file made the compile units for this DWARF
936 // file which is .o file with DWARF in it, and we should have
937 // only 1 compile unit which is at offset zero in the DWARF.
938 // TODO: modify to support LTO .o files where each .o file might
939 // have multiple DW_TAG_compile_unit tags.
Greg Clayton68c00bd2015-02-05 02:10:29 +0000940
941 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0).get();
942 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
943 dwarf_cu->SetUserData(comp_unit);
944 return dwarf_cu;
Greg Clayton1f746072012-08-29 21:13:06 +0000945 }
946 else
947 {
948 // Just a normal DWARF file whose user ID for the compile unit is
949 // the DWARF offset itself
Greg Clayton68c00bd2015-02-05 02:10:29 +0000950
951 DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
952 if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
953 dwarf_cu->SetUserData(comp_unit);
954 return dwarf_cu;
955
Greg Clayton1f746072012-08-29 21:13:06 +0000956 }
957 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000958 return NULL;
959}
960
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000961
962DWARFDebugRanges*
963SymbolFileDWARF::DebugRanges()
964{
965 if (m_ranges.get() == NULL)
966 {
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000967 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
968 __PRETTY_FUNCTION__, static_cast<void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000969 if (get_debug_ranges_data().GetByteSize() > 0)
970 {
971 m_ranges.reset(new DWARFDebugRanges());
972 if (m_ranges.get())
973 m_ranges->Extract(this);
974 }
975 }
976 return m_ranges.get();
977}
978
979const DWARFDebugRanges*
980SymbolFileDWARF::DebugRanges() const
981{
982 return m_ranges.get();
983}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000984
Greg Clayton53eb1c22012-04-02 22:59:12 +0000985lldb::CompUnitSP
986SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000987{
Greg Clayton53eb1c22012-04-02 22:59:12 +0000988 CompUnitSP cu_sp;
989 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000990 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000991 CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
992 if (comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993 {
Greg Clayton53eb1c22012-04-02 22:59:12 +0000994 // We already parsed this compile unit, had out a shared pointer to it
995 cu_sp = comp_unit->shared_from_this();
996 }
997 else
998 {
Greg Clayton1f746072012-08-29 21:13:06 +0000999 if (GetDebugMapSymfile ())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001000 {
Greg Clayton1f746072012-08-29 21:13:06 +00001001 // Let the debug map create the compile unit
1002 cu_sp = m_debug_map_symfile->GetCompileUnit(this);
1003 dwarf_cu->SetUserData(cu_sp.get());
1004 }
1005 else
1006 {
1007 ModuleSP module_sp (m_obj_file->GetModule());
1008 if (module_sp)
Greg Clayton53eb1c22012-04-02 22:59:12 +00001009 {
Greg Clayton1f746072012-08-29 21:13:06 +00001010 const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
1011 if (cu_die)
Greg Clayton53eb1c22012-04-02 22:59:12 +00001012 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001013 FileSpec cu_file_spec{cu_die->GetName(this, dwarf_cu), false};
1014 if (cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +00001015 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001016 // If we have a full path to the compile unit, we don't need to resolve
1017 // the file. This can be expensive e.g. when the source files are NFS mounted.
Chaoren Lin372e9062015-06-09 17:54:27 +00001018 if (cu_file_spec.IsRelative())
Greg Clayton53eb1c22012-04-02 22:59:12 +00001019 {
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001020 const char *cu_comp_dir{cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, nullptr)};
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +00001021 cu_file_spec.PrependPathComponent(resolveCompDir(cu_comp_dir));
Greg Clayton1f746072012-08-29 21:13:06 +00001022 }
1023
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001024 std::string remapped_file;
1025 if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
1026 cu_file_spec.SetFile(remapped_file, false);
David Srbeckyd515e942015-07-08 14:00:04 +00001027 }
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001028
David Srbeckyd515e942015-07-08 14:00:04 +00001029 LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0));
Chaoren Lin0c5a9c12015-06-05 00:28:06 +00001030
David Srbeckyd515e942015-07-08 14:00:04 +00001031 cu_sp.reset(new CompileUnit (module_sp,
1032 dwarf_cu,
1033 cu_file_spec,
1034 MakeUserID(dwarf_cu->GetOffset()),
1035 cu_language));
1036 if (cu_sp)
1037 {
1038 // If we just created a compile unit with an invalid file spec, try and get the
1039 // first entry in the supports files from the line table as that should be the
1040 // compile unit.
1041 if (!cu_file_spec)
Greg Clayton1f746072012-08-29 21:13:06 +00001042 {
David Srbeckyd515e942015-07-08 14:00:04 +00001043 cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
1044 if (cu_file_spec)
1045 {
1046 (FileSpec &)(*cu_sp) = cu_file_spec;
1047 // Also fix the invalid file spec which was copied from the compile unit.
1048 cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
1049 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001050 }
David Srbeckyd515e942015-07-08 14:00:04 +00001051
1052 dwarf_cu->SetUserData(cu_sp.get());
1053
1054 // Figure out the compile unit index if we weren't given one
1055 if (cu_idx == UINT32_MAX)
1056 DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
1057
1058 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
Greg Clayton53eb1c22012-04-02 22:59:12 +00001059 }
1060 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061 }
1062 }
1063 }
1064 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001065 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066}
1067
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068uint32_t
1069SymbolFileDWARF::GetNumCompileUnits()
1070{
1071 DWARFDebugInfo* info = DebugInfo();
1072 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001073 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 return 0;
1075}
1076
1077CompUnitSP
1078SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
1079{
Greg Clayton53eb1c22012-04-02 22:59:12 +00001080 CompUnitSP cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081 DWARFDebugInfo* info = DebugInfo();
1082 if (info)
1083 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00001084 DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
1085 if (dwarf_cu)
1086 cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001087 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00001088 return cu_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001089}
1090
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001091Function *
Greg Clayton0fffff52010-09-24 05:15:53 +00001092SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093{
1094 DWARFDebugRanges::RangeList func_ranges;
1095 const char *name = NULL;
1096 const char *mangled = NULL;
1097 int decl_file = 0;
1098 int decl_line = 0;
1099 int decl_column = 0;
1100 int call_file = 0;
1101 int call_line = 0;
1102 int call_column = 0;
1103 DWARFExpression frame_base;
1104
Greg Claytonc93237c2010-10-01 20:48:32 +00001105 assert (die->Tag() == DW_TAG_subprogram);
1106
1107 if (die->Tag() != DW_TAG_subprogram)
1108 return NULL;
1109
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001110 if (die->GetDIENamesAndRanges (this,
1111 dwarf_cu,
1112 name,
1113 mangled,
1114 func_ranges,
1115 decl_file,
1116 decl_line,
1117 decl_column,
1118 call_file,
1119 call_line,
1120 call_column,
1121 &frame_base))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001122 {
1123 // Union of all ranges in the function DIE (if the function is discontiguous)
1124 AddressRange func_range;
Greg Claytonea3e7d52011-10-08 00:49:15 +00001125 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
1126 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
1128 {
Michael Sartaina7499c92013-07-01 19:45:50 +00001129 ModuleSP module_sp (m_obj_file->GetModule());
Greg Clayton3046e662013-07-10 01:23:25 +00001130 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetSectionList());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001131 if (func_range.GetBaseAddress().IsValid())
1132 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
1133 }
1134
1135 if (func_range.GetBaseAddress().IsValid())
1136 {
1137 Mangled func_name;
1138 if (mangled)
Greg Clayton037520e2012-07-18 23:18:10 +00001139 func_name.SetValue(ConstString(mangled), true);
Siva Chandra462722d2015-03-27 00:10:04 +00001140 else if (die->GetParent()->Tag() == DW_TAG_compile_unit &&
1141 LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()) &&
Greg Clayton94380562015-05-15 22:20:29 +00001142 name && strcmp(name, "main") != 0)
Siva Chandra462722d2015-03-27 00:10:04 +00001143 {
1144 // If the mangled name is not present in the DWARF, generate the demangled name
1145 // using the decl context. We skip if the function is "main" as its name is
1146 // never mangled.
1147 bool is_static = false;
1148 bool is_variadic = false;
1149 unsigned type_quals = 0;
1150 std::vector<ClangASTType> param_types;
1151 std::vector<clang::ParmVarDecl*> param_decls;
1152 const DWARFDebugInfoEntry *decl_ctx_die = NULL;
1153 DWARFDeclContext decl_ctx;
1154 StreamString sstr;
1155
1156 die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx);
1157 sstr << decl_ctx.GetQualifiedName();
1158
1159 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(dwarf_cu,
1160 die,
1161 &decl_ctx_die);
1162 ParseChildParameters(sc,
1163 containing_decl_ctx,
1164 dwarf_cu,
1165 die,
1166 true,
1167 is_static,
1168 is_variadic,
1169 param_types,
1170 param_decls,
1171 type_quals);
1172 sstr << "(";
1173 for (size_t i = 0; i < param_types.size(); i++)
1174 {
1175 if (i > 0)
1176 sstr << ", ";
1177 sstr << param_types[i].GetTypeName();
1178 }
1179 if (is_variadic)
1180 sstr << ", ...";
1181 sstr << ")";
1182 if (type_quals & clang::Qualifiers::Const)
1183 sstr << " const";
1184
1185 func_name.SetValue(ConstString(sstr.GetData()), false);
1186 }
1187 else
Greg Clayton037520e2012-07-18 23:18:10 +00001188 func_name.SetValue(ConstString(name), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001189
1190 FunctionSP func_sp;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001191 std::unique_ptr<Declaration> decl_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +00001193 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1194 decl_line,
1195 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001196
Greg Clayton0bd4e1b2011-09-30 20:52:25 +00001197 // Supply the type _only_ if it has already been parsed
Greg Clayton594e5ed2010-09-27 21:07:38 +00001198 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001199
1200 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
1201
Greg Clayton9422dd62013-03-04 21:46:16 +00001202 if (FixupAddress (func_range.GetBaseAddress()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001203 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001204 const user_id_t func_user_id = MakeUserID(die->GetOffset());
1205 func_sp.reset(new Function (sc.comp_unit,
1206 MakeUserID(func_user_id), // UserID is the DIE offset
1207 MakeUserID(func_user_id),
1208 func_name,
1209 func_type,
1210 func_range)); // first address range
1211
1212 if (func_sp.get() != NULL)
1213 {
1214 if (frame_base.IsValid())
1215 func_sp->GetFrameBaseExpression() = frame_base;
1216 sc.comp_unit->AddFunction(func_sp);
1217 return func_sp.get();
1218 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001219 }
1220 }
1221 }
1222 return NULL;
1223}
1224
Greg Clayton9422dd62013-03-04 21:46:16 +00001225bool
1226SymbolFileDWARF::FixupAddress (Address &addr)
1227{
1228 SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
1229 if (debug_map_symfile)
1230 {
1231 return debug_map_symfile->LinkOSOAddress(addr);
1232 }
1233 // This is a normal DWARF file, no address fixups need to happen
1234 return true;
1235}
Greg Clayton1f746072012-08-29 21:13:06 +00001236lldb::LanguageType
1237SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
1238{
1239 assert (sc.comp_unit);
1240 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1241 if (dwarf_cu)
1242 {
1243 const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
Jim Ingham28eb5712012-10-12 17:34:26 +00001244 if (die)
Dawn Perchikd0e87eb2015-06-17 22:30:24 +00001245 return DWARFCompileUnit::LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0));
Greg Clayton1f746072012-08-29 21:13:06 +00001246 }
1247 return eLanguageTypeUnknown;
1248}
1249
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001250size_t
1251SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
1252{
1253 assert (sc.comp_unit);
1254 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00001255 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001256 if (dwarf_cu)
1257 {
1258 DWARFDIECollection function_dies;
Greg Clayton1f746072012-08-29 21:13:06 +00001259 const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001260 size_t func_idx;
Greg Clayton1f746072012-08-29 21:13:06 +00001261 for (func_idx = 0; func_idx < num_functions; ++func_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 {
1263 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
Greg Clayton81c22f62011-10-19 18:09:39 +00001264 if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001265 {
1266 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
1267 ++functions_added;
1268 }
1269 }
1270 //FixupTypes();
1271 }
1272 return functions_added;
1273}
1274
1275bool
1276SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
1277{
1278 assert (sc.comp_unit);
Greg Clayton1f746072012-08-29 21:13:06 +00001279 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Greg Claytonda2455b2012-11-01 17:28:37 +00001280 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281 {
Greg Claytonda2455b2012-11-01 17:28:37 +00001282 const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001283
Greg Claytonda2455b2012-11-01 17:28:37 +00001284 if (cu_die)
1285 {
Oleksiy Vyalov5d9c50b2015-07-21 02:09:42 +00001286 const char * cu_comp_dir = resolveCompDir(cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, nullptr));
Matthew Gardinere81df3b2014-08-26 06:57:23 +00001287
Greg Claytonda2455b2012-11-01 17:28:37 +00001288 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 +00001289
Greg Claytonda2455b2012-11-01 17:28:37 +00001290 // All file indexes in DWARF are one based and a file of index zero is
1291 // supposed to be the compile unit itself.
1292 support_files.Append (*sc.comp_unit);
1293
1294 return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
1295 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296 }
1297 return false;
1298}
1299
Sean Callananf0c5aeb2015-04-20 16:31:29 +00001300bool
1301SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
1302{
1303 assert (sc.comp_unit);
1304 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
1305 if (dwarf_cu)
1306 {
1307 if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
1308 {
1309 UpdateExternalModuleListIfNeeded();
1310 for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
1311 {
1312 imported_modules.push_back(external_type_module.second.m_name);
1313 }
1314 }
1315 }
1316 return false;
1317}
1318
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001319struct ParseDWARFLineTableCallbackInfo
1320{
1321 LineTable* line_table;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001322 std::unique_ptr<LineSequence> sequence_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001323};
1324
1325//----------------------------------------------------------------------
1326// ParseStatementTableCallback
1327//----------------------------------------------------------------------
1328static void
1329ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1330{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001331 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1332 {
1333 // Just started parsing the line table
1334 }
1335 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1336 {
1337 // Done parsing line table, nothing to do for the cleanup
1338 }
1339 else
1340 {
1341 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
Greg Clayton9422dd62013-03-04 21:46:16 +00001342 LineTable* line_table = info->line_table;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001343
Greg Clayton9422dd62013-03-04 21:46:16 +00001344 // If this is our first time here, we need to create a
1345 // sequence container.
1346 if (!info->sequence_ap.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001347 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001348 info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
1349 assert(info->sequence_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001350 }
Greg Clayton9422dd62013-03-04 21:46:16 +00001351 line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
1352 state.address,
1353 state.line,
1354 state.column,
1355 state.file,
1356 state.is_stmt,
1357 state.basic_block,
1358 state.prologue_end,
1359 state.epilogue_begin,
1360 state.end_sequence);
1361 if (state.end_sequence)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001362 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001363 // First, put the current sequence into the line table.
1364 line_table->InsertSequence(info->sequence_ap.get());
1365 // Then, empty it to prepare for the next sequence.
1366 info->sequence_ap->Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001367 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001368 }
1369}
1370
1371bool
1372SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1373{
1374 assert (sc.comp_unit);
1375 if (sc.comp_unit->GetLineTable() != NULL)
1376 return true;
1377
Greg Clayton1f746072012-08-29 21:13:06 +00001378 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001379 if (dwarf_cu)
1380 {
1381 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
Greg Clayton129d12c2011-11-28 03:29:03 +00001382 if (dwarf_cu_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001383 {
Greg Clayton129d12c2011-11-28 03:29:03 +00001384 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
1385 if (cu_line_offset != DW_INVALID_OFFSET)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001386 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001387 std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
Greg Clayton129d12c2011-11-28 03:29:03 +00001388 if (line_table_ap.get())
1389 {
Greg Clayton9422dd62013-03-04 21:46:16 +00001390 ParseDWARFLineTableCallbackInfo info;
1391 info.line_table = line_table_ap.get();
Greg Claytonc7bece562013-01-25 18:06:21 +00001392 lldb::offset_t offset = cu_line_offset;
Greg Clayton129d12c2011-11-28 03:29:03 +00001393 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
Greg Clayton9422dd62013-03-04 21:46:16 +00001394 if (m_debug_map_symfile)
1395 {
1396 // We have an object file that has a line table with addresses
1397 // that are not linked. We need to link the line table and convert
1398 // the addresses that are relative to the .o file into addresses
1399 // for the main executable.
1400 sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
1401 }
1402 else
1403 {
1404 sc.comp_unit->SetLineTable(line_table_ap.release());
1405 return true;
1406 }
Greg Clayton129d12c2011-11-28 03:29:03 +00001407 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001408 }
1409 }
1410 }
1411 return false;
1412}
1413
1414size_t
1415SymbolFileDWARF::ParseFunctionBlocks
1416(
1417 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001418 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +00001419 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001420 const DWARFDebugInfoEntry *die,
1421 addr_t subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001422 uint32_t depth
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001423)
1424{
1425 size_t blocks_added = 0;
1426 while (die != NULL)
1427 {
1428 dw_tag_t tag = die->Tag();
1429
1430 switch (tag)
1431 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001432 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001433 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434 case DW_TAG_lexical_block:
1435 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001436 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001437 if (tag == DW_TAG_subprogram)
1438 {
1439 // Skip any DW_TAG_subprogram DIEs that are inside
1440 // of a normal or inlined functions. These will be
1441 // parsed on their own as separate entities.
1442
1443 if (depth > 0)
1444 break;
1445
1446 block = parent_block;
1447 }
1448 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001449 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001450 BlockSP block_sp(new Block (MakeUserID(die->GetOffset())));
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001451 parent_block->AddChild(block_sp);
1452 block = block_sp.get();
1453 }
Greg Claytondd7feaf2011-08-12 17:54:33 +00001454 DWARFDebugRanges::RangeList ranges;
1455 const char *name = NULL;
1456 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001457
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001458 int decl_file = 0;
1459 int decl_line = 0;
1460 int decl_column = 0;
1461 int call_file = 0;
1462 int call_line = 0;
1463 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001464 if (die->GetDIENamesAndRanges (this,
1465 dwarf_cu,
1466 name,
1467 mangled_name,
1468 ranges,
1469 decl_file, decl_line, decl_column,
1470 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001471 {
1472 if (tag == DW_TAG_subprogram)
1473 {
1474 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
Greg Claytonea3e7d52011-10-08 00:49:15 +00001475 subprogram_low_pc = ranges.GetMinRangeBase(0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001476 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001477 else if (tag == DW_TAG_inlined_subroutine)
1478 {
1479 // We get called here for inlined subroutines in two ways.
1480 // The first time is when we are making the Function object
1481 // for this inlined concrete instance. Since we're creating a top level block at
1482 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1483 // adjust the containing address.
1484 // The second time is when we are parsing the blocks inside the function that contains
1485 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1486 // function the offset will be for that function.
1487 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1488 {
Greg Claytonea3e7d52011-10-08 00:49:15 +00001489 subprogram_low_pc = ranges.GetMinRangeBase(0);
Jim Inghamb0be4422010-08-12 01:20:14 +00001490 }
1491 }
Greg Clayton103f3092015-01-15 03:04:37 +00001492
1493 const size_t num_ranges = ranges.GetSize();
1494 for (size_t i = 0; i<num_ranges; ++i)
1495 {
1496 const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
1497 const addr_t range_base = range.GetRangeBase();
1498 if (range_base >= subprogram_low_pc)
1499 block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
1500 else
1501 {
1502 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",
1503 block->GetID(),
1504 range_base,
1505 range.GetRangeEnd(),
1506 subprogram_low_pc);
1507 }
1508 }
1509 block->FinalizeRanges ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001510
1511 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1512 {
Greg Clayton7b0992d2013-04-18 22:45:39 +00001513 std::unique_ptr<Declaration> decl_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001514 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001515 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1516 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001517
Greg Clayton7b0992d2013-04-18 22:45:39 +00001518 std::unique_ptr<Declaration> call_ap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001519 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001520 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1521 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001522
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001523 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001524 }
1525
1526 ++blocks_added;
1527
Greg Claytondd7feaf2011-08-12 17:54:33 +00001528 if (die->HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001529 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001530 blocks_added += ParseFunctionBlocks (sc,
1531 block,
1532 dwarf_cu,
1533 die->GetFirstChild(),
1534 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001535 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001536 }
1537 }
1538 }
1539 break;
1540 default:
1541 break;
1542 }
1543
Greg Claytondd7feaf2011-08-12 17:54:33 +00001544 // Only parse siblings of the block if we are not at depth zero. A depth
1545 // of zero indicates we are currently parsing the top level
1546 // DW_TAG_subprogram DIE
1547
1548 if (depth == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001549 die = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001550 else
1551 die = die->GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001552 }
1553 return blocks_added;
1554}
1555
Greg Claytonf0705c82011-10-22 03:33:13 +00001556bool
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001557SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu,
1558 const DWARFDebugInfoEntry *die,
1559 ClangASTContext::TemplateParameterInfos &template_param_infos)
1560{
1561 const dw_tag_t tag = die->Tag();
1562
1563 switch (tag)
1564 {
1565 case DW_TAG_template_type_parameter:
1566 case DW_TAG_template_value_parameter:
1567 {
Todd Fialaee8bfc62014-09-11 17:29:12 +00001568 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001569
1570 DWARFDebugInfoEntry::Attributes attributes;
1571 const size_t num_attributes = die->GetAttributes (this,
1572 dwarf_cu,
1573 fixed_form_sizes,
1574 attributes);
1575 const char *name = NULL;
1576 Type *lldb_type = NULL;
Greg Clayton57ee3062013-07-11 22:46:58 +00001577 ClangASTType clang_type;
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001578 uint64_t uval64 = 0;
1579 bool uval64_valid = false;
1580 if (num_attributes > 0)
1581 {
1582 DWARFFormValue form_value;
1583 for (size_t i=0; i<num_attributes; ++i)
1584 {
1585 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1586
1587 switch (attr)
1588 {
1589 case DW_AT_name:
1590 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1591 name = form_value.AsCString(&get_debug_str_data());
1592 break;
1593
1594 case DW_AT_type:
1595 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1596 {
Greg Clayton54166af2014-11-22 01:58:59 +00001597 const dw_offset_t type_die_offset = form_value.Reference();
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001598 lldb_type = ResolveTypeUID(type_die_offset);
1599 if (lldb_type)
1600 clang_type = lldb_type->GetClangForwardType();
1601 }
1602 break;
1603
1604 case DW_AT_const_value:
1605 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1606 {
1607 uval64_valid = true;
1608 uval64 = form_value.Unsigned();
1609 }
1610 break;
1611 default:
1612 break;
1613 }
1614 }
1615
Greg Clayton283b2652013-04-23 22:38:02 +00001616 clang::ASTContext *ast = GetClangASTContext().getASTContext();
1617 if (!clang_type)
Greg Clayton57ee3062013-07-11 22:46:58 +00001618 clang_type = GetClangASTContext().GetBasicType(eBasicTypeVoid);
Greg Clayton283b2652013-04-23 22:38:02 +00001619
1620 if (clang_type)
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001621 {
1622 bool is_signed = false;
Greg Clayton283b2652013-04-23 22:38:02 +00001623 if (name && name[0])
1624 template_param_infos.names.push_back(name);
1625 else
1626 template_param_infos.names.push_back(NULL);
1627
Greg Clayton283b2652013-04-23 22:38:02 +00001628 if (tag == DW_TAG_template_value_parameter &&
1629 lldb_type != NULL &&
Greg Clayton57ee3062013-07-11 22:46:58 +00001630 clang_type.IsIntegerType (is_signed) &&
Greg Clayton283b2652013-04-23 22:38:02 +00001631 uval64_valid)
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001632 {
1633 llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
Greg Clayton283b2652013-04-23 22:38:02 +00001634 template_param_infos.args.push_back (clang::TemplateArgument (*ast,
Sean Callanan3d654b32012-09-24 22:25:51 +00001635 llvm::APSInt(apint),
Pavel Labathc7c30eb2015-06-08 23:38:06 +00001636 clang_type.GetQualType()));
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001637 }
1638 else
1639 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00001640 template_param_infos.args.push_back (clang::TemplateArgument (clang_type.GetQualType()));
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001641 }
1642 }
1643 else
1644 {
1645 return false;
1646 }
1647
1648 }
1649 }
1650 return true;
1651
1652 default:
1653 break;
1654 }
1655 return false;
1656}
1657
1658bool
Greg Claytonf0705c82011-10-22 03:33:13 +00001659SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
1660 const DWARFDebugInfoEntry *parent_die,
1661 ClangASTContext::TemplateParameterInfos &template_param_infos)
1662{
1663
1664 if (parent_die == NULL)
Filipe Cabecinhas52008c62012-05-23 16:24:11 +00001665 return false;
Greg Claytonf0705c82011-10-22 03:33:13 +00001666
Greg Claytonf0705c82011-10-22 03:33:13 +00001667 Args template_parameter_names;
1668 for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild();
1669 die != NULL;
1670 die = die->GetSibling())
1671 {
1672 const dw_tag_t tag = die->Tag();
1673
1674 switch (tag)
1675 {
1676 case DW_TAG_template_type_parameter:
1677 case DW_TAG_template_value_parameter:
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00001678 ParseTemplateDIE (dwarf_cu, die, template_param_infos);
Greg Claytonf0705c82011-10-22 03:33:13 +00001679 break;
1680
1681 default:
1682 break;
1683 }
1684 }
1685 if (template_param_infos.args.empty())
1686 return false;
1687 return template_param_infos.args.size() == template_param_infos.names.size();
1688}
1689
1690clang::ClassTemplateDecl *
1691SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00001692 lldb::AccessType access_type,
Greg Claytonf0705c82011-10-22 03:33:13 +00001693 const char *parent_name,
1694 int tag_decl_kind,
1695 const ClangASTContext::TemplateParameterInfos &template_param_infos)
1696{
1697 if (template_param_infos.IsValid())
1698 {
1699 std::string template_basename(parent_name);
1700 template_basename.erase (template_basename.find('<'));
1701 ClangASTContext &ast = GetClangASTContext();
1702
1703 return ast.CreateClassTemplateDecl (decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00001704 access_type,
Greg Claytonf0705c82011-10-22 03:33:13 +00001705 template_basename.c_str(),
1706 tag_decl_kind,
1707 template_param_infos);
1708 }
1709 return NULL;
1710}
1711
Sean Callanana0b80ab2012-06-04 22:28:05 +00001712class SymbolFileDWARF::DelayedAddObjCClassProperty
1713{
1714public:
1715 DelayedAddObjCClassProperty
1716 (
Greg Clayton57ee3062013-07-11 22:46:58 +00001717 const ClangASTType &class_opaque_type,
Sean Callanana0b80ab2012-06-04 22:28:05 +00001718 const char *property_name,
Greg Clayton57ee3062013-07-11 22:46:58 +00001719 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 +00001720 clang::ObjCIvarDecl *ivar_decl,
1721 const char *property_setter_name,
1722 const char *property_getter_name,
1723 uint32_t property_attributes,
Greg Claytonc4ffd662013-03-08 01:37:30 +00001724 const ClangASTMetadata *metadata
Sean Callanana0b80ab2012-06-04 22:28:05 +00001725 ) :
Sean Callanana0b80ab2012-06-04 22:28:05 +00001726 m_class_opaque_type (class_opaque_type),
1727 m_property_name (property_name),
1728 m_property_opaque_type (property_opaque_type),
1729 m_ivar_decl (ivar_decl),
1730 m_property_setter_name (property_setter_name),
1731 m_property_getter_name (property_getter_name),
Jim Ingham379397632012-10-27 02:54:13 +00001732 m_property_attributes (property_attributes)
Sean Callanana0b80ab2012-06-04 22:28:05 +00001733 {
Jim Ingham379397632012-10-27 02:54:13 +00001734 if (metadata != NULL)
1735 {
1736 m_metadata_ap.reset(new ClangASTMetadata());
Greg Claytonc4ffd662013-03-08 01:37:30 +00001737 *m_metadata_ap = *metadata;
Jim Ingham379397632012-10-27 02:54:13 +00001738 }
1739 }
1740
1741 DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
1742 {
Greg Clayton57ee3062013-07-11 22:46:58 +00001743 *this = rhs;
Daniel Malead4c5be62012-11-12 21:02:14 +00001744 }
1745
1746 DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
1747 {
Jim Ingham379397632012-10-27 02:54:13 +00001748 m_class_opaque_type = rhs.m_class_opaque_type;
1749 m_property_name = rhs.m_property_name;
1750 m_property_opaque_type = rhs.m_property_opaque_type;
1751 m_ivar_decl = rhs.m_ivar_decl;
1752 m_property_setter_name = rhs.m_property_setter_name;
1753 m_property_getter_name = rhs.m_property_getter_name;
1754 m_property_attributes = rhs.m_property_attributes;
1755
1756 if (rhs.m_metadata_ap.get())
1757 {
1758 m_metadata_ap.reset (new ClangASTMetadata());
Greg Claytonc4ffd662013-03-08 01:37:30 +00001759 *m_metadata_ap = *rhs.m_metadata_ap;
Jim Ingham379397632012-10-27 02:54:13 +00001760 }
Daniel Malead4c5be62012-11-12 21:02:14 +00001761 return *this;
Sean Callanana0b80ab2012-06-04 22:28:05 +00001762 }
1763
Greg Clayton57ee3062013-07-11 22:46:58 +00001764 bool
1765 Finalize()
Sean Callanana0b80ab2012-06-04 22:28:05 +00001766 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00001767 return m_class_opaque_type.AddObjCClassProperty (m_property_name,
1768 m_property_opaque_type,
1769 m_ivar_decl,
1770 m_property_setter_name,
1771 m_property_getter_name,
1772 m_property_attributes,
1773 m_metadata_ap.get());
Sean Callanana0b80ab2012-06-04 22:28:05 +00001774 }
1775private:
Greg Clayton57ee3062013-07-11 22:46:58 +00001776 ClangASTType m_class_opaque_type;
Sean Callanana0b80ab2012-06-04 22:28:05 +00001777 const char *m_property_name;
Greg Clayton57ee3062013-07-11 22:46:58 +00001778 ClangASTType m_property_opaque_type;
Sean Callanana0b80ab2012-06-04 22:28:05 +00001779 clang::ObjCIvarDecl *m_ivar_decl;
1780 const char *m_property_setter_name;
1781 const char *m_property_getter_name;
1782 uint32_t m_property_attributes;
Greg Clayton7b0992d2013-04-18 22:45:39 +00001783 std::unique_ptr<ClangASTMetadata> m_metadata_ap;
Sean Callanana0b80ab2012-06-04 22:28:05 +00001784};
1785
Sean Callananfaa0bb32012-12-05 23:37:14 +00001786struct BitfieldInfo
1787{
1788 uint64_t bit_size;
1789 uint64_t bit_offset;
1790
1791 BitfieldInfo () :
1792 bit_size (LLDB_INVALID_ADDRESS),
1793 bit_offset (LLDB_INVALID_ADDRESS)
1794 {
1795 }
1796
Greg Clayton78f4d952013-12-11 23:10:39 +00001797 void
1798 Clear()
1799 {
1800 bit_size = LLDB_INVALID_ADDRESS;
1801 bit_offset = LLDB_INVALID_ADDRESS;
1802 }
1803
Sean Callananfaa0bb32012-12-05 23:37:14 +00001804 bool IsValid ()
1805 {
1806 return (bit_size != LLDB_INVALID_ADDRESS) &&
1807 (bit_offset != LLDB_INVALID_ADDRESS);
1808 }
1809};
1810
Greg Claytonc4ffd662013-03-08 01:37:30 +00001811
1812bool
1813SymbolFileDWARF::ClassOrStructIsVirtual (DWARFCompileUnit* dwarf_cu,
1814 const DWARFDebugInfoEntry *parent_die)
1815{
1816 if (parent_die)
1817 {
1818 for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1819 {
1820 dw_tag_t tag = die->Tag();
1821 bool check_virtuality = false;
1822 switch (tag)
1823 {
1824 case DW_TAG_inheritance:
1825 case DW_TAG_subprogram:
1826 check_virtuality = true;
1827 break;
1828 default:
1829 break;
1830 }
1831 if (check_virtuality)
1832 {
1833 if (die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_virtuality, 0) != 0)
1834 return true;
1835 }
1836 }
1837 }
1838 return false;
1839}
1840
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001841size_t
1842SymbolFileDWARF::ParseChildMembers
1843(
1844 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001845 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001846 const DWARFDebugInfoEntry *parent_die,
Greg Clayton57ee3062013-07-11 22:46:58 +00001847 ClangASTType &class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001848 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001849 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1850 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001851 DWARFDIECollection& member_function_dies,
Sean Callanana0b80ab2012-06-04 22:28:05 +00001852 DelayedPropertyList& delayed_properties,
Sean Callananc7fbf732010-08-06 00:32:49 +00001853 AccessType& default_accessibility,
Greg Claytoncaab74e2012-01-28 00:48:57 +00001854 bool &is_a_class,
1855 LayoutInfo &layout_info
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001856)
1857{
1858 if (parent_die == NULL)
1859 return 0;
1860
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001861 size_t count = 0;
1862 const DWARFDebugInfoEntry *die;
Todd Fialaee8bfc62014-09-11 17:29:12 +00001863 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001864 uint32_t member_idx = 0;
Sean Callananfaa0bb32012-12-05 23:37:14 +00001865 BitfieldInfo last_field_info;
Richard Mitton0a558352013-10-17 21:14:00 +00001866 ModuleSP module = GetObjectFile()->GetModule();
Greg Claytond88d7592010-09-15 08:33:30 +00001867
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001868 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1869 {
1870 dw_tag_t tag = die->Tag();
1871
1872 switch (tag)
1873 {
1874 case DW_TAG_member:
Sean Callanan3d654b32012-09-24 22:25:51 +00001875 case DW_TAG_APPLE_property:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001876 {
1877 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001878 const size_t num_attributes = die->GetAttributes (this,
1879 dwarf_cu,
1880 fixed_form_sizes,
1881 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001882 if (num_attributes > 0)
1883 {
1884 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001885 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001886 const char *name = NULL;
Jim Inghame3ae82a2011-11-12 01:36:43 +00001887 const char *prop_name = NULL;
1888 const char *prop_getter_name = NULL;
1889 const char *prop_setter_name = NULL;
Greg Claytone528efd72013-02-26 23:45:18 +00001890 uint32_t prop_attributes = 0;
Jim Inghame3ae82a2011-11-12 01:36:43 +00001891
1892
Greg Clayton24739922010-10-13 03:15:28 +00001893 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001894 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001895 AccessType accessibility = eAccessNone;
Greg Claytoncaab74e2012-01-28 00:48:57 +00001896 uint32_t member_byte_offset = UINT32_MAX;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001897 size_t byte_size = 0;
1898 size_t bit_offset = 0;
1899 size_t bit_size = 0;
Greg Claytone528efd72013-02-26 23:45:18 +00001900 bool is_external = false; // On DW_TAG_members, this means the member is static
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001901 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001902 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001903 {
1904 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1905 DWARFFormValue form_value;
1906 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1907 {
1908 switch (attr)
1909 {
1910 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1911 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1912 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1913 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00001914 case DW_AT_type: encoding_uid = form_value.Reference(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001915 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1916 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1917 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1918 case DW_AT_data_member_location:
Greg Claytoncaab74e2012-01-28 00:48:57 +00001919 if (form_value.BlockData())
1920 {
1921 Value initialValue(0);
1922 Value memberOffset(0);
Ed Masteeeae7212013-10-24 20:43:47 +00001923 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Claytoncaab74e2012-01-28 00:48:57 +00001924 uint32_t block_length = form_value.Unsigned();
1925 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1926 if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
Greg Claytoncaab74e2012-01-28 00:48:57 +00001927 NULL, // ClangExpressionVariableList *
1928 NULL, // ClangExpressionDeclMap *
1929 NULL, // RegisterContext *
Richard Mitton0a558352013-10-17 21:14:00 +00001930 module,
Greg Claytoncaab74e2012-01-28 00:48:57 +00001931 debug_info_data,
1932 block_offset,
1933 block_length,
1934 eRegisterKindDWARF,
1935 &initialValue,
1936 memberOffset,
1937 NULL))
1938 {
Greg Clayton57ee3062013-07-11 22:46:58 +00001939 member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
Greg Claytoncaab74e2012-01-28 00:48:57 +00001940 }
1941 }
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00001942 else
1943 {
1944 // With DWARF 3 and later, if the value is an integer constant,
1945 // this form value is the offset in bytes from the beginning
1946 // of the containing entity.
1947 member_byte_offset = form_value.Unsigned();
1948 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001949 break;
1950
Greg Clayton8cf05932010-07-22 18:30:50 +00001951 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00001952 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Jim Inghame3ae82a2011-11-12 01:36:43 +00001953 case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(&get_debug_str_data()); break;
1954 case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
1955 case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
1956 case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00001957 case DW_AT_external: is_external = form_value.Boolean(); break;
Jim Inghame3ae82a2011-11-12 01:36:43 +00001958
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001959 default:
Greg Clayton1b02c172012-03-14 21:00:47 +00001960 case DW_AT_declaration:
1961 case DW_AT_description:
1962 case DW_AT_mutable:
1963 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001964 case DW_AT_sibling:
1965 break;
1966 }
1967 }
1968 }
Sean Callanana6582262012-04-05 00:12:52 +00001969
1970 if (prop_name)
Sean Callanan751aac62012-03-29 19:07:06 +00001971 {
Sean Callanana6582262012-04-05 00:12:52 +00001972 ConstString fixed_getter;
1973 ConstString fixed_setter;
1974
1975 // Check if the property getter/setter were provided as full
1976 // names. We want basenames, so we extract them.
1977
1978 if (prop_getter_name && prop_getter_name[0] == '-')
1979 {
Greg Clayton1b3815c2013-01-30 00:18:29 +00001980 ObjCLanguageRuntime::MethodName prop_getter_method(prop_getter_name, true);
1981 prop_getter_name = prop_getter_method.GetSelector().GetCString();
Sean Callanana6582262012-04-05 00:12:52 +00001982 }
1983
1984 if (prop_setter_name && prop_setter_name[0] == '-')
1985 {
Greg Clayton1b3815c2013-01-30 00:18:29 +00001986 ObjCLanguageRuntime::MethodName prop_setter_method(prop_setter_name, true);
1987 prop_setter_name = prop_setter_method.GetSelector().GetCString();
Sean Callanana6582262012-04-05 00:12:52 +00001988 }
1989
1990 // If the names haven't been provided, they need to be
1991 // filled in.
1992
1993 if (!prop_getter_name)
1994 {
1995 prop_getter_name = prop_name;
1996 }
1997 if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly))
1998 {
1999 StreamString ss;
2000
2001 ss.Printf("set%c%s:",
2002 toupper(prop_name[0]),
2003 &prop_name[1]);
2004
2005 fixed_setter.SetCString(ss.GetData());
2006 prop_setter_name = fixed_setter.GetCString();
2007 }
Sean Callanan751aac62012-03-29 19:07:06 +00002008 }
2009
2010 // Clang has a DWARF generation bug where sometimes it
Greg Clayton44953932011-10-25 01:25:35 +00002011 // represents fields that are references with bad byte size
2012 // and bit size/offset information such as:
2013 //
2014 // DW_AT_byte_size( 0x00 )
2015 // DW_AT_bit_size( 0x40 )
2016 // DW_AT_bit_offset( 0xffffffffffffffc0 )
2017 //
2018 // So check the bit offset to make sure it is sane, and if
2019 // the values are not sane, remove them. If we don't do this
2020 // then we will end up with a crash if we try to use this
2021 // type in an expression when clang becomes unhappy with its
2022 // recycled debug info.
Sean Callanan5a477cf2010-10-30 01:56:10 +00002023
Greg Clayton44953932011-10-25 01:25:35 +00002024 if (bit_offset > 128)
2025 {
2026 bit_size = 0;
2027 bit_offset = 0;
2028 }
2029
2030 // FIXME: Make Clang ignore Objective-C accessibility for expressions
Sean Callanan5a477cf2010-10-30 01:56:10 +00002031 if (class_language == eLanguageTypeObjC ||
2032 class_language == eLanguageTypeObjC_plus_plus)
2033 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00002034
2035 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
2036 {
2037 // Not all compilers will mark the vtable pointer
2038 // member as artificial (llvm-gcc). We can't have
2039 // the virtual members in our classes otherwise it
2040 // throws off all child offsets since we end up
2041 // having and extra pointer sized member in our
2042 // class layouts.
2043 is_artificial = true;
2044 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002045
Greg Clayton29659712013-07-12 20:08:35 +00002046 // Handle static members
Greg Claytone528efd72013-02-26 23:45:18 +00002047 if (is_external && member_byte_offset == UINT32_MAX)
Greg Clayton973b6c92013-04-11 16:57:51 +00002048 {
2049 Type *var_type = ResolveTypeUID(encoding_uid);
2050
2051 if (var_type)
2052 {
Greg Clayton29659712013-07-12 20:08:35 +00002053 if (accessibility == eAccessNone)
2054 accessibility = eAccessPublic;
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002055 class_clang_type.AddVariableToRecordType (name,
Greg Clayton57ee3062013-07-11 22:46:58 +00002056 var_type->GetClangLayoutType(),
2057 accessibility);
Greg Clayton973b6c92013-04-11 16:57:51 +00002058 }
Greg Claytone528efd72013-02-26 23:45:18 +00002059 break;
Greg Clayton973b6c92013-04-11 16:57:51 +00002060 }
Greg Claytone528efd72013-02-26 23:45:18 +00002061
Greg Clayton24739922010-10-13 03:15:28 +00002062 if (is_artificial == false)
2063 {
2064 Type *member_type = ResolveTypeUID(encoding_uid);
Sean Callananfa3ab452012-12-14 00:54:13 +00002065
Jim Inghame3ae82a2011-11-12 01:36:43 +00002066 clang::FieldDecl *field_decl = NULL;
Sean Callanan751aac62012-03-29 19:07:06 +00002067 if (tag == DW_TAG_member)
Greg Claytond16e1e52011-07-12 17:06:17 +00002068 {
Sean Callanan751aac62012-03-29 19:07:06 +00002069 if (member_type)
2070 {
2071 if (accessibility == eAccessNone)
2072 accessibility = default_accessibility;
2073 member_accessibilities.push_back(accessibility);
Sean Callananfaa0bb32012-12-05 23:37:14 +00002074
Greg Clayton78f4d952013-12-11 23:10:39 +00002075 uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
2076 if (bit_size > 0)
Greg Clayton88bc7f32012-11-06 00:20:41 +00002077 {
Greg Clayton78f4d952013-12-11 23:10:39 +00002078
2079 BitfieldInfo this_field_info;
2080 this_field_info.bit_offset = field_bit_offset;
2081 this_field_info.bit_size = bit_size;
2082
Sean Callananfaa0bb32012-12-05 23:37:14 +00002083 /////////////////////////////////////////////////////////////
2084 // How to locate a field given the DWARF debug information
2085 //
2086 // AT_byte_size indicates the size of the word in which the
2087 // bit offset must be interpreted.
2088 //
2089 // AT_data_member_location indicates the byte offset of the
2090 // word from the base address of the structure.
2091 //
2092 // AT_bit_offset indicates how many bits into the word
2093 // (according to the host endianness) the low-order bit of
2094 // the field starts. AT_bit_offset can be negative.
2095 //
2096 // AT_bit_size indicates the size of the field in bits.
2097 /////////////////////////////////////////////////////////////
2098
Greg Clayton78f4d952013-12-11 23:10:39 +00002099 if (byte_size == 0)
2100 byte_size = member_type->GetByteSize();
2101
Sean Callananfaa0bb32012-12-05 23:37:14 +00002102 if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
2103 {
2104 this_field_info.bit_offset += byte_size * 8;
2105 this_field_info.bit_offset -= (bit_offset + bit_size);
2106 }
2107 else
2108 {
2109 this_field_info.bit_offset += bit_offset;
2110 }
Greg Clayton78f4d952013-12-11 23:10:39 +00002111
2112 // Update the field bit offset we will report for layout
2113 field_bit_offset = this_field_info.bit_offset;
Sean Callananfaa0bb32012-12-05 23:37:14 +00002114
Greg Clayton78f4d952013-12-11 23:10:39 +00002115 // If the member to be emitted did not start on a character boundary and there is
2116 // empty space between the last field and this one, then we need to emit an
2117 // anonymous member filling up the space up to its start. There are three cases
2118 // here:
2119 //
2120 // 1 If the previous member ended on a character boundary, then we can emit an
2121 // anonymous member starting at the most recent character boundary.
2122 //
2123 // 2 If the previous member did not end on a character boundary and the distance
2124 // from the end of the previous member to the current member is less than a
2125 // word width, then we can emit an anonymous member starting right after the
2126 // previous member and right before this member.
2127 //
2128 // 3 If the previous member did not end on a character boundary and the distance
2129 // from the end of the previous member to the current member is greater than
2130 // or equal a word width, then we act as in Case 1.
2131
2132 const uint64_t character_width = 8;
2133 const uint64_t word_width = 32;
2134
Sean Callananfaa0bb32012-12-05 23:37:14 +00002135 // Objective-C has invalid DW_AT_bit_offset values in older versions
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +00002136 // of clang, so we have to be careful and only insert unnamed bitfields
Greg Clayton37c36e42012-11-27 00:59:26 +00002137 // if we have a new enough clang.
2138 bool detect_unnamed_bitfields = true;
Greg Clayton88bc7f32012-11-06 00:20:41 +00002139
Greg Clayton37c36e42012-11-27 00:59:26 +00002140 if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)
2141 detect_unnamed_bitfields = dwarf_cu->Supports_unnamed_objc_bitfields ();
2142
2143 if (detect_unnamed_bitfields)
Greg Clayton88bc7f32012-11-06 00:20:41 +00002144 {
Sean Callananfaa0bb32012-12-05 23:37:14 +00002145 BitfieldInfo anon_field_info;
2146
2147 if ((this_field_info.bit_offset % character_width) != 0) // not char aligned
Greg Clayton88bc7f32012-11-06 00:20:41 +00002148 {
Sean Callananfaa0bb32012-12-05 23:37:14 +00002149 uint64_t last_field_end = 0;
Greg Clayton88bc7f32012-11-06 00:20:41 +00002150
Sean Callananfaa0bb32012-12-05 23:37:14 +00002151 if (last_field_info.IsValid())
2152 last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
Greg Clayton88bc7f32012-11-06 00:20:41 +00002153
Sean Callananfaa0bb32012-12-05 23:37:14 +00002154 if (this_field_info.bit_offset != last_field_end)
2155 {
2156 if (((last_field_end % character_width) == 0) || // case 1
2157 (this_field_info.bit_offset - last_field_end >= word_width)) // case 3
2158 {
2159 anon_field_info.bit_size = this_field_info.bit_offset % character_width;
2160 anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size;
2161 }
2162 else // case 2
2163 {
2164 anon_field_info.bit_size = this_field_info.bit_offset - last_field_end;
2165 anon_field_info.bit_offset = last_field_end;
2166 }
Greg Clayton88bc7f32012-11-06 00:20:41 +00002167 }
Greg Clayton88bc7f32012-11-06 00:20:41 +00002168 }
2169
Sean Callananfaa0bb32012-12-05 23:37:14 +00002170 if (anon_field_info.IsValid())
Greg Clayton88bc7f32012-11-06 00:20:41 +00002171 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002172 clang::FieldDecl *unnamed_bitfield_decl = class_clang_type.AddFieldToRecordType (NULL,
2173 GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
2174 accessibility,
2175 anon_field_info.bit_size);
Zachary Turner504f38d2015-03-24 16:24:50 +00002176
Zachary Turnera98fac22015-03-24 18:56:08 +00002177 layout_info.field_offsets.insert(
Zachary Turner504f38d2015-03-24 16:24:50 +00002178 std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
Greg Clayton88bc7f32012-11-06 00:20:41 +00002179 }
2180 }
Greg Clayton78f4d952013-12-11 23:10:39 +00002181 last_field_info = this_field_info;
2182 }
2183 else
2184 {
2185 last_field_info.Clear();
Greg Clayton88bc7f32012-11-06 00:20:41 +00002186 }
Sean Callananfaa0bb32012-12-05 23:37:14 +00002187
Greg Clayton57ee3062013-07-11 22:46:58 +00002188 ClangASTType member_clang_type = member_type->GetClangLayoutType();
Sean Callananfa3ab452012-12-14 00:54:13 +00002189
2190 {
2191 // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
2192 // If the current field is at the end of the structure, then there is definitely no room for extra
2193 // elements and we override the type to array[0].
2194
Greg Clayton57ee3062013-07-11 22:46:58 +00002195 ClangASTType member_array_element_type;
Sean Callananfa3ab452012-12-14 00:54:13 +00002196 uint64_t member_array_size;
2197 bool member_array_is_incomplete;
2198
Greg Clayton57ee3062013-07-11 22:46:58 +00002199 if (member_clang_type.IsArrayType(&member_array_element_type,
2200 &member_array_size,
2201 &member_array_is_incomplete) &&
Sean Callananfa3ab452012-12-14 00:54:13 +00002202 !member_array_is_incomplete)
2203 {
2204 uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX);
2205
2206 if (member_byte_offset >= parent_byte_size)
2207 {
2208 if (member_array_size != 1)
2209 {
2210 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,
2211 MakeUserID(die->GetOffset()),
2212 name,
2213 encoding_uid,
2214 MakeUserID(parent_die->GetOffset()));
2215 }
2216
Greg Clayton1c8ef472013-04-05 23:27:21 +00002217 member_clang_type = GetClangASTContext().CreateArrayType(member_array_element_type, 0, false);
Sean Callananfa3ab452012-12-14 00:54:13 +00002218 }
2219 }
2220 }
2221
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002222 field_decl = class_clang_type.AddFieldToRecordType (name,
Greg Clayton57ee3062013-07-11 22:46:58 +00002223 member_clang_type,
2224 accessibility,
2225 bit_size);
Sean Callanan60217122012-04-13 00:10:03 +00002226
Greg Claytond0029442013-03-27 01:48:02 +00002227 GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset()));
Greg Clayton78f4d952013-12-11 23:10:39 +00002228
Zachary Turnera98fac22015-03-24 18:56:08 +00002229 layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset));
Sean Callanan5b26f272012-02-04 08:49:35 +00002230 }
2231 else
2232 {
Sean Callanan751aac62012-03-29 19:07:06 +00002233 if (name)
Daniel Malead01b2952012-11-29 21:49:15 +00002234 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 +00002235 MakeUserID(die->GetOffset()),
2236 name,
2237 encoding_uid);
2238 else
Daniel Malead01b2952012-11-29 21:49:15 +00002239 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 +00002240 MakeUserID(die->GetOffset()),
2241 encoding_uid);
Sean Callanan5b26f272012-02-04 08:49:35 +00002242 }
Greg Claytoncaab74e2012-01-28 00:48:57 +00002243 }
Sean Callanan751aac62012-03-29 19:07:06 +00002244
Greg Clayton3ca8f422015-07-13 22:08:16 +00002245 if (prop_name != NULL && member_type)
Jim Inghame3ae82a2011-11-12 01:36:43 +00002246 {
Sean Callanan751aac62012-03-29 19:07:06 +00002247 clang::ObjCIvarDecl *ivar_decl = NULL;
Jim Inghame3ae82a2011-11-12 01:36:43 +00002248
Sean Callanan751aac62012-03-29 19:07:06 +00002249 if (field_decl)
2250 {
2251 ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
2252 assert (ivar_decl != NULL);
2253 }
Jim Inghame3ae82a2011-11-12 01:36:43 +00002254
Jim Ingham379397632012-10-27 02:54:13 +00002255 ClangASTMetadata metadata;
2256 metadata.SetUserID (MakeUserID(die->GetOffset()));
Greg Clayton57ee3062013-07-11 22:46:58 +00002257 delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type,
Sean Callanana0b80ab2012-06-04 22:28:05 +00002258 prop_name,
2259 member_type->GetClangLayoutType(),
2260 ivar_decl,
2261 prop_setter_name,
2262 prop_getter_name,
2263 prop_attributes,
Jim Ingham379397632012-10-27 02:54:13 +00002264 &metadata));
Sean Callanan60217122012-04-13 00:10:03 +00002265
Sean Callananad880762012-04-18 01:06:17 +00002266 if (ivar_decl)
Greg Claytond0029442013-03-27 01:48:02 +00002267 GetClangASTContext().SetMetadataAsUserID (ivar_decl, MakeUserID(die->GetOffset()));
Jim Inghame3ae82a2011-11-12 01:36:43 +00002268 }
Greg Clayton24739922010-10-13 03:15:28 +00002269 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002270 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00002271 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002272 }
2273 break;
2274
2275 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00002276 // Let the type parsing code handle this one for us.
2277 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002278 break;
2279
2280 case DW_TAG_inheritance:
2281 {
2282 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00002283 if (default_accessibility == eAccessNone)
2284 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002285 // TODO: implement DW_TAG_inheritance type parsing
2286 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00002287 const size_t num_attributes = die->GetAttributes (this,
2288 dwarf_cu,
2289 fixed_form_sizes,
2290 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002291 if (num_attributes > 0)
2292 {
2293 Declaration decl;
2294 DWARFExpression location;
2295 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00002296 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002297 bool is_virtual = false;
2298 bool is_base_of_class = true;
Greg Clayton2508b9b2012-11-01 23:20:02 +00002299 off_t member_byte_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002300 uint32_t i;
2301 for (i=0; i<num_attributes; ++i)
2302 {
2303 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2304 DWARFFormValue form_value;
2305 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2306 {
2307 switch (attr)
2308 {
2309 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2310 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2311 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00002312 case DW_AT_type: encoding_uid = form_value.Reference(); break;
Greg Clayton2508b9b2012-11-01 23:20:02 +00002313 case DW_AT_data_member_location:
2314 if (form_value.BlockData())
2315 {
2316 Value initialValue(0);
2317 Value memberOffset(0);
Ed Masteeeae7212013-10-24 20:43:47 +00002318 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Clayton2508b9b2012-11-01 23:20:02 +00002319 uint32_t block_length = form_value.Unsigned();
2320 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
2321 if (DWARFExpression::Evaluate (NULL,
2322 NULL,
2323 NULL,
Greg Clayton2508b9b2012-11-01 23:20:02 +00002324 NULL,
Richard Mitton0a558352013-10-17 21:14:00 +00002325 module,
Greg Clayton2508b9b2012-11-01 23:20:02 +00002326 debug_info_data,
2327 block_offset,
2328 block_length,
2329 eRegisterKindDWARF,
2330 &initialValue,
2331 memberOffset,
2332 NULL))
2333 {
Greg Clayton57ee3062013-07-11 22:46:58 +00002334 member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
Greg Clayton2508b9b2012-11-01 23:20:02 +00002335 }
2336 }
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00002337 else
2338 {
2339 // With DWARF 3 and later, if the value is an integer constant,
2340 // this form value is the offset in bytes from the beginning
2341 // of the containing entity.
2342 member_byte_offset = form_value.Unsigned();
2343 }
Greg Clayton2508b9b2012-11-01 23:20:02 +00002344 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002345
2346 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00002347 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002348 break;
2349
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00002350 case DW_AT_virtuality:
2351 is_virtual = form_value.Boolean();
2352 break;
2353
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002354 case DW_AT_sibling:
2355 break;
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00002356
2357 default:
2358 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002359 }
2360 }
2361 }
2362
Greg Clayton526e5af2010-11-13 03:52:47 +00002363 Type *base_class_type = ResolveTypeUID(encoding_uid);
Greg Clayton898c1b22015-05-15 22:31:18 +00002364 if (base_class_type == NULL)
2365 {
Bruce Mitchener58ef3912015-06-18 05:27:05 +00002366 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 +00002367 die->GetOffset(),
2368 encoding_uid,
2369 parent_die->GetOffset());
2370 break;
2371 }
2372
Greg Clayton57ee3062013-07-11 22:46:58 +00002373 ClangASTType base_class_clang_type = base_class_type->GetClangFullType();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00002374 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00002375 if (class_language == eLanguageTypeObjC)
2376 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002377 class_clang_type.SetObjCSuperClass(base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00002378 }
2379 else
2380 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002381 base_classes.push_back (base_class_clang_type.CreateBaseClassSpecifier (accessibility,
2382 is_virtual,
2383 is_base_of_class));
Greg Clayton2508b9b2012-11-01 23:20:02 +00002384
2385 if (is_virtual)
2386 {
Greg Clayton52694e32013-09-16 21:57:07 +00002387 // Do not specify any offset for virtual inheritance. The DWARF produced by clang doesn't
2388 // give us a constant offset, but gives us a DWARF expressions that requires an actual object
2389 // in memory. the DW_AT_data_member_location for a virtual base class looks like:
2390 // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, DW_OP_plus )
2391 // Given this, there is really no valid response we can give to clang for virtual base
2392 // class offsets, and this should eventually be removed from LayoutRecordType() in the external
2393 // AST source in clang.
Greg Clayton2508b9b2012-11-01 23:20:02 +00002394 }
2395 else
2396 {
Zachary Turnera98fac22015-03-24 18:56:08 +00002397 layout_info.base_offsets.insert(
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002398 std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(),
Zachary Turner504f38d2015-03-24 16:24:50 +00002399 clang::CharUnits::fromQuantity(member_byte_offset)));
Greg Clayton2508b9b2012-11-01 23:20:02 +00002400 }
Greg Clayton9e409562010-07-28 02:04:09 +00002401 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002402 }
2403 }
2404 break;
2405
2406 default:
2407 break;
2408 }
2409 }
Sean Callanana0b80ab2012-06-04 22:28:05 +00002410
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002411 return count;
2412}
2413
2414
2415clang::DeclContext*
Sean Callanan72e49402011-08-05 23:43:37 +00002416SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002417{
2418 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton81c22f62011-10-19 18:09:39 +00002419 if (debug_info && UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002420 {
2421 DWARFCompileUnitSP cu_sp;
2422 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
2423 if (die)
Greg Claytoncb5860a2011-10-13 23:49:28 +00002424 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
Sean Callanan72e49402011-08-05 23:43:37 +00002425 }
2426 return NULL;
2427}
2428
2429clang::DeclContext*
2430SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
2431{
Greg Clayton81c22f62011-10-19 18:09:39 +00002432 if (UserIDMatches(type_uid))
2433 return GetClangDeclContextForDIEOffset (sc, type_uid);
2434 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002435}
2436
2437Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00002438SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002439{
Greg Clayton81c22f62011-10-19 18:09:39 +00002440 if (UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002441 {
Greg Clayton81c22f62011-10-19 18:09:39 +00002442 DWARFDebugInfo* debug_info = DebugInfo();
2443 if (debug_info)
Greg Claytonca512b32011-01-14 04:54:56 +00002444 {
Greg Clayton81c22f62011-10-19 18:09:39 +00002445 DWARFCompileUnitSP cu_sp;
2446 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Greg Claytoncab36a32011-12-08 05:16:30 +00002447 const bool assert_not_being_parsed = true;
2448 return ResolveTypeUID (cu_sp.get(), type_die, assert_not_being_parsed);
Greg Claytonca512b32011-01-14 04:54:56 +00002449 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002450 }
2451 return NULL;
2452}
2453
Greg Claytoncab36a32011-12-08 05:16:30 +00002454Type*
2455SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed)
Sean Callanan5b26f272012-02-04 08:49:35 +00002456{
Greg Claytoncab36a32011-12-08 05:16:30 +00002457 if (die != NULL)
2458 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002459 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00002460 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002461 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002462 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
2463 die->GetOffset(),
2464 DW_TAG_value_to_name(die->Tag()),
2465 die->GetName(this, cu));
Greg Clayton3bffb082011-12-10 02:15:28 +00002466
Greg Claytoncab36a32011-12-08 05:16:30 +00002467 // We might be coming in in the middle of a type tree (a class
2468 // withing a class, an enum within a class), so parse any needed
2469 // parent DIEs before we get to this one...
2470 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
2471 switch (decl_ctx_die->Tag())
2472 {
2473 case DW_TAG_structure_type:
2474 case DW_TAG_union_type:
2475 case DW_TAG_class_type:
2476 {
2477 // Get the type, which could be a forward declaration
Greg Clayton3bffb082011-12-10 02:15:28 +00002478 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002479 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00002480 "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
2481 die->GetOffset(),
2482 DW_TAG_value_to_name(die->Tag()),
2483 die->GetName(this, cu),
2484 decl_ctx_die->GetOffset());
Greg Clayton219cf312012-03-30 00:51:13 +00002485//
2486// Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
2487// if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
2488// {
2489// if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002490// GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton219cf312012-03-30 00:51:13 +00002491// "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function",
2492// die->GetOffset(),
2493// DW_TAG_value_to_name(die->Tag()),
2494// die->GetName(this, cu),
2495// decl_ctx_die->GetOffset());
2496// // Ask the type to complete itself if it already hasn't since if we
2497// // want a function (method or static) from a class, the class must
2498// // create itself and add it's own methods and class functions.
2499// if (parent_type)
2500// parent_type->GetClangFullType();
2501// }
Greg Claytoncab36a32011-12-08 05:16:30 +00002502 }
2503 break;
2504
2505 default:
2506 break;
2507 }
2508 return ResolveType (cu, die);
2509 }
2510 return NULL;
2511}
2512
Greg Clayton6beaaa62011-01-17 03:46:26 +00002513// This function is used when SymbolFileDWARFDebugMap owns a bunch of
2514// SymbolFileDWARF objects to detect if this DWARF file is the one that
2515// can resolve a clang_type.
2516bool
Greg Clayton57ee3062013-07-11 22:46:58 +00002517SymbolFileDWARF::HasForwardDeclForClangType (const ClangASTType &clang_type)
Greg Clayton6beaaa62011-01-17 03:46:26 +00002518{
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002519 ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
Greg Clayton57ee3062013-07-11 22:46:58 +00002520 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
Greg Clayton6beaaa62011-01-17 03:46:26 +00002521 return die != NULL;
2522}
2523
2524
Greg Clayton57ee3062013-07-11 22:46:58 +00002525bool
2526SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00002527{
2528 // We have a struct/union/class/enum that needs to be fully resolved.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002529 ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
Greg Clayton57ee3062013-07-11 22:46:58 +00002530 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
Greg Clayton1be10fc2010-09-29 01:12:09 +00002531 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00002532 {
2533 // We have already resolved this type...
Greg Clayton57ee3062013-07-11 22:46:58 +00002534 return true;
Greg Clayton73b472d2010-10-27 03:32:59 +00002535 }
2536 // Once we start resolving this type, remove it from the forward declaration
2537 // map in case anyone child members or other types require this type to get resolved.
2538 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
2539 // are done.
Greg Clayton57ee3062013-07-11 22:46:58 +00002540 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType());
Greg Clayton1be10fc2010-09-29 01:12:09 +00002541
Greg Clayton85ae2e12011-10-18 23:36:41 +00002542 // Disable external storage for this type so we don't get anymore
2543 // clang::ExternalASTSource queries for this type.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002544 clang_type.SetHasExternalStorage (false);
Greg Clayton85ae2e12011-10-18 23:36:41 +00002545
Greg Clayton450e3f32010-10-12 02:24:53 +00002546 DWARFDebugInfo* debug_info = DebugInfo();
2547
Greg Clayton53eb1c22012-04-02 22:59:12 +00002548 DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002549 Type *type = m_die_to_type.lookup (die);
2550
2551 const dw_tag_t tag = die->Tag();
2552
Greg Clayton5160ce52013-03-27 23:08:40 +00002553 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
Greg Clayton3bffb082011-12-10 02:15:28 +00002554 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00002555 GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
Daniel Malead01b2952012-11-29 21:49:15 +00002556 "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
Greg Claytond61c0fc2012-04-23 22:55:20 +00002557 MakeUserID(die->GetOffset()),
2558 DW_TAG_value_to_name(tag),
2559 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00002560 assert (clang_type);
2561 DWARFDebugInfoEntry::Attributes attributes;
2562
Greg Clayton1be10fc2010-09-29 01:12:09 +00002563 switch (tag)
2564 {
2565 case DW_TAG_structure_type:
2566 case DW_TAG_union_type:
2567 case DW_TAG_class_type:
Greg Claytonc93237c2010-10-01 20:48:32 +00002568 {
Greg Claytoncaab74e2012-01-28 00:48:57 +00002569 LayoutInfo layout_info;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002570
Greg Clayton1be10fc2010-09-29 01:12:09 +00002571 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002572 if (die->HasChildren())
Greg Claytonc93237c2010-10-01 20:48:32 +00002573 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002574 LanguageType class_language = eLanguageTypeUnknown;
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002575 if (clang_type.IsObjCObjectOrInterfaceType())
Greg Clayton219cf312012-03-30 00:51:13 +00002576 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002577 class_language = eLanguageTypeObjC;
Greg Clayton219cf312012-03-30 00:51:13 +00002578 // For objective C we don't start the definition when
2579 // the class is created.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002580 clang_type.StartTagDeclarationDefinition ();
Greg Clayton219cf312012-03-30 00:51:13 +00002581 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002582
Sean Callanan77a1fd32012-02-27 20:07:01 +00002583 int tag_decl_kind = -1;
2584 AccessType default_accessibility = eAccessNone;
2585 if (tag == DW_TAG_structure_type)
2586 {
2587 tag_decl_kind = clang::TTK_Struct;
2588 default_accessibility = eAccessPublic;
2589 }
2590 else if (tag == DW_TAG_union_type)
2591 {
2592 tag_decl_kind = clang::TTK_Union;
2593 default_accessibility = eAccessPublic;
2594 }
2595 else if (tag == DW_TAG_class_type)
2596 {
2597 tag_decl_kind = clang::TTK_Class;
2598 default_accessibility = eAccessPrivate;
2599 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002600
Greg Clayton53eb1c22012-04-02 22:59:12 +00002601 SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
Sean Callanan77a1fd32012-02-27 20:07:01 +00002602 std::vector<clang::CXXBaseSpecifier *> base_classes;
2603 std::vector<int> member_accessibilities;
2604 bool is_a_class = false;
2605 // Parse members and base classes first
2606 DWARFDIECollection member_function_dies;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002607
Sean Callanana0b80ab2012-06-04 22:28:05 +00002608 DelayedPropertyList delayed_properties;
Greg Clayton88bc7f32012-11-06 00:20:41 +00002609 ParseChildMembers (sc,
Greg Clayton53eb1c22012-04-02 22:59:12 +00002610 dwarf_cu,
Sean Callanan77a1fd32012-02-27 20:07:01 +00002611 die,
2612 clang_type,
2613 class_language,
2614 base_classes,
2615 member_accessibilities,
2616 member_function_dies,
Sean Callanana0b80ab2012-06-04 22:28:05 +00002617 delayed_properties,
Sean Callanan77a1fd32012-02-27 20:07:01 +00002618 default_accessibility,
2619 is_a_class,
2620 layout_info);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002621
Sean Callanan77a1fd32012-02-27 20:07:01 +00002622 // Now parse any methods if there were any...
2623 size_t num_functions = member_function_dies.Size();
2624 if (num_functions > 0)
2625 {
2626 for (size_t i=0; i<num_functions; ++i)
Greg Claytond4a2b372011-09-12 23:21:58 +00002627 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00002628 ResolveType(dwarf_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytoncaab74e2012-01-28 00:48:57 +00002629 }
Sean Callanan77a1fd32012-02-27 20:07:01 +00002630 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002631
Sean Callanan77a1fd32012-02-27 20:07:01 +00002632 if (class_language == eLanguageTypeObjC)
2633 {
Jim Inghamfb6fc0d2013-09-27 20:59:37 +00002634 ConstString class_name (clang_type.GetTypeName());
2635 if (class_name)
Greg Claytoncaab74e2012-01-28 00:48:57 +00002636 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002637 DIEArray method_die_offsets;
2638 if (m_using_apple_tables)
Greg Clayton95d87902011-11-11 03:16:25 +00002639 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002640 if (m_apple_objc_ap.get())
Jim Inghamfb6fc0d2013-09-27 20:59:37 +00002641 m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
Sean Callanan77a1fd32012-02-27 20:07:01 +00002642 }
2643 else
2644 {
2645 if (!m_indexed)
2646 Index ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002647
Sean Callanan77a1fd32012-02-27 20:07:01 +00002648 m_objc_class_selectors_index.Find (class_name, method_die_offsets);
2649 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002650
Sean Callanan77a1fd32012-02-27 20:07:01 +00002651 if (!method_die_offsets.empty())
2652 {
2653 DWARFDebugInfo* debug_info = DebugInfo();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002654
Sean Callanan77a1fd32012-02-27 20:07:01 +00002655 DWARFCompileUnit* method_cu = NULL;
2656 const size_t num_matches = method_die_offsets.size();
2657 for (size_t i=0; i<num_matches; ++i)
Greg Clayton95d87902011-11-11 03:16:25 +00002658 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002659 const dw_offset_t die_offset = method_die_offsets[i];
2660 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002661
Sean Callanan77a1fd32012-02-27 20:07:01 +00002662 if (method_die)
2663 ResolveType (method_cu, method_die);
2664 else
Greg Claytoncaab74e2012-01-28 00:48:57 +00002665 {
Sean Callanan77a1fd32012-02-27 20:07:01 +00002666 if (m_using_apple_tables)
2667 {
2668 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 +00002669 die_offset, class_name.GetCString());
Sean Callanan77a1fd32012-02-27 20:07:01 +00002670 }
2671 }
2672 }
Greg Claytoncaab74e2012-01-28 00:48:57 +00002673 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002674
Greg Clayton57ee3062013-07-11 22:46:58 +00002675 for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
Sean Callanana0b80ab2012-06-04 22:28:05 +00002676 pi != pe;
2677 ++pi)
2678 pi->Finalize();
Greg Clayton450e3f32010-10-12 02:24:53 +00002679 }
2680 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002681
Sean Callanan77a1fd32012-02-27 20:07:01 +00002682 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2683 // need to tell the clang type it is actually a class.
2684 if (class_language != eLanguageTypeObjC)
2685 {
2686 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002687 clang_type.SetTagTypeKind (clang::TTK_Class);
Sean Callanan77a1fd32012-02-27 20:07:01 +00002688 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002689
Sean Callanan77a1fd32012-02-27 20:07:01 +00002690 // Since DW_TAG_structure_type gets used for both classes
2691 // and structures, we may need to set any DW_TAG_member
2692 // fields to have a "private" access if none was specified.
2693 // When we parsed the child members we tracked that actual
2694 // accessibility value for each DW_TAG_member in the
2695 // "member_accessibilities" array. If the value for the
2696 // member is zero, then it was set to the "default_accessibility"
2697 // which for structs was "public". Below we correct this
2698 // by setting any fields to "private" that weren't correctly
2699 // set.
2700 if (is_a_class && !member_accessibilities.empty())
2701 {
2702 // This is a class and all members that didn't have
2703 // their access specified are private.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002704 clang_type.SetDefaultAccessForRecordFields (eAccessPrivate,
2705 &member_accessibilities.front(),
2706 member_accessibilities.size());
Sean Callanan77a1fd32012-02-27 20:07:01 +00002707 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002708
Sean Callanan77a1fd32012-02-27 20:07:01 +00002709 if (!base_classes.empty())
2710 {
Greg Clayton4705f8d2013-12-12 01:54:04 +00002711 // Make sure all base classes refer to complete types and not
2712 // forward declarations. If we don't do this, clang will crash
2713 // with an assertion in the call to clang_type.SetBaseClassesForClassType()
2714 bool base_class_error = false;
2715 for (auto &base_class : base_classes)
2716 {
2717 clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo();
2718 if (type_source_info)
2719 {
2720 ClangASTType base_class_type (GetClangASTContext().getASTContext(), type_source_info->getType());
2721 if (base_class_type.GetCompleteType() == false)
2722 {
2723 if (!base_class_error)
2724 {
2725 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",
2726 die->GetOffset(),
2727 die->GetName(this, dwarf_cu),
2728 base_class_type.GetTypeName().GetCString(),
2729 sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
2730 }
2731 // We have no choice other than to pretend that the base class
2732 // is complete. If we don't do this, clang will crash when we
2733 // call setBases() inside of "clang_type.SetBaseClassesForClassType()"
2734 // below. Since we provide layout assistance, all ivars in this
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00002735 // class and other classes will be fine, this is the best we can do
Greg Clayton4705f8d2013-12-12 01:54:04 +00002736 // short of crashing.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002737 base_class_type.StartTagDeclarationDefinition ();
2738 base_class_type.CompleteTagDeclarationDefinition ();
Greg Clayton4705f8d2013-12-12 01:54:04 +00002739 }
2740 }
2741 }
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002742 clang_type.SetBaseClassesForClassType (&base_classes.front(),
2743 base_classes.size());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002744
Sean Callanan77a1fd32012-02-27 20:07:01 +00002745 // Clang will copy each CXXBaseSpecifier in "base_classes"
2746 // so we have to free them all.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002747 ClangASTType::DeleteBaseClassSpecifiers (&base_classes.front(),
2748 base_classes.size());
Sean Callanan77a1fd32012-02-27 20:07:01 +00002749 }
Greg Clayton450e3f32010-10-12 02:24:53 +00002750 }
Greg Claytonc93237c2010-10-01 20:48:32 +00002751 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002752
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002753 clang_type.BuildIndirectFields ();
2754 clang_type.CompleteTagDeclarationDefinition ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002755
Greg Clayton2508b9b2012-11-01 23:20:02 +00002756 if (!layout_info.field_offsets.empty() ||
2757 !layout_info.base_offsets.empty() ||
2758 !layout_info.vbase_offsets.empty() )
Greg Claytoncaab74e2012-01-28 00:48:57 +00002759 {
2760 if (type)
2761 layout_info.bit_size = type->GetByteSize() * 8;
2762 if (layout_info.bit_size == 0)
Greg Clayton53eb1c22012-04-02 22:59:12 +00002763 layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002764
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002765 clang::CXXRecordDecl *record_decl = clang_type.GetAsCXXRecordDecl();
Greg Clayton2508b9b2012-11-01 23:20:02 +00002766 if (record_decl)
Greg Claytoncaab74e2012-01-28 00:48:57 +00002767 {
Greg Claytoncaab74e2012-01-28 00:48:57 +00002768 if (log)
Greg Clayton821ac6d2012-01-28 02:22:27 +00002769 {
Greg Clayton5160ce52013-03-27 23:08:40 +00002770 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00002771 "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 +00002772 static_cast<void*>(clang_type.GetOpaqueQualType()),
2773 static_cast<void*>(record_decl),
Greg Claytoncaab74e2012-01-28 00:48:57 +00002774 layout_info.bit_size,
2775 layout_info.alignment,
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002776 static_cast<uint32_t>(layout_info.field_offsets.size()),
2777 static_cast<uint32_t>(layout_info.base_offsets.size()),
2778 static_cast<uint32_t>(layout_info.vbase_offsets.size()));
2779
Zachary Turnera98fac22015-03-24 18:56:08 +00002780 uint32_t idx;
2781 {
2782 llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos,
2783 end = layout_info.field_offsets.end();
2784 for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx)
Greg Clayton2508b9b2012-11-01 23:20:02 +00002785 {
Zachary Turner504f38d2015-03-24 16:24:50 +00002786 GetObjectFile()->GetModule()->LogMessage(
2787 log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = "
2788 "{ bit_offset=%u, name='%s' }",
Zachary Turner504f38d2015-03-24 16:24:50 +00002789 static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
Zachary Turnera98fac22015-03-24 18:56:08 +00002790 static_cast<uint32_t>(pos->second), pos->first->getNameAsString().c_str());
2791 }
2792 }
2793
2794 {
2795 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos,
2796 base_end = layout_info.base_offsets.end();
2797 for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end;
2798 ++base_pos, ++idx)
2799 {
2800 GetObjectFile()->GetModule()->LogMessage(
2801 log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] "
2802 "= { byte_offset=%u, name='%s' }",
2803 clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(),
2804 base_pos->first->getNameAsString().c_str());
2805 }
2806 }
2807 {
2808 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos,
2809 vbase_end = layout_info.vbase_offsets.end();
2810 for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end;
2811 ++vbase_pos, ++idx)
2812 {
2813 GetObjectFile()->GetModule()->LogMessage(
2814 log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) "
2815 "vbase[%u] = { byte_offset=%u, name='%s' }",
2816 static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
2817 static_cast<uint32_t>(vbase_pos->second.getQuantity()),
2818 vbase_pos->first->getNameAsString().c_str());
2819 }
Greg Clayton2508b9b2012-11-01 23:20:02 +00002820 }
Greg Clayton821ac6d2012-01-28 02:22:27 +00002821 }
Greg Claytoncaab74e2012-01-28 00:48:57 +00002822 m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
2823 }
2824 }
Greg Claytonc93237c2010-10-01 20:48:32 +00002825 }
Sean Callanan77a1fd32012-02-27 20:07:01 +00002826
Sean Callanan9076c0f2013-10-04 21:35:29 +00002827 return (bool)clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002828
2829 case DW_TAG_enumeration_type:
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002830 clang_type.StartTagDeclarationDefinition ();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002831 if (die->HasChildren())
2832 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00002833 SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
Greg Clayton3e067532013-03-05 23:54:39 +00002834 bool is_signed = false;
Greg Clayton57ee3062013-07-11 22:46:58 +00002835 clang_type.IsIntegerType(is_signed);
Greg Clayton3e067532013-03-05 23:54:39 +00002836 ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002837 }
Pavel Labathc7c30eb2015-06-08 23:38:06 +00002838 clang_type.CompleteTagDeclarationDefinition ();
Sean Callanan9076c0f2013-10-04 21:35:29 +00002839 return (bool)clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002840
2841 default:
2842 assert(false && "not a forward clang type decl!");
2843 break;
2844 }
Ashok Thirumurthia4658a52013-07-30 14:58:39 +00002845 return false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002846}
2847
Greg Claytonc685f8e2010-09-15 04:15:46 +00002848Type*
Greg Clayton53eb1c22012-04-02 22:59:12 +00002849SymbolFileDWARF::ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002850{
2851 if (type_die != NULL)
2852 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002853 Type *type = m_die_to_type.lookup (type_die);
Greg Claytoncab36a32011-12-08 05:16:30 +00002854
Greg Claytonc685f8e2010-09-15 04:15:46 +00002855 if (type == NULL)
Greg Clayton53eb1c22012-04-02 22:59:12 +00002856 type = GetTypeForDIE (dwarf_cu, type_die).get();
Greg Claytoncab36a32011-12-08 05:16:30 +00002857
Greg Clayton24739922010-10-13 03:15:28 +00002858 if (assert_not_being_parsed)
Jim Inghamc3549282012-01-11 02:21:12 +00002859 {
2860 if (type != DIE_IS_BEING_PARSED)
2861 return type;
2862
2863 GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
Greg Clayton53eb1c22012-04-02 22:59:12 +00002864 type_die->GetOffset(),
2865 DW_TAG_value_to_name(type_die->Tag()),
2866 type_die->GetName(this, dwarf_cu));
Jim Inghamc3549282012-01-11 02:21:12 +00002867
2868 }
2869 else
2870 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002871 }
2872 return NULL;
2873}
2874
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002875CompileUnit*
Greg Clayton53eb1c22012-04-02 22:59:12 +00002876SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002877{
2878 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton53eb1c22012-04-02 22:59:12 +00002879 if (dwarf_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002880 {
2881 // The symbol vendor doesn't know about this compile unit, we
2882 // need to parse and add it to the symbol vendor object.
Greg Clayton53eb1c22012-04-02 22:59:12 +00002883 return ParseCompileUnit(dwarf_cu, cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002884 }
Greg Clayton53eb1c22012-04-02 22:59:12 +00002885 return (CompileUnit*)dwarf_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002886}
2887
2888bool
Greg Clayton53eb1c22012-04-02 22:59:12 +00002889SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002890{
Greg Clayton72310352013-02-23 04:12:47 +00002891 sc.Clear(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002892 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton53eb1c22012-04-02 22:59:12 +00002893 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002894
Greg Clayton81c22f62011-10-19 18:09:39 +00002895 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002896 if (sc.function == NULL)
Greg Clayton53eb1c22012-04-02 22:59:12 +00002897 sc.function = ParseCompileUnitFunction(sc, dwarf_cu, func_die);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002898
2899 if (sc.function)
2900 {
Greg Claytone72dfb32012-02-24 01:59:29 +00002901 sc.module_sp = sc.function->CalculateSymbolContextModule();
Jim Ingham4cda6e02011-10-07 22:23:45 +00002902 return true;
2903 }
2904
2905 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002906}
2907
Sean Callananf0c5aeb2015-04-20 16:31:29 +00002908void
2909SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
2910{
2911 if (m_fetched_external_modules)
2912 return;
2913 m_fetched_external_modules = true;
2914
2915 DWARFDebugInfo * debug_info = DebugInfo();
2916 debug_info->GetNumCompileUnits();
2917
2918 const uint32_t num_compile_units = GetNumCompileUnits();
2919 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2920 {
2921 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
2922
2923 const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
2924 if (die && die->HasChildren() == false)
2925 {
2926 const uint64_t name_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_name, UINT64_MAX);
2927 const uint64_t dwo_path_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_GNU_dwo_name, UINT64_MAX);
2928
2929 if (name_strp != UINT64_MAX)
2930 {
2931 if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
2932 {
2933 const char *name = get_debug_str_data().PeekCStr(name_strp);
2934 const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);
2935 if (name || dwo_path)
2936 {
2937 ModuleSP module_sp;
2938 if (dwo_path)
2939 {
2940 ModuleSpec dwo_module_spec;
2941 dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
2942 dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
2943 //printf ("Loading dwo = '%s'\n", dwo_path);
2944 Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
2945 }
2946
2947 if (dwo_path_strp != LLDB_INVALID_UID)
2948 {
2949 m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };
2950 }
2951 else
2952 {
2953 // This hack should be removed promptly once clang emits both.
2954 m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };
2955 }
2956 }
2957 }
2958 }
2959 }
2960 }
2961}
Greg Clayton2501e5e2015-01-15 02:59:20 +00002962
2963SymbolFileDWARF::GlobalVariableMap &
2964SymbolFileDWARF::GetGlobalAranges()
2965{
2966 if (!m_global_aranges_ap)
2967 {
2968 m_global_aranges_ap.reset (new GlobalVariableMap());
2969
2970 ModuleSP module_sp = GetObjectFile()->GetModule();
2971 if (module_sp)
2972 {
2973 const size_t num_cus = module_sp->GetNumCompileUnits();
2974 for (size_t i = 0; i < num_cus; ++i)
2975 {
2976 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
2977 if (cu_sp)
2978 {
2979 VariableListSP globals_sp = cu_sp->GetVariableList(true);
2980 if (globals_sp)
2981 {
2982 const size_t num_globals = globals_sp->GetSize();
2983 for (size_t g = 0; g < num_globals; ++g)
2984 {
2985 VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
2986 if (var_sp && !var_sp->GetLocationIsConstantValueData())
2987 {
2988 const DWARFExpression &location = var_sp->LocationExpression();
2989 Value location_result;
2990 Error error;
2991 if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
2992 {
2993 if (location_result.GetValueType() == Value::eValueTypeFileAddress)
2994 {
2995 lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
2996 lldb::addr_t byte_size = 1;
2997 if (var_sp->GetType())
2998 byte_size = var_sp->GetType()->GetByteSize();
2999 m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
3000 }
3001 }
3002 }
3003 }
3004 }
3005 }
3006 }
3007 }
3008 m_global_aranges_ap->Sort();
3009 }
3010 return *m_global_aranges_ap;
3011}
3012
3013
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003014uint32_t
3015SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
3016{
3017 Timer scoped_timer(__PRETTY_FUNCTION__,
Daniel Malead01b2952012-11-29 21:49:15 +00003018 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003019 static_cast<void*>(so_addr.GetSection().get()),
3020 so_addr.GetOffset(), resolve_scope);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003021 uint32_t resolved = 0;
Greg Clayton2501e5e2015-01-15 02:59:20 +00003022 if (resolve_scope & ( eSymbolContextCompUnit |
3023 eSymbolContextFunction |
3024 eSymbolContextBlock |
3025 eSymbolContextLineEntry |
3026 eSymbolContextVariable ))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003027 {
3028 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
3029
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003030 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00003031 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003032 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003033 const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Greg Clayton2501e5e2015-01-15 02:59:20 +00003034 if (cu_offset == DW_INVALID_OFFSET)
3035 {
3036 // Global variables are not in the compile unit address ranges. The only way to
3037 // currently find global variables is to iterate over the .debug_pubnames or the
3038 // __apple_names table and find all items in there that point to DW_TAG_variable
3039 // DIEs and then find the address that matches.
3040 if (resolve_scope & eSymbolContextVariable)
3041 {
3042 GlobalVariableMap &map = GetGlobalAranges();
3043 const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
3044 if (entry && entry->data)
3045 {
3046 Variable *variable = entry->data;
3047 SymbolContextScope *scc = variable->GetSymbolContextScope();
3048 if (scc)
3049 {
3050 scc->CalculateSymbolContext(&sc);
3051 sc.variable = variable;
3052 }
3053 return sc.GetResolvedMask();
3054 }
3055 }
3056 }
3057 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003058 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003059 uint32_t cu_idx = DW_INVALID_INDEX;
Greg Clayton53eb1c22012-04-02 22:59:12 +00003060 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
3061 if (dwarf_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003062 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003063 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00003064 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003065 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003066 resolved |= eSymbolContextCompUnit;
3067
Greg Clayton6ab80132012-12-12 17:30:52 +00003068 bool force_check_line_table = false;
Greg Clayton526a4ae2012-05-16 22:09:01 +00003069 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
3070 {
3071 DWARFDebugInfoEntry *function_die = NULL;
3072 DWARFDebugInfoEntry *block_die = NULL;
3073 if (resolve_scope & eSymbolContextBlock)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003074 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003075 dwarf_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
3076 }
3077 else
3078 {
3079 dwarf_cu->LookupAddress(file_vm_addr, &function_die, NULL);
3080 }
3081
3082 if (function_die != NULL)
3083 {
3084 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
3085 if (sc.function == NULL)
3086 sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
3087 }
3088 else
3089 {
3090 // We might have had a compile unit that had discontiguous
3091 // address ranges where the gaps are symbols that don't have
3092 // any debug info. Discontiguous compile unit address ranges
3093 // should only happen when there aren't other functions from
3094 // other compile units in these gaps. This helps keep the size
3095 // of the aranges down.
Greg Clayton6ab80132012-12-12 17:30:52 +00003096 force_check_line_table = true;
Greg Clayton526a4ae2012-05-16 22:09:01 +00003097 }
3098
3099 if (sc.function != NULL)
3100 {
3101 resolved |= eSymbolContextFunction;
3102
3103 if (resolve_scope & eSymbolContextBlock)
3104 {
3105 Block& block = sc.function->GetBlock (true);
3106
3107 if (block_die != NULL)
3108 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
3109 else
3110 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
3111 if (sc.block)
3112 resolved |= eSymbolContextBlock;
3113 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003114 }
3115 }
Greg Clayton6ab80132012-12-12 17:30:52 +00003116
3117 if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
3118 {
3119 LineTable *line_table = sc.comp_unit->GetLineTable();
3120 if (line_table != NULL)
3121 {
Greg Clayton9422dd62013-03-04 21:46:16 +00003122 // And address that makes it into this function should be in terms
3123 // of this debug file if there is no debug map, or it will be an
3124 // address in the .o file which needs to be fixed up to be in terms
3125 // of the debug map executable. Either way, calling FixupAddress()
3126 // will work for us.
3127 Address exe_so_addr (so_addr);
3128 if (FixupAddress(exe_so_addr))
Greg Clayton6ab80132012-12-12 17:30:52 +00003129 {
Greg Clayton9422dd62013-03-04 21:46:16 +00003130 if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
Greg Clayton6ab80132012-12-12 17:30:52 +00003131 {
3132 resolved |= eSymbolContextLineEntry;
3133 }
3134 }
Greg Clayton6ab80132012-12-12 17:30:52 +00003135 }
3136 }
3137
3138 if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
3139 {
3140 // We might have had a compile unit that had discontiguous
3141 // address ranges where the gaps are symbols that don't have
3142 // any debug info. Discontiguous compile unit address ranges
3143 // should only happen when there aren't other functions from
3144 // other compile units in these gaps. This helps keep the size
3145 // of the aranges down.
3146 sc.comp_unit = NULL;
3147 resolved &= ~eSymbolContextCompUnit;
3148 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003149 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00003150 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003151 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003152 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
3153 cu_offset,
3154 cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003155 }
3156 }
3157 }
3158 }
3159 }
3160 return resolved;
3161}
3162
3163
3164
3165uint32_t
3166SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
3167{
3168 const uint32_t prev_size = sc_list.GetSize();
3169 if (resolve_scope & eSymbolContextCompUnit)
3170 {
3171 DWARFDebugInfo* debug_info = DebugInfo();
3172 if (debug_info)
3173 {
3174 uint32_t cu_idx;
Greg Clayton53eb1c22012-04-02 22:59:12 +00003175 DWARFCompileUnit* dwarf_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003176
Greg Clayton53eb1c22012-04-02 22:59:12 +00003177 for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003178 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003179 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Sean Callananddd7a2a2013-10-03 22:27:29 +00003180 const bool full_match = (bool)file_spec.GetDirectory();
Greg Clayton1f746072012-08-29 21:13:06 +00003181 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 +00003182 if (check_inlines || file_spec_matches_cu_file_spec)
3183 {
3184 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton53eb1c22012-04-02 22:59:12 +00003185 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
Greg Clayton526a4ae2012-05-16 22:09:01 +00003186 if (sc.comp_unit)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003187 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003188 uint32_t file_idx = UINT32_MAX;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003189
Greg Clayton526a4ae2012-05-16 22:09:01 +00003190 // If we are looking for inline functions only and we don't
3191 // find it in the support files, we are done.
3192 if (check_inlines)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003193 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003194 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
3195 if (file_idx == UINT32_MAX)
3196 continue;
3197 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003198
Greg Clayton526a4ae2012-05-16 22:09:01 +00003199 if (line != 0)
3200 {
3201 LineTable *line_table = sc.comp_unit->GetLineTable();
3202
3203 if (line_table != NULL && line != 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003204 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003205 // We will have already looked up the file index if
3206 // we are searching for inline entries.
3207 if (!check_inlines)
3208 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003209
Greg Clayton526a4ae2012-05-16 22:09:01 +00003210 if (file_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003211 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003212 uint32_t found_line;
3213 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
3214 found_line = sc.line_entry.line;
3215
3216 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003217 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003218 sc.function = NULL;
3219 sc.block = NULL;
3220 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003221 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003222 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
3223 if (file_vm_addr != LLDB_INVALID_ADDRESS)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003224 {
Greg Clayton526a4ae2012-05-16 22:09:01 +00003225 DWARFDebugInfoEntry *function_die = NULL;
3226 DWARFDebugInfoEntry *block_die = NULL;
3227 dwarf_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003228
Greg Clayton526a4ae2012-05-16 22:09:01 +00003229 if (function_die != NULL)
3230 {
3231 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
3232 if (sc.function == NULL)
3233 sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
3234 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003235
Greg Clayton526a4ae2012-05-16 22:09:01 +00003236 if (sc.function != NULL)
3237 {
3238 Block& block = sc.function->GetBlock (true);
3239
3240 if (block_die != NULL)
3241 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
Jason Molenda60db6e42014-10-16 01:40:16 +00003242 else if (function_die != NULL)
Greg Clayton526a4ae2012-05-16 22:09:01 +00003243 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
3244 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003245 }
3246 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003247
Greg Clayton526a4ae2012-05-16 22:09:01 +00003248 sc_list.Append(sc);
3249 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
3250 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003251 }
3252 }
Greg Clayton526a4ae2012-05-16 22:09:01 +00003253 else if (file_spec_matches_cu_file_spec && !check_inlines)
3254 {
3255 // only append the context if we aren't looking for inline call sites
3256 // by file and line and if the file spec matches that of the compile unit
3257 sc_list.Append(sc);
3258 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003259 }
3260 else if (file_spec_matches_cu_file_spec && !check_inlines)
3261 {
3262 // only append the context if we aren't looking for inline call sites
3263 // by file and line and if the file spec matches that of the compile unit
3264 sc_list.Append(sc);
3265 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003266
Greg Clayton526a4ae2012-05-16 22:09:01 +00003267 if (!check_inlines)
3268 break;
3269 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003270 }
3271 }
3272 }
3273 }
3274 return sc_list.GetSize() - prev_size;
3275}
3276
3277void
3278SymbolFileDWARF::Index ()
3279{
3280 if (m_indexed)
3281 return;
3282 m_indexed = true;
3283 Timer scoped_timer (__PRETTY_FUNCTION__,
3284 "SymbolFileDWARF::Index (%s)",
Jim Ingham4af59612014-12-19 19:20:44 +00003285 GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003286
3287 DWARFDebugInfo* debug_info = DebugInfo();
3288 if (debug_info)
3289 {
3290 uint32_t cu_idx = 0;
3291 const uint32_t num_compile_units = GetNumCompileUnits();
3292 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
3293 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00003294 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003295
Greg Clayton53eb1c22012-04-02 22:59:12 +00003296 bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003297
Greg Clayton53eb1c22012-04-02 22:59:12 +00003298 dwarf_cu->Index (cu_idx,
3299 m_function_basename_index,
3300 m_function_fullname_index,
3301 m_function_method_index,
3302 m_function_selector_index,
3303 m_objc_class_selectors_index,
3304 m_global_index,
3305 m_type_index,
3306 m_namespace_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003307
3308 // Keep memory down by clearing DIEs if this generate function
3309 // caused them to be parsed
3310 if (clear_dies)
Greg Clayton53eb1c22012-04-02 22:59:12 +00003311 dwarf_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003312 }
3313
Greg Claytond4a2b372011-09-12 23:21:58 +00003314 m_function_basename_index.Finalize();
3315 m_function_fullname_index.Finalize();
3316 m_function_method_index.Finalize();
3317 m_function_selector_index.Finalize();
3318 m_objc_class_selectors_index.Finalize();
3319 m_global_index.Finalize();
3320 m_type_index.Finalize();
3321 m_namespace_index.Finalize();
Greg Claytonc685f8e2010-09-15 04:15:46 +00003322
Greg Clayton24739922010-10-13 03:15:28 +00003323#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00003324 StreamFile s(stdout, false);
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00003325 s.Printf ("DWARF index for '%s':",
3326 GetObjectFile()->GetFileSpec().GetPath().c_str());
Greg Claytonba2d22d2010-11-13 22:57:37 +00003327 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
3328 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
3329 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
3330 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
3331 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
3332 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00003333 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00003334 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00003335#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003336 }
3337}
Greg Claytonbfe3dd42011-10-13 00:00:53 +00003338
3339bool
3340SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl)
3341{
3342 if (namespace_decl == NULL)
3343 {
3344 // Invalid namespace decl which means we aren't matching only things
3345 // in this symbol file, so return true to indicate it matches this
3346 // symbol file.
3347 return true;
3348 }
3349
3350 clang::ASTContext *namespace_ast = namespace_decl->GetASTContext();
3351
3352 if (namespace_ast == NULL)
3353 return true; // No AST in the "namespace_decl", return true since it
3354 // could then match any symbol file, including this one
3355
3356 if (namespace_ast == GetClangASTContext().getASTContext())
3357 return true; // The ASTs match, return true
3358
3359 // The namespace AST was valid, and it does not match...
Greg Clayton5160ce52013-03-27 23:08:40 +00003360 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Sean Callananc41e68b2011-10-13 21:08:11 +00003361
3362 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003363 GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
Sean Callananc41e68b2011-10-13 21:08:11 +00003364
Greg Claytonbfe3dd42011-10-13 00:00:53 +00003365 return false;
3366}
3367
Greg Clayton2506a7a2011-10-12 23:34:26 +00003368bool
3369SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl,
3370 DWARFCompileUnit* cu,
3371 const DWARFDebugInfoEntry* die)
3372{
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +00003373 // No namespace specified, so the answer is
Greg Clayton2506a7a2011-10-12 23:34:26 +00003374 if (namespace_decl == NULL)
3375 return true;
Sean Callananebe60672011-10-13 21:50:33 +00003376
Greg Clayton5160ce52013-03-27 23:08:40 +00003377 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Claytonbfe3dd42011-10-13 00:00:53 +00003378
Greg Clayton437a1352012-04-09 22:43:43 +00003379 const DWARFDebugInfoEntry *decl_ctx_die = NULL;
3380 clang::DeclContext *die_clang_decl_ctx = GetClangDeclContextContainingDIE (cu, die, &decl_ctx_die);
Greg Clayton2506a7a2011-10-12 23:34:26 +00003381 if (decl_ctx_die)
Greg Clayton437a1352012-04-09 22:43:43 +00003382 {
Greg Clayton2506a7a2011-10-12 23:34:26 +00003383 clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl();
Greg Clayton437a1352012-04-09 22:43:43 +00003384
Greg Clayton2506a7a2011-10-12 23:34:26 +00003385 if (clang_namespace_decl)
3386 {
3387 if (decl_ctx_die->Tag() != DW_TAG_namespace)
Sean Callananebe60672011-10-13 21:50:33 +00003388 {
3389 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003390 GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent is not a namespace");
Greg Clayton2506a7a2011-10-12 23:34:26 +00003391 return false;
Sean Callananebe60672011-10-13 21:50:33 +00003392 }
3393
Greg Clayton437a1352012-04-09 22:43:43 +00003394 if (clang_namespace_decl == die_clang_decl_ctx)
3395 return true;
3396 else
Greg Clayton2506a7a2011-10-12 23:34:26 +00003397 return false;
Greg Clayton2506a7a2011-10-12 23:34:26 +00003398 }
3399 else
3400 {
3401 // We have a namespace_decl that was not NULL but it contained
3402 // a NULL "clang::NamespaceDecl", so this means the global namespace
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00003403 // So as long the contained decl context DIE isn't a namespace
Greg Clayton2506a7a2011-10-12 23:34:26 +00003404 // we should be ok.
3405 if (decl_ctx_die->Tag() != DW_TAG_namespace)
3406 return true;
3407 }
3408 }
Sean Callananebe60672011-10-13 21:50:33 +00003409
3410 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003411 GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent doesn't exist");
Sean Callananebe60672011-10-13 21:50:33 +00003412
Greg Clayton2506a7a2011-10-12 23:34:26 +00003413 return false;
3414}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003415uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +00003416SymbolFileDWARF::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 +00003417{
Greg Clayton5160ce52013-03-27 23:08:40 +00003418 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00003419
3420 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00003421 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003422 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables)",
3423 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003424 static_cast<const void*>(namespace_decl),
3425 append, max_matches);
3426
Sean Callanan213fdb82011-10-13 01:49:10 +00003427 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
Ed Maste4c24b122013-10-17 20:13:14 +00003428 return 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003429
Greg Claytonc685f8e2010-09-15 04:15:46 +00003430 DWARFDebugInfo* info = DebugInfo();
3431 if (info == NULL)
3432 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003433
3434 // If we aren't appending the results to this list, then clear the list
3435 if (!append)
3436 variables.Clear();
3437
3438 // Remember how many variables are in the list before we search in case
3439 // we are appending the results to a variable list.
3440 const uint32_t original_size = variables.GetSize();
3441
Greg Claytond4a2b372011-09-12 23:21:58 +00003442 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003443
Greg Clayton97fbc342011-10-20 22:30:33 +00003444 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003445 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003446 if (m_apple_names_ap.get())
3447 {
3448 const char *name_cstr = name.GetCString();
Jim Inghamfa39bb42014-10-25 00:33:55 +00003449 llvm::StringRef basename;
3450 llvm::StringRef context;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003451
Jim Inghamfa39bb42014-10-25 00:33:55 +00003452 if (!CPPLanguageRuntime::ExtractContextAndIdentifier(name_cstr, context, basename))
3453 basename = name_cstr;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003454
Jim Inghamfa39bb42014-10-25 00:33:55 +00003455 m_apple_names_ap->FindByName (basename.data(), die_offsets);
Greg Clayton97fbc342011-10-20 22:30:33 +00003456 }
Greg Clayton7f995132011-10-04 22:41:51 +00003457 }
3458 else
3459 {
3460 // Index the DWARF if we haven't already
3461 if (!m_indexed)
3462 Index ();
3463
3464 m_global_index.Find (name, die_offsets);
3465 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003466
Greg Clayton437a1352012-04-09 22:43:43 +00003467 const size_t num_die_matches = die_offsets.size();
3468 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003469 {
Greg Clayton7f995132011-10-04 22:41:51 +00003470 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00003471 sc.module_sp = m_obj_file->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00003472 assert (sc.module_sp);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003473
Greg Claytond4a2b372011-09-12 23:21:58 +00003474 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton7f995132011-10-04 22:41:51 +00003475 DWARFCompileUnit* dwarf_cu = NULL;
3476 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton437a1352012-04-09 22:43:43 +00003477 bool done = false;
3478 for (size_t i=0; i<num_die_matches && !done; ++i)
Greg Claytond4a2b372011-09-12 23:21:58 +00003479 {
3480 const dw_offset_t die_offset = die_offsets[i];
3481 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003482
Greg Clayton95d87902011-11-11 03:16:25 +00003483 if (die)
3484 {
Greg Clayton437a1352012-04-09 22:43:43 +00003485 switch (die->Tag())
3486 {
3487 default:
3488 case DW_TAG_subprogram:
3489 case DW_TAG_inlined_subroutine:
3490 case DW_TAG_try_block:
3491 case DW_TAG_catch_block:
3492 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003493
Greg Clayton437a1352012-04-09 22:43:43 +00003494 case DW_TAG_variable:
3495 {
3496 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003497
Greg Clayton437a1352012-04-09 22:43:43 +00003498 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3499 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003500
Greg Clayton437a1352012-04-09 22:43:43 +00003501 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003502
Greg Clayton437a1352012-04-09 22:43:43 +00003503 if (variables.GetSize() - original_size >= max_matches)
3504 done = true;
3505 }
3506 break;
3507 }
Greg Clayton95d87902011-11-11 03:16:25 +00003508 }
3509 else
3510 {
3511 if (m_using_apple_tables)
3512 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003513 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
3514 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00003515 }
3516 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003517 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003518 }
3519
3520 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00003521 const uint32_t num_matches = variables.GetSize() - original_size;
3522 if (log && num_matches > 0)
3523 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003524 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00003525 "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables) => %u",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003526 name.GetCString(),
3527 static_cast<const void*>(namespace_decl),
3528 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00003529 num_matches);
3530 }
3531 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003532}
3533
3534uint32_t
3535SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
3536{
Greg Clayton5160ce52013-03-27 23:08:40 +00003537 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003538
Greg Clayton21f2a492011-10-06 00:09:08 +00003539 if (log)
3540 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003541 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003542 "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003543 regex.GetText(), append,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003544 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00003545 }
3546
Greg Claytonc685f8e2010-09-15 04:15:46 +00003547 DWARFDebugInfo* info = DebugInfo();
3548 if (info == NULL)
3549 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003550
3551 // If we aren't appending the results to this list, then clear the list
3552 if (!append)
3553 variables.Clear();
3554
3555 // Remember how many variables are in the list before we search in case
3556 // we are appending the results to a variable list.
3557 const uint32_t original_size = variables.GetSize();
3558
Greg Clayton7f995132011-10-04 22:41:51 +00003559 DIEArray die_offsets;
3560
Greg Clayton97fbc342011-10-20 22:30:33 +00003561 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003562 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003563 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00003564 {
3565 DWARFMappedHash::DIEInfoArray hash_data_array;
3566 if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
3567 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
3568 }
Greg Clayton7f995132011-10-04 22:41:51 +00003569 }
3570 else
3571 {
3572 // Index the DWARF if we haven't already
3573 if (!m_indexed)
3574 Index ();
3575
3576 m_global_index.Find (regex, die_offsets);
3577 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003578
Greg Claytonc685f8e2010-09-15 04:15:46 +00003579 SymbolContext sc;
Greg Claytone72dfb32012-02-24 01:59:29 +00003580 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00003581 assert (sc.module_sp);
3582
Greg Claytond4a2b372011-09-12 23:21:58 +00003583 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00003584 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00003585 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003586 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003587 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003588 DWARFDebugInfo* debug_info = DebugInfo();
3589 for (size_t i=0; i<num_matches; ++i)
3590 {
3591 const dw_offset_t die_offset = die_offsets[i];
3592 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Greg Clayton95d87902011-11-11 03:16:25 +00003593
3594 if (die)
3595 {
3596 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003597
Greg Clayton95d87902011-11-11 03:16:25 +00003598 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003599
Greg Clayton95d87902011-11-11 03:16:25 +00003600 if (variables.GetSize() - original_size >= max_matches)
3601 break;
3602 }
3603 else
3604 {
3605 if (m_using_apple_tables)
3606 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003607 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
3608 die_offset, regex.GetText());
Greg Clayton95d87902011-11-11 03:16:25 +00003609 }
3610 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003611 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003612 }
3613
3614 // Return the number of variable that were appended to the list
3615 return variables.GetSize() - original_size;
3616}
3617
Greg Claytonaa044962011-10-13 00:59:38 +00003618
Jim Ingham4cda6e02011-10-07 22:23:45 +00003619bool
3620SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
3621 DWARFCompileUnit *&dwarf_cu,
Pavel Labatha73d6572015-03-13 10:22:00 +00003622 bool include_inlines,
Jim Ingham4cda6e02011-10-07 22:23:45 +00003623 SymbolContextList& sc_list)
Greg Clayton9e315582011-09-02 04:03:59 +00003624{
Greg Claytonaa044962011-10-13 00:59:38 +00003625 const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Pavel Labatha73d6572015-03-13 10:22:00 +00003626 return ResolveFunction (dwarf_cu, die, include_inlines, sc_list);
Greg Claytonaa044962011-10-13 00:59:38 +00003627}
3628
3629
3630bool
3631SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
3632 const DWARFDebugInfoEntry *die,
Pavel Labatha73d6572015-03-13 10:22:00 +00003633 bool include_inlines,
Greg Claytonaa044962011-10-13 00:59:38 +00003634 SymbolContextList& sc_list)
3635{
Greg Clayton9e315582011-09-02 04:03:59 +00003636 SymbolContext sc;
Greg Claytonaa044962011-10-13 00:59:38 +00003637
3638 if (die == NULL)
3639 return false;
3640
Jim Ingham4cda6e02011-10-07 22:23:45 +00003641 // If we were passed a die that is not a function, just return false...
Pavel Labatha73d6572015-03-13 10:22:00 +00003642 if (! (die->Tag() == DW_TAG_subprogram || (include_inlines && die->Tag() == DW_TAG_inlined_subroutine)))
Jim Ingham4cda6e02011-10-07 22:23:45 +00003643 return false;
3644
3645 const DWARFDebugInfoEntry* inlined_die = NULL;
3646 if (die->Tag() == DW_TAG_inlined_subroutine)
Greg Clayton9e315582011-09-02 04:03:59 +00003647 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00003648 inlined_die = die;
Greg Clayton9e315582011-09-02 04:03:59 +00003649
Jim Ingham4cda6e02011-10-07 22:23:45 +00003650 while ((die = die->GetParent()) != NULL)
Greg Clayton2bc22f82011-09-30 03:20:47 +00003651 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00003652 if (die->Tag() == DW_TAG_subprogram)
3653 break;
Greg Clayton9e315582011-09-02 04:03:59 +00003654 }
3655 }
Jason Molenda60db6e42014-10-16 01:40:16 +00003656 assert (die && die->Tag() == DW_TAG_subprogram);
Greg Claytonaa044962011-10-13 00:59:38 +00003657 if (GetFunction (cu, die, sc))
Jim Ingham4cda6e02011-10-07 22:23:45 +00003658 {
3659 Address addr;
3660 // Parse all blocks if needed
3661 if (inlined_die)
3662 {
Greg Claytonf7bb1fb2015-01-15 03:13:44 +00003663 Block &function_block = sc.function->GetBlock (true);
3664 sc.block = function_block.FindBlockByID (MakeUserID(inlined_die->GetOffset()));
3665 if (sc.block == NULL)
3666 sc.block = function_block.FindBlockByID (inlined_die->GetOffset());
3667 if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
Jim Ingham4cda6e02011-10-07 22:23:45 +00003668 addr.Clear();
3669 }
3670 else
3671 {
3672 sc.block = NULL;
3673 addr = sc.function->GetAddressRange().GetBaseAddress();
3674 }
3675
3676 if (addr.IsValid())
3677 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00003678 sc_list.Append(sc);
Greg Claytonaa044962011-10-13 00:59:38 +00003679 return true;
Jim Ingham4cda6e02011-10-07 22:23:45 +00003680 }
3681 }
3682
Greg Claytonaa044962011-10-13 00:59:38 +00003683 return false;
Greg Clayton9e315582011-09-02 04:03:59 +00003684}
3685
Greg Clayton7f995132011-10-04 22:41:51 +00003686void
3687SymbolFileDWARF::FindFunctions (const ConstString &name,
3688 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00003689 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00003690 SymbolContextList& sc_list)
3691{
Greg Claytond4a2b372011-09-12 23:21:58 +00003692 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00003693 if (name_to_die.Find (name, die_offsets))
3694 {
Pavel Labatha73d6572015-03-13 10:22:00 +00003695 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00003696 }
3697}
3698
3699
3700void
3701SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
3702 const NameToDIE &name_to_die,
Pavel Labatha73d6572015-03-13 10:22:00 +00003703 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00003704 SymbolContextList& sc_list)
3705{
3706 DIEArray die_offsets;
3707 if (name_to_die.Find (regex, die_offsets))
3708 {
Pavel Labatha73d6572015-03-13 10:22:00 +00003709 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00003710 }
3711}
3712
3713
3714void
3715SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
3716 const DWARFMappedHash::MemoryTable &memory_table,
Pavel Labatha73d6572015-03-13 10:22:00 +00003717 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00003718 SymbolContextList& sc_list)
3719{
3720 DIEArray die_offsets;
Greg Claytond1767f02011-12-08 02:13:16 +00003721 DWARFMappedHash::DIEInfoArray hash_data_array;
3722 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
Greg Clayton7f995132011-10-04 22:41:51 +00003723 {
Greg Claytond1767f02011-12-08 02:13:16 +00003724 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
Pavel Labatha73d6572015-03-13 10:22:00 +00003725 ParseFunctions (die_offsets, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00003726 }
3727}
3728
3729void
3730SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
Pavel Labatha73d6572015-03-13 10:22:00 +00003731 bool include_inlines,
Greg Clayton7f995132011-10-04 22:41:51 +00003732 SymbolContextList& sc_list)
3733{
3734 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003735 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00003736 {
Greg Clayton7f995132011-10-04 22:41:51 +00003737 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00003738 for (size_t i=0; i<num_matches; ++i)
Greg Claytond7e05462010-11-14 00:22:48 +00003739 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003740 const dw_offset_t die_offset = die_offsets[i];
Pavel Labatha73d6572015-03-13 10:22:00 +00003741 ResolveFunction (die_offset, dwarf_cu, include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003742 }
3743 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00003744}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003745
Jim Ingham4cda6e02011-10-07 22:23:45 +00003746bool
3747SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
3748 const DWARFCompileUnit *dwarf_cu,
3749 uint32_t name_type_mask,
3750 const char *partial_name,
3751 const char *base_name_start,
3752 const char *base_name_end)
3753{
Greg Claytonfbea0f62012-11-15 18:05:43 +00003754 // If we are looking only for methods, throw away all the ones that are or aren't in C++ classes:
3755 if (name_type_mask == eFunctionNameTypeMethod || name_type_mask == eFunctionNameTypeBase)
Jim Ingham4cda6e02011-10-07 22:23:45 +00003756 {
Greg Claytonf0705c82011-10-22 03:33:13 +00003757 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
3758 if (!containing_decl_ctx)
3759 return false;
3760
3761 bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
3762
Greg Claytonfbea0f62012-11-15 18:05:43 +00003763 if (name_type_mask == eFunctionNameTypeMethod)
3764 {
3765 if (is_cxx_method == false)
3766 return false;
3767 }
3768
3769 if (name_type_mask == eFunctionNameTypeBase)
3770 {
3771 if (is_cxx_method == true)
3772 return false;
3773 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00003774 }
3775
3776 // Now we need to check whether the name we got back for this type matches the extra specifications
3777 // that were in the name we're looking up:
3778 if (base_name_start != partial_name || *base_name_end != '\0')
3779 {
3780 // First see if the stuff to the left matches the full name. To do that let's see if
3781 // we can pull out the mips linkage name attribute:
3782
3783 Mangled best_name;
Jim Ingham4cda6e02011-10-07 22:23:45 +00003784 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonfbea0f62012-11-15 18:05:43 +00003785 DWARFFormValue form_value;
Jim Ingham4cda6e02011-10-07 22:23:45 +00003786 die->GetAttributes(this, dwarf_cu, NULL, attributes);
3787 uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
Greg Clayton71415542012-12-08 00:24:40 +00003788 if (idx == UINT32_MAX)
3789 idx = attributes.FindAttributeIndex(DW_AT_linkage_name);
Jim Ingham4cda6e02011-10-07 22:23:45 +00003790 if (idx != UINT32_MAX)
3791 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00003792 if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
3793 {
Greg Claytonfbea0f62012-11-15 18:05:43 +00003794 const char *mangled_name = form_value.AsCString(&get_debug_str_data());
3795 if (mangled_name)
3796 best_name.SetValue (ConstString(mangled_name), true);
3797 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00003798 }
Greg Claytonfbea0f62012-11-15 18:05:43 +00003799
3800 if (!best_name)
3801 {
3802 idx = attributes.FindAttributeIndex(DW_AT_name);
3803 if (idx != UINT32_MAX && attributes.ExtractFormValueAtIndex(this, idx, form_value))
3804 {
3805 const char *name = form_value.AsCString(&get_debug_str_data());
3806 best_name.SetValue (ConstString(name), false);
3807 }
3808 }
3809
Greg Claytonddaf6a72015-07-08 22:32:23 +00003810 const LanguageType cu_language = const_cast<DWARFCompileUnit *>(dwarf_cu)->GetLanguageType();
3811 if (best_name.GetDemangledName(cu_language))
Jim Ingham4cda6e02011-10-07 22:23:45 +00003812 {
Greg Claytonddaf6a72015-07-08 22:32:23 +00003813 const char *demangled = best_name.GetDemangledName(cu_language).GetCString();
Jim Ingham4cda6e02011-10-07 22:23:45 +00003814 if (demangled)
3815 {
3816 std::string name_no_parens(partial_name, base_name_end - partial_name);
Jim Ingham85c13d72012-03-02 02:24:42 +00003817 const char *partial_in_demangled = strstr (demangled, name_no_parens.c_str());
3818 if (partial_in_demangled == NULL)
Jim Ingham4cda6e02011-10-07 22:23:45 +00003819 return false;
Jim Ingham85c13d72012-03-02 02:24:42 +00003820 else
3821 {
3822 // Sort out the case where our name is something like "Process::Destroy" and the match is
3823 // "SBProcess::Destroy" - that shouldn't be a match. We should really always match on
3824 // namespace boundaries...
3825
3826 if (partial_name[0] == ':' && partial_name[1] == ':')
3827 {
3828 // The partial name was already on a namespace boundary so all matches are good.
3829 return true;
3830 }
3831 else if (partial_in_demangled == demangled)
3832 {
3833 // They both start the same, so this is an good match.
3834 return true;
3835 }
3836 else
3837 {
3838 if (partial_in_demangled - demangled == 1)
3839 {
3840 // Only one character difference, can't be a namespace boundary...
3841 return false;
3842 }
3843 else if (*(partial_in_demangled - 1) == ':' && *(partial_in_demangled - 2) == ':')
3844 {
3845 // We are on a namespace boundary, so this is also good.
3846 return true;
3847 }
3848 else
3849 return false;
3850 }
3851 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00003852 }
3853 }
3854 }
3855
3856 return true;
3857}
Greg Claytonc685f8e2010-09-15 04:15:46 +00003858
Greg Clayton0c5cd902010-06-28 21:30:43 +00003859uint32_t
Greg Clayton2bc22f82011-09-30 03:20:47 +00003860SymbolFileDWARF::FindFunctions (const ConstString &name,
Sean Callanan213fdb82011-10-13 01:49:10 +00003861 const lldb_private::ClangNamespaceDecl *namespace_decl,
Sean Callanan9df05fb2012-02-10 22:52:19 +00003862 uint32_t name_type_mask,
3863 bool include_inlines,
Greg Clayton2bc22f82011-09-30 03:20:47 +00003864 bool append,
3865 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00003866{
3867 Timer scoped_timer (__PRETTY_FUNCTION__,
3868 "SymbolFileDWARF::FindFunctions (name = '%s')",
3869 name.AsCString());
3870
Greg Clayton43fe2172013-04-03 02:00:15 +00003871 // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
3872 assert ((name_type_mask & eFunctionNameTypeAuto) == 0);
3873
Greg Clayton5160ce52013-03-27 23:08:40 +00003874 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00003875
3876 if (log)
3877 {
Greg Clayton5160ce52013-03-27 23:08:40 +00003878 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00003879 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
3880 name.GetCString(),
3881 name_type_mask,
3882 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00003883 }
3884
Greg Clayton0c5cd902010-06-28 21:30:43 +00003885 // If we aren't appending the results to this list, then clear the list
3886 if (!append)
3887 sc_list.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00003888
3889 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
Ed Maste4c24b122013-10-17 20:13:14 +00003890 return 0;
Jim Ingham4cda6e02011-10-07 22:23:45 +00003891
3892 // If name is empty then we won't find anything.
3893 if (name.IsEmpty())
3894 return 0;
Greg Clayton0c5cd902010-06-28 21:30:43 +00003895
3896 // Remember how many sc_list are in the list before we search in case
3897 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00003898
Jim Ingham4cda6e02011-10-07 22:23:45 +00003899 const char *name_cstr = name.GetCString();
Greg Clayton43fe2172013-04-03 02:00:15 +00003900
3901 const uint32_t original_size = sc_list.GetSize();
3902
Jim Ingham4cda6e02011-10-07 22:23:45 +00003903 DWARFDebugInfo* info = DebugInfo();
3904 if (info == NULL)
3905 return 0;
3906
Greg Claytonaa044962011-10-13 00:59:38 +00003907 DWARFCompileUnit *dwarf_cu = NULL;
Greg Clayton43fe2172013-04-03 02:00:15 +00003908 std::set<const DWARFDebugInfoEntry *> resolved_dies;
Greg Clayton97fbc342011-10-20 22:30:33 +00003909 if (m_using_apple_tables)
Greg Clayton4d01ace2011-09-29 16:58:15 +00003910 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003911 if (m_apple_names_ap.get())
Jim Ingham4cda6e02011-10-07 22:23:45 +00003912 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003913
3914 DIEArray die_offsets;
3915
3916 uint32_t num_matches = 0;
3917
Greg Clayton43fe2172013-04-03 02:00:15 +00003918 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonaa044962011-10-13 00:59:38 +00003919 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003920 // If they asked for the full name, match what they typed. At some point we may
3921 // want to canonicalize this (strip double spaces, etc. For now, we just add all the
3922 // dies that we find by exact match.
Jim Ingham4cda6e02011-10-07 22:23:45 +00003923 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00003924 for (uint32_t i = 0; i < num_matches; i++)
3925 {
Greg Clayton95d87902011-11-11 03:16:25 +00003926 const dw_offset_t die_offset = die_offsets[i];
3927 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Greg Claytonaa044962011-10-13 00:59:38 +00003928 if (die)
3929 {
Sean Callanan213fdb82011-10-13 01:49:10 +00003930 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3931 continue;
3932
Greg Clayton43fe2172013-04-03 02:00:15 +00003933 if (resolved_dies.find(die) == resolved_dies.end())
3934 {
Pavel Labatha73d6572015-03-13 10:22:00 +00003935 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00003936 resolved_dies.insert(die);
3937 }
Greg Claytonaa044962011-10-13 00:59:38 +00003938 }
Greg Clayton95d87902011-11-11 03:16:25 +00003939 else
3940 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00003941 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
3942 die_offset, name_cstr);
Greg Clayton95d87902011-11-11 03:16:25 +00003943 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00003944 }
Greg Clayton97fbc342011-10-20 22:30:33 +00003945 }
Greg Clayton43fe2172013-04-03 02:00:15 +00003946
3947 if (name_type_mask & eFunctionNameTypeSelector)
3948 {
3949 if (namespace_decl && *namespace_decl)
3950 return 0; // no selectors in namespaces
Greg Clayton97fbc342011-10-20 22:30:33 +00003951
Greg Clayton43fe2172013-04-03 02:00:15 +00003952 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
3953 // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
3954 // and if it is an ObjC method name, we're good.
Greg Clayton97fbc342011-10-20 22:30:33 +00003955
Greg Clayton43fe2172013-04-03 02:00:15 +00003956 for (uint32_t i = 0; i < num_matches; i++)
Greg Clayton97fbc342011-10-20 22:30:33 +00003957 {
Greg Clayton43fe2172013-04-03 02:00:15 +00003958 const dw_offset_t die_offset = die_offsets[i];
3959 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
3960 if (die)
Greg Clayton97fbc342011-10-20 22:30:33 +00003961 {
Greg Clayton43fe2172013-04-03 02:00:15 +00003962 const char *die_name = die->GetName(this, dwarf_cu);
3963 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
Greg Clayton97fbc342011-10-20 22:30:33 +00003964 {
Greg Clayton43fe2172013-04-03 02:00:15 +00003965 if (resolved_dies.find(die) == resolved_dies.end())
3966 {
Pavel Labatha73d6572015-03-13 10:22:00 +00003967 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00003968 resolved_dies.insert(die);
3969 }
Greg Clayton97fbc342011-10-20 22:30:33 +00003970 }
3971 }
Greg Clayton43fe2172013-04-03 02:00:15 +00003972 else
3973 {
3974 GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
3975 die_offset, name_cstr);
3976 }
Greg Clayton97fbc342011-10-20 22:30:33 +00003977 }
Greg Clayton43fe2172013-04-03 02:00:15 +00003978 die_offsets.clear();
3979 }
3980
3981 if (((name_type_mask & eFunctionNameTypeMethod) && !namespace_decl) || name_type_mask & eFunctionNameTypeBase)
3982 {
3983 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
3984 // extract the base name, look that up, and if there is any other information in the name we were
3985 // passed in we have to post-filter based on that.
3986
3987 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
3988 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
3989
3990 for (uint32_t i = 0; i < num_matches; i++)
3991 {
3992 const dw_offset_t die_offset = die_offsets[i];
3993 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
3994 if (die)
3995 {
Greg Clayton43fe2172013-04-03 02:00:15 +00003996 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3997 continue;
3998
3999 // If we get to here, the die is good, and we should add it:
4000 if (resolved_dies.find(die) == resolved_dies.end())
Pavel Labatha73d6572015-03-13 10:22:00 +00004001 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00004002 {
4003 bool keep_die = true;
4004 if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
4005 {
4006 // We are looking for either basenames or methods, so we need to
4007 // trim out the ones we won't want by looking at the type
4008 SymbolContext sc;
4009 if (sc_list.GetLastContext(sc))
4010 {
4011 if (sc.block)
4012 {
4013 // We have an inlined function
4014 }
4015 else if (sc.function)
4016 {
4017 Type *type = sc.function->GetType();
4018
Sean Callananc370a8a2013-09-18 22:59:55 +00004019 if (type)
Greg Clayton43fe2172013-04-03 02:00:15 +00004020 {
Sean Callananc370a8a2013-09-18 22:59:55 +00004021 clang::DeclContext* decl_ctx = GetClangDeclContextContainingTypeUID (type->GetID());
4022 if (decl_ctx->isRecord())
Greg Clayton43fe2172013-04-03 02:00:15 +00004023 {
Sean Callananc370a8a2013-09-18 22:59:55 +00004024 if (name_type_mask & eFunctionNameTypeBase)
4025 {
4026 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
4027 keep_die = false;
4028 }
4029 }
4030 else
4031 {
4032 if (name_type_mask & eFunctionNameTypeMethod)
4033 {
4034 sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
4035 keep_die = false;
4036 }
Greg Clayton43fe2172013-04-03 02:00:15 +00004037 }
4038 }
4039 else
4040 {
Sean Callananc370a8a2013-09-18 22:59:55 +00004041 GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
4042 die_offset);
Greg Clayton43fe2172013-04-03 02:00:15 +00004043 }
4044 }
4045 }
4046 }
4047 if (keep_die)
4048 resolved_dies.insert(die);
4049 }
4050 }
4051 else
4052 {
4053 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
4054 die_offset, name_cstr);
4055 }
4056 }
4057 die_offsets.clear();
Jim Ingham4cda6e02011-10-07 22:23:45 +00004058 }
4059 }
Greg Clayton7f995132011-10-04 22:41:51 +00004060 }
4061 else
4062 {
4063
4064 // Index the DWARF if we haven't already
4065 if (!m_indexed)
4066 Index ();
4067
Greg Clayton7f995132011-10-04 22:41:51 +00004068 if (name_type_mask & eFunctionNameTypeFull)
Matt Kopecd6089962013-05-10 17:53:48 +00004069 {
Pavel Labatha73d6572015-03-13 10:22:00 +00004070 FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00004071
Ed Mastefc7baa02013-09-09 18:00:45 +00004072 // FIXME Temporary workaround for global/anonymous namespace
Robert Flack5cbd3bf2015-05-13 18:20:02 +00004073 // functions debugging FreeBSD and Linux binaries.
Matt Kopecd6089962013-05-10 17:53:48 +00004074 // If we didn't find any functions in the global namespace try
4075 // looking in the basename index but ignore any returned
Robert Flackeb83fab2015-05-15 18:59:59 +00004076 // functions that have a namespace but keep functions which
4077 // have an anonymous namespace
4078 // TODO: The arch in the object file isn't correct for MSVC
4079 // binaries on windows, we should find a way to make it
4080 // correct and handle those symbols as well.
Matt Kopecd6089962013-05-10 17:53:48 +00004081 if (sc_list.GetSize() == 0)
4082 {
Robert Flackeb83fab2015-05-15 18:59:59 +00004083 ArchSpec arch;
4084 if (!namespace_decl &&
4085 GetObjectFile()->GetArchitecture(arch) &&
4086 (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
4087 arch.GetMachine() == llvm::Triple::hexagon))
Matt Kopecd6089962013-05-10 17:53:48 +00004088 {
Robert Flackeb83fab2015-05-15 18:59:59 +00004089 SymbolContextList temp_sc_list;
4090 FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
Matt Kopecd6089962013-05-10 17:53:48 +00004091 SymbolContext sc;
4092 for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
4093 {
4094 if (temp_sc_list.GetContextAtIndex(i, sc))
4095 {
Matt Kopeca189d492013-05-10 22:55:24 +00004096 ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
4097 ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
Robert Flackeb83fab2015-05-15 18:59:59 +00004098 // Mangled names on Linux and FreeBSD are of the form:
4099 // _ZN18function_namespace13function_nameEv.
Matt Kopec04e5d582013-05-14 19:00:41 +00004100 if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
4101 !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
Matt Kopecd6089962013-05-10 17:53:48 +00004102 {
4103 sc_list.Append(sc);
4104 }
4105 }
4106 }
4107 }
4108 }
Matt Kopecd6089962013-05-10 17:53:48 +00004109 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00004110 DIEArray die_offsets;
4111 DWARFCompileUnit *dwarf_cu = NULL;
4112
Greg Clayton43fe2172013-04-03 02:00:15 +00004113 if (name_type_mask & eFunctionNameTypeBase)
Jim Ingham4cda6e02011-10-07 22:23:45 +00004114 {
Greg Clayton43fe2172013-04-03 02:00:15 +00004115 uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
Greg Claytonaa044962011-10-13 00:59:38 +00004116 for (uint32_t i = 0; i < num_base; i++)
Jim Ingham4cda6e02011-10-07 22:23:45 +00004117 {
Greg Claytonaa044962011-10-13 00:59:38 +00004118 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
4119 if (die)
4120 {
Sean Callanan213fdb82011-10-13 01:49:10 +00004121 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
4122 continue;
4123
Greg Claytonaa044962011-10-13 00:59:38 +00004124 // If we get to here, the die is good, and we should add it:
Greg Clayton43fe2172013-04-03 02:00:15 +00004125 if (resolved_dies.find(die) == resolved_dies.end())
4126 {
Pavel Labatha73d6572015-03-13 10:22:00 +00004127 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00004128 resolved_dies.insert(die);
4129 }
Greg Claytonaa044962011-10-13 00:59:38 +00004130 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00004131 }
4132 die_offsets.clear();
4133 }
4134
Greg Clayton43fe2172013-04-03 02:00:15 +00004135 if (name_type_mask & eFunctionNameTypeMethod)
Jim Ingham4cda6e02011-10-07 22:23:45 +00004136 {
Sean Callanan213fdb82011-10-13 01:49:10 +00004137 if (namespace_decl && *namespace_decl)
4138 return 0; // no methods in namespaces
4139
Greg Clayton43fe2172013-04-03 02:00:15 +00004140 uint32_t num_base = m_function_method_index.Find(name, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00004141 {
Greg Claytonaa044962011-10-13 00:59:38 +00004142 for (uint32_t i = 0; i < num_base; i++)
4143 {
4144 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
4145 if (die)
4146 {
Greg Claytonaa044962011-10-13 00:59:38 +00004147 // If we get to here, the die is good, and we should add it:
Greg Clayton43fe2172013-04-03 02:00:15 +00004148 if (resolved_dies.find(die) == resolved_dies.end())
4149 {
Pavel Labatha73d6572015-03-13 10:22:00 +00004150 if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
Greg Clayton43fe2172013-04-03 02:00:15 +00004151 resolved_dies.insert(die);
4152 }
Greg Claytonaa044962011-10-13 00:59:38 +00004153 }
4154 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00004155 }
4156 die_offsets.clear();
4157 }
Greg Clayton7f995132011-10-04 22:41:51 +00004158
Greg Clayton43fe2172013-04-03 02:00:15 +00004159 if ((name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
Jim Ingham4cda6e02011-10-07 22:23:45 +00004160 {
Pavel Labatha73d6572015-03-13 10:22:00 +00004161 FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
Jim Ingham4cda6e02011-10-07 22:23:45 +00004162 }
4163
Greg Clayton4d01ace2011-09-29 16:58:15 +00004164 }
4165
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004166 // Return the number of variable that were appended to the list
Greg Clayton437a1352012-04-09 22:43:43 +00004167 const uint32_t num_matches = sc_list.GetSize() - original_size;
4168
4169 if (log && num_matches > 0)
4170 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004171 GetObjectFile()->GetModule()->LogMessage (log,
Pavel Labatha73d6572015-03-13 10:22:00 +00004172 "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
Greg Clayton437a1352012-04-09 22:43:43 +00004173 name.GetCString(),
4174 name_type_mask,
Pavel Labatha73d6572015-03-13 10:22:00 +00004175 include_inlines,
Greg Clayton437a1352012-04-09 22:43:43 +00004176 append,
4177 num_matches);
4178 }
4179 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004180}
4181
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004182uint32_t
Sean Callanan9df05fb2012-02-10 22:52:19 +00004183SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004184{
4185 Timer scoped_timer (__PRETTY_FUNCTION__,
4186 "SymbolFileDWARF::FindFunctions (regex = '%s')",
4187 regex.GetText());
4188
Greg Clayton5160ce52013-03-27 23:08:40 +00004189 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00004190
4191 if (log)
4192 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004193 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00004194 "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
4195 regex.GetText(),
4196 append);
Greg Clayton21f2a492011-10-06 00:09:08 +00004197 }
4198
4199
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004200 // If we aren't appending the results to this list, then clear the list
4201 if (!append)
4202 sc_list.Clear();
4203
4204 // Remember how many sc_list are in the list before we search in case
4205 // we are appending the results to a variable list.
4206 uint32_t original_size = sc_list.GetSize();
4207
Greg Clayton97fbc342011-10-20 22:30:33 +00004208 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00004209 {
Greg Clayton97fbc342011-10-20 22:30:33 +00004210 if (m_apple_names_ap.get())
Pavel Labatha73d6572015-03-13 10:22:00 +00004211 FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00004212 }
4213 else
4214 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00004215 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00004216 if (!m_indexed)
4217 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004218
Pavel Labatha73d6572015-03-13 10:22:00 +00004219 FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004220
Pavel Labatha73d6572015-03-13 10:22:00 +00004221 FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00004222 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004223
4224 // Return the number of variable that were appended to the list
4225 return sc_list.GetSize() - original_size;
4226}
Jim Ingham318c9f22011-08-26 19:44:13 +00004227
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004228uint32_t
Greg Claytond1767f02011-12-08 02:13:16 +00004229SymbolFileDWARF::FindTypes (const SymbolContext& sc,
4230 const ConstString &name,
4231 const lldb_private::ClangNamespaceDecl *namespace_decl,
4232 bool append,
4233 uint32_t max_matches,
4234 TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004235{
Greg Claytonc685f8e2010-09-15 04:15:46 +00004236 DWARFDebugInfo* info = DebugInfo();
4237 if (info == NULL)
4238 return 0;
4239
Greg Clayton5160ce52013-03-27 23:08:40 +00004240 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004241
Greg Clayton21f2a492011-10-06 00:09:08 +00004242 if (log)
4243 {
Greg Clayton437a1352012-04-09 22:43:43 +00004244 if (namespace_decl)
Greg Clayton5160ce52013-03-27 23:08:40 +00004245 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004246 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list)",
4247 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004248 static_cast<void*>(namespace_decl->GetNamespaceDecl()),
Greg Clayton437a1352012-04-09 22:43:43 +00004249 namespace_decl->GetQualifiedName().c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004250 append, max_matches);
Greg Clayton437a1352012-04-09 22:43:43 +00004251 else
Greg Clayton5160ce52013-03-27 23:08:40 +00004252 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004253 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004254 name.GetCString(), append,
Greg Clayton437a1352012-04-09 22:43:43 +00004255 max_matches);
Greg Clayton21f2a492011-10-06 00:09:08 +00004256 }
4257
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004258 // If we aren't appending the results to this list, then clear the list
4259 if (!append)
4260 types.Clear();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004261
Sean Callanan213fdb82011-10-13 01:49:10 +00004262 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
Ed Maste4c24b122013-10-17 20:13:14 +00004263 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004264
Greg Claytond4a2b372011-09-12 23:21:58 +00004265 DIEArray die_offsets;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004266
Greg Clayton97fbc342011-10-20 22:30:33 +00004267 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00004268 {
Greg Clayton97fbc342011-10-20 22:30:33 +00004269 if (m_apple_types_ap.get())
4270 {
4271 const char *name_cstr = name.GetCString();
4272 m_apple_types_ap->FindByName (name_cstr, die_offsets);
4273 }
Greg Clayton7f995132011-10-04 22:41:51 +00004274 }
4275 else
4276 {
4277 if (!m_indexed)
4278 Index ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004279
Greg Clayton7f995132011-10-04 22:41:51 +00004280 m_type_index.Find (name, die_offsets);
4281 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004282
Greg Clayton437a1352012-04-09 22:43:43 +00004283 const size_t num_die_matches = die_offsets.size();
Greg Clayton7f995132011-10-04 22:41:51 +00004284
Greg Clayton437a1352012-04-09 22:43:43 +00004285 if (num_die_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004286 {
Greg Clayton7f995132011-10-04 22:41:51 +00004287 const uint32_t initial_types_size = types.GetSize();
4288 DWARFCompileUnit* dwarf_cu = NULL;
4289 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00004290 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton437a1352012-04-09 22:43:43 +00004291 for (size_t i=0; i<num_die_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004292 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004293 const dw_offset_t die_offset = die_offsets[i];
4294 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
4295
Greg Clayton95d87902011-11-11 03:16:25 +00004296 if (die)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004297 {
Greg Clayton95d87902011-11-11 03:16:25 +00004298 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
4299 continue;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004300
Greg Clayton95d87902011-11-11 03:16:25 +00004301 Type *matching_type = ResolveType (dwarf_cu, die);
4302 if (matching_type)
4303 {
4304 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone1cd1be2012-01-29 20:56:30 +00004305 types.InsertUnique (matching_type->shared_from_this());
Greg Clayton95d87902011-11-11 03:16:25 +00004306 if (types.GetSize() >= max_matches)
4307 break;
4308 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004309 }
Greg Clayton95d87902011-11-11 03:16:25 +00004310 else
4311 {
4312 if (m_using_apple_tables)
4313 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00004314 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
4315 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00004316 }
4317 }
4318
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004319 }
Greg Clayton437a1352012-04-09 22:43:43 +00004320 const uint32_t num_matches = types.GetSize() - initial_types_size;
4321 if (log && num_matches)
4322 {
4323 if (namespace_decl)
4324 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004325 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004326 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list) => %u",
4327 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004328 static_cast<void*>(namespace_decl->GetNamespaceDecl()),
Greg Clayton437a1352012-04-09 22:43:43 +00004329 namespace_decl->GetQualifiedName().c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004330 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00004331 num_matches);
4332 }
4333 else
4334 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004335 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004336 "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list) => %u",
4337 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004338 append, max_matches,
Greg Clayton437a1352012-04-09 22:43:43 +00004339 num_matches);
4340 }
4341 }
4342 return num_matches;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004343 }
Greg Clayton7f995132011-10-04 22:41:51 +00004344 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004345}
4346
4347
Greg Clayton526e5af2010-11-13 03:52:47 +00004348ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00004349SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00004350 const ConstString &name,
4351 const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00004352{
Greg Clayton5160ce52013-03-27 23:08:40 +00004353 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Clayton21f2a492011-10-06 00:09:08 +00004354
4355 if (log)
4356 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004357 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00004358 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
4359 name.GetCString());
Greg Clayton21f2a492011-10-06 00:09:08 +00004360 }
Sean Callanan213fdb82011-10-13 01:49:10 +00004361
4362 if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl))
Ed Maste4c24b122013-10-17 20:13:14 +00004363 return ClangNamespaceDecl();
Greg Clayton21f2a492011-10-06 00:09:08 +00004364
Greg Clayton526e5af2010-11-13 03:52:47 +00004365 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00004366 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00004367 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00004368 {
Greg Clayton7f995132011-10-04 22:41:51 +00004369 DIEArray die_offsets;
4370
Greg Clayton526e5af2010-11-13 03:52:47 +00004371 // Index if we already haven't to make sure the compile units
4372 // get indexed and make their global DIE index list
Greg Clayton97fbc342011-10-20 22:30:33 +00004373 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00004374 {
Greg Clayton97fbc342011-10-20 22:30:33 +00004375 if (m_apple_namespaces_ap.get())
4376 {
4377 const char *name_cstr = name.GetCString();
4378 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
4379 }
Greg Clayton7f995132011-10-04 22:41:51 +00004380 }
4381 else
4382 {
4383 if (!m_indexed)
4384 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00004385
Greg Clayton7f995132011-10-04 22:41:51 +00004386 m_namespace_index.Find (name, die_offsets);
4387 }
Greg Claytond4a2b372011-09-12 23:21:58 +00004388
4389 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton526e5af2010-11-13 03:52:47 +00004390 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00004391 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00004392 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00004393 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004394 DWARFDebugInfo* debug_info = DebugInfo();
4395 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00004396 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004397 const dw_offset_t die_offset = die_offsets[i];
4398 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Sean Callanan213fdb82011-10-13 01:49:10 +00004399
Greg Clayton95d87902011-11-11 03:16:25 +00004400 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00004401 {
Greg Clayton95d87902011-11-11 03:16:25 +00004402 if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die))
4403 continue;
4404
4405 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
4406 if (clang_namespace_decl)
4407 {
4408 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
4409 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
Greg Claytond1767f02011-12-08 02:13:16 +00004410 break;
Greg Clayton95d87902011-11-11 03:16:25 +00004411 }
Greg Claytond4a2b372011-09-12 23:21:58 +00004412 }
Greg Clayton95d87902011-11-11 03:16:25 +00004413 else
4414 {
4415 if (m_using_apple_tables)
4416 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00004417 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
4418 die_offset, name.GetCString());
Greg Clayton95d87902011-11-11 03:16:25 +00004419 }
4420 }
4421
Greg Clayton526e5af2010-11-13 03:52:47 +00004422 }
4423 }
Greg Clayton96d7d742010-11-10 23:42:09 +00004424 }
Greg Clayton437a1352012-04-09 22:43:43 +00004425 if (log && namespace_decl.GetNamespaceDecl())
4426 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004427 GetObjectFile()->GetModule()->LogMessage (log,
Greg Clayton437a1352012-04-09 22:43:43 +00004428 "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => clang::NamespaceDecl(%p) \"%s\"",
4429 name.GetCString(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004430 static_cast<const void*>(namespace_decl.GetNamespaceDecl()),
Greg Clayton437a1352012-04-09 22:43:43 +00004431 namespace_decl.GetQualifiedName().c_str());
4432 }
4433
Greg Clayton526e5af2010-11-13 03:52:47 +00004434 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00004435}
4436
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004437uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004438SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004439{
4440 // Remember how many sc_list are in the list before we search in case
4441 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004442 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004443
4444 const uint32_t num_die_offsets = die_offsets.size();
4445 // Parse all of the types we found from the pubtypes matches
4446 uint32_t i;
4447 uint32_t num_matches = 0;
4448 for (i = 0; i < num_die_offsets; ++i)
4449 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004450 Type *matching_type = ResolveTypeUID (die_offsets[i]);
4451 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004452 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004453 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone1cd1be2012-01-29 20:56:30 +00004454 types.InsertUnique (matching_type->shared_from_this());
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004455 ++num_matches;
4456 if (num_matches >= max_matches)
4457 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004458 }
4459 }
4460
4461 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00004462 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004463}
4464
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004465
4466size_t
Greg Clayton5113dc82011-08-12 06:47:54 +00004467SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
4468 clang::DeclContext *containing_decl_ctx,
Greg Clayton5113dc82011-08-12 06:47:54 +00004469 DWARFCompileUnit* dwarf_cu,
4470 const DWARFDebugInfoEntry *parent_die,
4471 bool skip_artificial,
4472 bool &is_static,
Greg Clayton03969752014-02-24 18:53:11 +00004473 bool &is_variadic,
Greg Clayton57ee3062013-07-11 22:46:58 +00004474 std::vector<ClangASTType>& function_param_types,
Greg Clayton5113dc82011-08-12 06:47:54 +00004475 std::vector<clang::ParmVarDecl*>& function_param_decls,
Greg Claytond20deac2014-04-04 18:15:18 +00004476 unsigned &type_quals) // ,
4477 // ClangASTContext::TemplateParameterInfos &template_param_infos))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004478{
4479 if (parent_die == NULL)
4480 return 0;
4481
Todd Fialaee8bfc62014-09-11 17:29:12 +00004482 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Greg Claytond88d7592010-09-15 08:33:30 +00004483
Greg Clayton7fedea22010-11-16 02:10:54 +00004484 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004485 const DWARFDebugInfoEntry *die;
4486 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
4487 {
4488 dw_tag_t tag = die->Tag();
4489 switch (tag)
4490 {
4491 case DW_TAG_formal_parameter:
4492 {
4493 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004494 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004495 if (num_attributes > 0)
4496 {
4497 const char *name = NULL;
4498 Declaration decl;
4499 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00004500 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004501 // one of None, Auto, Register, Extern, Static, PrivateExtern
4502
Sean Callanane2ef6e32010-09-23 03:01:22 +00004503 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004504 uint32_t i;
4505 for (i=0; i<num_attributes; ++i)
4506 {
4507 const dw_attr_t attr = attributes.AttributeAtIndex(i);
4508 DWARFFormValue form_value;
4509 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4510 {
4511 switch (attr)
4512 {
4513 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4514 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4515 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4516 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00004517 case DW_AT_type: param_type_die_offset = form_value.Reference(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00004518 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004519 case DW_AT_location:
4520 // if (form_value.BlockData())
4521 // {
Ed Masteeeae7212013-10-24 20:43:47 +00004522 // const DWARFDataExtractor& debug_info_data = debug_info();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004523 // uint32_t block_length = form_value.Unsigned();
Ed Masteeeae7212013-10-24 20:43:47 +00004524 // DWARFDataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004525 // }
4526 // else
4527 // {
4528 // }
4529 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004530 case DW_AT_const_value:
4531 case DW_AT_default_value:
4532 case DW_AT_description:
4533 case DW_AT_endianity:
4534 case DW_AT_is_optional:
4535 case DW_AT_segment:
4536 case DW_AT_variable_parameter:
4537 default:
4538 case DW_AT_abstract_origin:
4539 case DW_AT_sibling:
4540 break;
4541 }
4542 }
4543 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00004544
Greg Clayton0fffff52010-09-24 05:15:53 +00004545 bool skip = false;
4546 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004547 {
Greg Clayton0fffff52010-09-24 05:15:53 +00004548 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00004549 {
4550 // In order to determine if a C++ member function is
4551 // "const" we have to look at the const-ness of "this"...
4552 // Ugly, but that
4553 if (arg_idx == 0)
4554 {
Greg Claytonf0705c82011-10-22 03:33:13 +00004555 if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
Sean Callanan763d72a2011-08-02 22:21:50 +00004556 {
Greg Clayton5113dc82011-08-12 06:47:54 +00004557 // Often times compilers omit the "this" name for the
4558 // specification DIEs, so we can't rely upon the name
4559 // being in the formal parameter DIE...
4560 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton7fedea22010-11-16 02:10:54 +00004561 {
Greg Clayton5113dc82011-08-12 06:47:54 +00004562 Type *this_type = ResolveTypeUID (param_type_die_offset);
4563 if (this_type)
4564 {
4565 uint32_t encoding_mask = this_type->GetEncodingMask();
4566 if (encoding_mask & Type::eEncodingIsPointerUID)
4567 {
4568 is_static = false;
4569
4570 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
4571 type_quals |= clang::Qualifiers::Const;
4572 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
4573 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00004574 }
4575 }
4576 }
4577 }
4578 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004579 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00004580 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004581 else
4582 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004583
Greg Clayton0fffff52010-09-24 05:15:53 +00004584 // HACK: Objective C formal parameters "self" and "_cmd"
4585 // are not marked as artificial in the DWARF...
Greg Clayton53eb1c22012-04-02 22:59:12 +00004586 CompileUnit *comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
4587 if (comp_unit)
Greg Clayton0fffff52010-09-24 05:15:53 +00004588 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00004589 switch (comp_unit->GetLanguage())
4590 {
4591 case eLanguageTypeObjC:
4592 case eLanguageTypeObjC_plus_plus:
4593 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
4594 skip = true;
4595 break;
4596 default:
4597 break;
4598 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004599 }
4600 }
4601 }
4602
4603 if (!skip)
4604 {
4605 Type *type = ResolveTypeUID(param_type_die_offset);
4606 if (type)
4607 {
Greg Claytonc93237c2010-10-01 20:48:32 +00004608 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00004609
Greg Clayton42ce2f32011-12-12 21:50:19 +00004610 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name,
4611 type->GetClangForwardType(),
4612 storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00004613 assert(param_var_decl);
4614 function_param_decls.push_back(param_var_decl);
Sean Callanan60217122012-04-13 00:10:03 +00004615
Greg Claytond0029442013-03-27 01:48:02 +00004616 GetClangASTContext().SetMetadataAsUserID (param_var_decl, MakeUserID(die->GetOffset()));
Greg Clayton0fffff52010-09-24 05:15:53 +00004617 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004618 }
4619 }
Greg Clayton7fedea22010-11-16 02:10:54 +00004620 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004621 }
4622 break;
4623
Greg Clayton03969752014-02-24 18:53:11 +00004624 case DW_TAG_unspecified_parameters:
4625 is_variadic = true;
4626 break;
4627
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00004628 case DW_TAG_template_type_parameter:
4629 case DW_TAG_template_value_parameter:
Greg Claytond20deac2014-04-04 18:15:18 +00004630 // The one caller of this was never using the template_param_infos,
4631 // and the local variable was taking up a large amount of stack space
4632 // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
4633 // the template params back, we can add them back.
4634 // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00004635 break;
4636
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004637 default:
4638 break;
4639 }
4640 }
Greg Clayton7fedea22010-11-16 02:10:54 +00004641 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004642}
4643
4644size_t
4645SymbolFileDWARF::ParseChildEnumerators
4646(
4647 const SymbolContext& sc,
Greg Clayton57ee3062013-07-11 22:46:58 +00004648 lldb_private::ClangASTType &clang_type,
Greg Clayton3e067532013-03-05 23:54:39 +00004649 bool is_signed,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004650 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00004651 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004652 const DWARFDebugInfoEntry *parent_die
4653)
4654{
4655 if (parent_die == NULL)
4656 return 0;
4657
4658 size_t enumerators_added = 0;
4659 const DWARFDebugInfoEntry *die;
Todd Fialaee8bfc62014-09-11 17:29:12 +00004660 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Greg Claytond88d7592010-09-15 08:33:30 +00004661
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004662 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
4663 {
4664 const dw_tag_t tag = die->Tag();
4665 if (tag == DW_TAG_enumerator)
4666 {
4667 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004668 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004669 if (num_child_attributes > 0)
4670 {
4671 const char *name = NULL;
4672 bool got_value = false;
4673 int64_t enum_value = 0;
4674 Declaration decl;
4675
4676 uint32_t i;
4677 for (i=0; i<num_child_attributes; ++i)
4678 {
4679 const dw_attr_t attr = attributes.AttributeAtIndex(i);
4680 DWARFFormValue form_value;
4681 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4682 {
4683 switch (attr)
4684 {
4685 case DW_AT_const_value:
4686 got_value = true;
Greg Clayton3e067532013-03-05 23:54:39 +00004687 if (is_signed)
4688 enum_value = form_value.Signed();
4689 else
4690 enum_value = form_value.Unsigned();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004691 break;
4692
4693 case DW_AT_name:
4694 name = form_value.AsCString(&get_debug_str_data());
4695 break;
4696
4697 case DW_AT_description:
4698 default:
4699 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4700 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4701 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4702 case DW_AT_sibling:
4703 break;
4704 }
4705 }
4706 }
4707
4708 if (name && name[0] && got_value)
4709 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00004710 clang_type.AddEnumerationValueToEnumerationType (clang_type.GetEnumerationIntegerType(),
4711 decl,
4712 name,
4713 enum_value,
4714 enumerator_byte_size * 8);
4715 ++enumerators_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004716 }
4717 }
4718 }
4719 }
4720 return enumerators_added;
4721}
4722
4723void
4724SymbolFileDWARF::ParseChildArrayInfo
4725(
4726 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004727 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004728 const DWARFDebugInfoEntry *parent_die,
4729 int64_t& first_index,
4730 std::vector<uint64_t>& element_orders,
4731 uint32_t& byte_stride,
4732 uint32_t& bit_stride
4733)
4734{
4735 if (parent_die == NULL)
4736 return;
4737
4738 const DWARFDebugInfoEntry *die;
Todd Fialaee8bfc62014-09-11 17:29:12 +00004739 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004740 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
4741 {
4742 const dw_tag_t tag = die->Tag();
4743 switch (tag)
4744 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004745 case DW_TAG_subrange_type:
4746 {
4747 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004748 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004749 if (num_child_attributes > 0)
4750 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004751 uint64_t num_elements = 0;
4752 uint64_t lower_bound = 0;
4753 uint64_t upper_bound = 0;
Greg Clayton4ef877f2012-12-06 02:33:54 +00004754 bool upper_bound_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004755 uint32_t i;
4756 for (i=0; i<num_child_attributes; ++i)
4757 {
4758 const dw_attr_t attr = attributes.AttributeAtIndex(i);
4759 DWARFFormValue form_value;
4760 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4761 {
4762 switch (attr)
4763 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004764 case DW_AT_name:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004765 break;
4766
4767 case DW_AT_count:
4768 num_elements = form_value.Unsigned();
4769 break;
4770
4771 case DW_AT_bit_stride:
4772 bit_stride = form_value.Unsigned();
4773 break;
4774
4775 case DW_AT_byte_stride:
4776 byte_stride = form_value.Unsigned();
4777 break;
4778
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004779 case DW_AT_lower_bound:
4780 lower_bound = form_value.Unsigned();
4781 break;
4782
4783 case DW_AT_upper_bound:
Greg Clayton4ef877f2012-12-06 02:33:54 +00004784 upper_bound_valid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004785 upper_bound = form_value.Unsigned();
4786 break;
4787
4788 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004789 case DW_AT_abstract_origin:
4790 case DW_AT_accessibility:
4791 case DW_AT_allocated:
4792 case DW_AT_associated:
4793 case DW_AT_data_location:
4794 case DW_AT_declaration:
4795 case DW_AT_description:
4796 case DW_AT_sibling:
4797 case DW_AT_threads_scaled:
4798 case DW_AT_type:
4799 case DW_AT_visibility:
4800 break;
4801 }
4802 }
4803 }
4804
Greg Claytone6a07792012-12-05 21:59:39 +00004805 if (num_elements == 0)
4806 {
Greg Clayton4ef877f2012-12-06 02:33:54 +00004807 if (upper_bound_valid && upper_bound >= lower_bound)
Greg Claytone6a07792012-12-05 21:59:39 +00004808 num_elements = upper_bound - lower_bound + 1;
4809 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004810
Sean Callananec979ba2012-10-22 23:56:48 +00004811 element_orders.push_back (num_elements);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004812 }
4813 }
4814 break;
4815 }
4816 }
4817}
4818
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004819TypeSP
Greg Clayton53eb1c22012-04-02 22:59:12 +00004820SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004821{
4822 TypeSP type_sp;
4823 if (die != NULL)
4824 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00004825 assert(dwarf_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00004826 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004827 if (type_ptr == NULL)
4828 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00004829 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(dwarf_cu);
Greg Claytonca512b32011-01-14 04:54:56 +00004830 assert (lldb_cu);
4831 SymbolContext sc(lldb_cu);
Greg Clayton53eb1c22012-04-02 22:59:12 +00004832 type_sp = ParseType(sc, dwarf_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004833 }
4834 else if (type_ptr != DIE_IS_BEING_PARSED)
4835 {
4836 // Grab the existing type from the master types lists
Greg Claytone1cd1be2012-01-29 20:56:30 +00004837 type_sp = type_ptr->shared_from_this();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004838 }
4839
4840 }
4841 return type_sp;
4842}
4843
4844clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00004845SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004846{
4847 if (die_offset != DW_INVALID_OFFSET)
4848 {
4849 DWARFCompileUnitSP cu_sp;
4850 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Greg Claytoncb5860a2011-10-13 23:49:28 +00004851 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004852 }
4853 return NULL;
4854}
4855
Sean Callanan72e49402011-08-05 23:43:37 +00004856clang::DeclContext *
4857SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
4858{
4859 if (die_offset != DW_INVALID_OFFSET)
4860 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004861 DWARFDebugInfo* debug_info = DebugInfo();
4862 if (debug_info)
4863 {
4864 DWARFCompileUnitSP cu_sp;
4865 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
4866 if (die)
4867 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
4868 }
Sean Callanan72e49402011-08-05 23:43:37 +00004869 }
4870 return NULL;
4871}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004872
Greg Clayton96d7d742010-11-10 23:42:09 +00004873clang::NamespaceDecl *
Greg Clayton53eb1c22012-04-02 22:59:12 +00004874SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry *die)
Greg Clayton96d7d742010-11-10 23:42:09 +00004875{
Greg Clayton030a2042011-10-14 21:34:45 +00004876 if (die && die->Tag() == DW_TAG_namespace)
Greg Clayton96d7d742010-11-10 23:42:09 +00004877 {
Greg Clayton030a2042011-10-14 21:34:45 +00004878 // See if we already parsed this namespace DIE and associated it with a
4879 // uniqued namespace declaration
4880 clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
4881 if (namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00004882 return namespace_decl;
Greg Clayton030a2042011-10-14 21:34:45 +00004883 else
4884 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00004885 const char *namespace_name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL);
4886 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, NULL);
Greg Clayton9d3d6882011-10-31 23:51:19 +00004887 namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
Greg Clayton5160ce52013-03-27 23:08:40 +00004888 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton9d3d6882011-10-31 23:51:19 +00004889 if (log)
Greg Clayton030a2042011-10-14 21:34:45 +00004890 {
Greg Clayton9d3d6882011-10-31 23:51:19 +00004891 if (namespace_name)
Greg Clayton030a2042011-10-14 21:34:45 +00004892 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004893 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00004894 "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 +00004895 static_cast<void*>(GetClangASTContext().getASTContext()),
Greg Claytone38a5ed2012-01-05 03:57:59 +00004896 MakeUserID(die->GetOffset()),
4897 namespace_name,
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004898 static_cast<void*>(namespace_decl),
4899 static_cast<void*>(namespace_decl->getOriginalNamespace()));
Greg Clayton030a2042011-10-14 21:34:45 +00004900 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00004901 else
4902 {
Greg Clayton5160ce52013-03-27 23:08:40 +00004903 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00004904 "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004905 static_cast<void*>(GetClangASTContext().getASTContext()),
Greg Claytone38a5ed2012-01-05 03:57:59 +00004906 MakeUserID(die->GetOffset()),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004907 static_cast<void*>(namespace_decl),
4908 static_cast<void*>(namespace_decl->getOriginalNamespace()));
Greg Clayton9d3d6882011-10-31 23:51:19 +00004909 }
Greg Clayton030a2042011-10-14 21:34:45 +00004910 }
Greg Clayton9d3d6882011-10-31 23:51:19 +00004911
4912 if (namespace_decl)
4913 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
4914 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00004915 }
4916 }
4917 return NULL;
4918}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004919
4920clang::DeclContext *
Greg Claytoncab36a32011-12-08 05:16:30 +00004921SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
Sean Callanan72e49402011-08-05 23:43:37 +00004922{
Greg Clayton5cf58b92011-10-05 22:22:08 +00004923 clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
4924 if (clang_decl_ctx)
4925 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00004926 // If this DIE has a specification, or an abstract origin, then trace to those.
4927
Greg Claytoncab36a32011-12-08 05:16:30 +00004928 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
Sean Callanan72e49402011-08-05 23:43:37 +00004929 if (die_offset != DW_INVALID_OFFSET)
4930 return GetClangDeclContextForDIEOffset (sc, die_offset);
4931
Greg Claytoncab36a32011-12-08 05:16:30 +00004932 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
Sean Callanan72e49402011-08-05 23:43:37 +00004933 if (die_offset != DW_INVALID_OFFSET)
4934 return GetClangDeclContextForDIEOffset (sc, die_offset);
4935
Greg Clayton5160ce52013-03-27 23:08:40 +00004936 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00004937 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00004938 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 +00004939 // This is the DIE we want. Parse it, then query our map.
Greg Claytoncab36a32011-12-08 05:16:30 +00004940 bool assert_not_being_parsed = true;
4941 ResolveTypeUID (cu, die, assert_not_being_parsed);
4942
Greg Clayton5cf58b92011-10-05 22:22:08 +00004943 clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
4944
4945 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00004946}
4947
4948clang::DeclContext *
Greg Claytoncb5860a2011-10-13 23:49:28 +00004949SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004950{
Greg Claytonca512b32011-01-14 04:54:56 +00004951 if (m_clang_tu_decl == NULL)
4952 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004953
Greg Clayton2bc22f82011-09-30 03:20:47 +00004954 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
Greg Claytoncb5860a2011-10-13 23:49:28 +00004955
4956 if (decl_ctx_die_copy)
4957 *decl_ctx_die_copy = decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00004958
4959 if (decl_ctx_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004960 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00004961
Greg Clayton2bc22f82011-09-30 03:20:47 +00004962 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
4963 if (pos != m_die_to_decl_ctx.end())
4964 return pos->second;
4965
4966 switch (decl_ctx_die->Tag())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004967 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00004968 case DW_TAG_compile_unit:
4969 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004970
Greg Clayton2bc22f82011-09-30 03:20:47 +00004971 case DW_TAG_namespace:
Greg Clayton030a2042011-10-14 21:34:45 +00004972 return ResolveNamespaceDIE (cu, decl_ctx_die);
Greg Clayton2bc22f82011-09-30 03:20:47 +00004973 break;
4974
4975 case DW_TAG_structure_type:
4976 case DW_TAG_union_type:
4977 case DW_TAG_class_type:
4978 {
4979 Type* type = ResolveType (cu, decl_ctx_die);
4980 if (type)
4981 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00004982 clang::DeclContext *decl_ctx = type->GetClangForwardType().GetDeclContextForType ();
Greg Clayton2bc22f82011-09-30 03:20:47 +00004983 if (decl_ctx)
Greg Claytonca512b32011-01-14 04:54:56 +00004984 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00004985 LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
4986 if (decl_ctx)
4987 return decl_ctx;
Greg Claytonca512b32011-01-14 04:54:56 +00004988 }
4989 }
Greg Claytonca512b32011-01-14 04:54:56 +00004990 }
Greg Clayton2bc22f82011-09-30 03:20:47 +00004991 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004992
Greg Clayton2bc22f82011-09-30 03:20:47 +00004993 default:
4994 break;
Greg Claytonca512b32011-01-14 04:54:56 +00004995 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004996 }
Greg Clayton7a345282010-11-09 23:46:37 +00004997 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004998}
4999
Greg Clayton2bc22f82011-09-30 03:20:47 +00005000
5001const DWARFDebugInfoEntry *
5002SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
5003{
5004 if (cu && die)
5005 {
5006 const DWARFDebugInfoEntry * const decl_die = die;
5007
5008 while (die != NULL)
5009 {
5010 // If this is the original DIE that we are searching for a declaration
5011 // for, then don't look in the cache as we don't want our own decl
5012 // context to be our decl context...
5013 if (decl_die != die)
5014 {
5015 switch (die->Tag())
5016 {
5017 case DW_TAG_compile_unit:
5018 case DW_TAG_namespace:
5019 case DW_TAG_structure_type:
5020 case DW_TAG_union_type:
5021 case DW_TAG_class_type:
5022 return die;
5023
5024 default:
5025 break;
5026 }
5027 }
5028
5029 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
5030 if (die_offset != DW_INVALID_OFFSET)
5031 {
5032 DWARFCompileUnit *spec_cu = cu;
5033 const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
5034 const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
5035 if (spec_die_decl_ctx_die)
5036 return spec_die_decl_ctx_die;
5037 }
5038
5039 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
5040 if (die_offset != DW_INVALID_OFFSET)
5041 {
5042 DWARFCompileUnit *abs_cu = cu;
5043 const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
5044 const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
5045 if (abs_die_decl_ctx_die)
5046 return abs_die_decl_ctx_die;
5047 }
5048
5049 die = die->GetParent();
5050 }
5051 }
5052 return NULL;
5053}
5054
5055
Greg Clayton901c5ca2011-12-03 04:40:03 +00005056Symbol *
5057SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
5058{
5059 Symbol *objc_class_symbol = NULL;
5060 if (m_obj_file)
5061 {
Greg Clayton3046e662013-07-10 01:23:25 +00005062 Symtab *symtab = m_obj_file->GetSymtab ();
Greg Clayton901c5ca2011-12-03 04:40:03 +00005063 if (symtab)
5064 {
5065 objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
5066 eSymbolTypeObjCClass,
5067 Symtab::eDebugNo,
5068 Symtab::eVisibilityAny);
5069 }
5070 }
5071 return objc_class_symbol;
5072}
5073
Greg Claytonc7f03b62012-01-12 04:33:28 +00005074// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
5075// then we can end up looking through all class types for a complete type and never find
5076// the full definition. We need to know if this attribute is supported, so we determine
5077// this here and cache th result. We also need to worry about the debug map DWARF file
5078// if we are doing darwin DWARF in .o file debugging.
5079bool
5080SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
5081{
5082 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
5083 {
5084 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
5085 if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
5086 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
5087 else
5088 {
5089 DWARFDebugInfo* debug_info = DebugInfo();
5090 const uint32_t num_compile_units = GetNumCompileUnits();
5091 for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
5092 {
Greg Clayton53eb1c22012-04-02 22:59:12 +00005093 DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
5094 if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
Greg Claytonc7f03b62012-01-12 04:33:28 +00005095 {
5096 m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
5097 break;
5098 }
5099 }
5100 }
Greg Clayton1f746072012-08-29 21:13:06 +00005101 if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
Greg Claytonc7f03b62012-01-12 04:33:28 +00005102 return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
5103 }
5104 return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
5105}
Greg Clayton901c5ca2011-12-03 04:40:03 +00005106
5107// This function can be used when a DIE is found that is a forward declaration
5108// DIE and we want to try and find a type that has the complete definition.
5109TypeSP
Greg Claytonc7f03b62012-01-12 04:33:28 +00005110SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
5111 const ConstString &type_name,
5112 bool must_be_implementation)
Greg Clayton901c5ca2011-12-03 04:40:03 +00005113{
5114
5115 TypeSP type_sp;
5116
Greg Claytonc7f03b62012-01-12 04:33:28 +00005117 if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
Greg Clayton901c5ca2011-12-03 04:40:03 +00005118 return type_sp;
5119
5120 DIEArray die_offsets;
5121
5122 if (m_using_apple_tables)
5123 {
5124 if (m_apple_types_ap.get())
5125 {
5126 const char *name_cstr = type_name.GetCString();
Greg Clayton68221ec2012-01-18 20:58:12 +00005127 m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
Greg Clayton901c5ca2011-12-03 04:40:03 +00005128 }
5129 }
5130 else
5131 {
5132 if (!m_indexed)
5133 Index ();
5134
5135 m_type_index.Find (type_name, die_offsets);
5136 }
5137
Greg Clayton901c5ca2011-12-03 04:40:03 +00005138 const size_t num_matches = die_offsets.size();
5139
Greg Clayton901c5ca2011-12-03 04:40:03 +00005140 DWARFCompileUnit* type_cu = NULL;
5141 const DWARFDebugInfoEntry* type_die = NULL;
5142 if (num_matches)
5143 {
5144 DWARFDebugInfo* debug_info = DebugInfo();
5145 for (size_t i=0; i<num_matches; ++i)
5146 {
5147 const dw_offset_t die_offset = die_offsets[i];
5148 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
5149
5150 if (type_die)
5151 {
5152 bool try_resolving_type = false;
5153
5154 // Don't try and resolve the DIE we are looking for with the DIE itself!
5155 if (type_die != die)
5156 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00005157 switch (type_die->Tag())
Greg Clayton901c5ca2011-12-03 04:40:03 +00005158 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00005159 case DW_TAG_class_type:
5160 case DW_TAG_structure_type:
5161 try_resolving_type = true;
5162 break;
5163 default:
5164 break;
Greg Clayton901c5ca2011-12-03 04:40:03 +00005165 }
5166 }
5167
5168 if (try_resolving_type)
5169 {
Ed Maste4c24b122013-10-17 20:13:14 +00005170 if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type())
5171 try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0);
Greg Clayton901c5ca2011-12-03 04:40:03 +00005172
5173 if (try_resolving_type)
5174 {
5175 Type *resolved_type = ResolveType (type_cu, type_die, false);
5176 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
5177 {
Ed Mastea0191d12013-10-17 20:42:56 +00005178 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 +00005179 MakeUserID(die->GetOffset()),
Jim Ingham4af59612014-12-19 19:20:44 +00005180 m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
Greg Clayton901c5ca2011-12-03 04:40:03 +00005181 MakeUserID(type_die->GetOffset()),
5182 MakeUserID(type_cu->GetOffset()));
5183
Greg Claytonc7f03b62012-01-12 04:33:28 +00005184 if (die)
5185 m_die_to_type[die] = resolved_type;
Greg Claytone1cd1be2012-01-29 20:56:30 +00005186 type_sp = resolved_type->shared_from_this();
Greg Clayton901c5ca2011-12-03 04:40:03 +00005187 break;
5188 }
5189 }
5190 }
5191 }
5192 else
5193 {
5194 if (m_using_apple_tables)
5195 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00005196 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
5197 die_offset, type_name.GetCString());
Greg Clayton901c5ca2011-12-03 04:40:03 +00005198 }
5199 }
5200
5201 }
5202 }
5203 return type_sp;
5204}
5205
Greg Claytona8022fa2012-04-24 21:22:41 +00005206
Greg Clayton80c26302012-02-05 06:12:47 +00005207//----------------------------------------------------------------------
5208// This function helps to ensure that the declaration contexts match for
5209// two different DIEs. Often times debug information will refer to a
5210// forward declaration of a type (the equivalent of "struct my_struct;".
5211// There will often be a declaration of that type elsewhere that has the
5212// full definition. When we go looking for the full type "my_struct", we
5213// will find one or more matches in the accelerator tables and we will
5214// then need to make sure the type was in the same declaration context
5215// as the original DIE. This function can efficiently compare two DIEs
5216// and will return true when the declaration context matches, and false
5217// when they don't.
5218//----------------------------------------------------------------------
Greg Clayton890ff562012-02-02 05:48:16 +00005219bool
5220SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1,
5221 DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2)
5222{
Greg Claytona8022fa2012-04-24 21:22:41 +00005223 if (die1 == die2)
5224 return true;
5225
5226#if defined (LLDB_CONFIGURATION_DEBUG)
5227 // You can't and shouldn't call this function with a compile unit from
5228 // two different SymbolFileDWARF instances.
5229 assert (DebugInfo()->ContainsCompileUnit (cu1));
5230 assert (DebugInfo()->ContainsCompileUnit (cu2));
5231#endif
5232
Greg Clayton890ff562012-02-02 05:48:16 +00005233 DWARFDIECollection decl_ctx_1;
5234 DWARFDIECollection decl_ctx_2;
Greg Clayton80c26302012-02-05 06:12:47 +00005235 //The declaration DIE stack is a stack of the declaration context
5236 // DIEs all the way back to the compile unit. If a type "T" is
5237 // declared inside a class "B", and class "B" is declared inside
5238 // a class "A" and class "A" is in a namespace "lldb", and the
5239 // namespace is in a compile unit, there will be a stack of DIEs:
5240 //
5241 // [0] DW_TAG_class_type for "B"
5242 // [1] DW_TAG_class_type for "A"
5243 // [2] DW_TAG_namespace for "lldb"
5244 // [3] DW_TAG_compile_unit for the source file.
5245 //
5246 // We grab both contexts and make sure that everything matches
5247 // all the way back to the compiler unit.
5248
5249 // First lets grab the decl contexts for both DIEs
Greg Clayton890ff562012-02-02 05:48:16 +00005250 die1->GetDeclContextDIEs (this, cu1, decl_ctx_1);
Sean Callanan5b26f272012-02-04 08:49:35 +00005251 die2->GetDeclContextDIEs (this, cu2, decl_ctx_2);
Greg Clayton80c26302012-02-05 06:12:47 +00005252 // Make sure the context arrays have the same size, otherwise
5253 // we are done
Greg Clayton890ff562012-02-02 05:48:16 +00005254 const size_t count1 = decl_ctx_1.Size();
5255 const size_t count2 = decl_ctx_2.Size();
5256 if (count1 != count2)
5257 return false;
Greg Clayton80c26302012-02-05 06:12:47 +00005258
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00005259 // Make sure the DW_TAG values match all the way back up the
Greg Clayton80c26302012-02-05 06:12:47 +00005260 // compile unit. If they don't, then we are done.
Greg Clayton890ff562012-02-02 05:48:16 +00005261 const DWARFDebugInfoEntry *decl_ctx_die1;
5262 const DWARFDebugInfoEntry *decl_ctx_die2;
5263 size_t i;
5264 for (i=0; i<count1; i++)
5265 {
5266 decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
5267 decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
5268 if (decl_ctx_die1->Tag() != decl_ctx_die2->Tag())
5269 return false;
5270 }
Greg Clayton890ff562012-02-02 05:48:16 +00005271#if defined LLDB_CONFIGURATION_DEBUG
Greg Clayton80c26302012-02-05 06:12:47 +00005272
5273 // Make sure the top item in the decl context die array is always
5274 // DW_TAG_compile_unit. If it isn't then something went wrong in
5275 // the DWARFDebugInfoEntry::GetDeclContextDIEs() function...
Greg Clayton890ff562012-02-02 05:48:16 +00005276 assert (decl_ctx_1.GetDIEPtrAtIndex (count1 - 1)->Tag() == DW_TAG_compile_unit);
Greg Clayton80c26302012-02-05 06:12:47 +00005277
Greg Clayton890ff562012-02-02 05:48:16 +00005278#endif
5279 // Always skip the compile unit when comparing by only iterating up to
Greg Clayton80c26302012-02-05 06:12:47 +00005280 // "count - 1". Here we compare the names as we go.
Greg Clayton890ff562012-02-02 05:48:16 +00005281 for (i=0; i<count1 - 1; i++)
5282 {
5283 decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
5284 decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
5285 const char *name1 = decl_ctx_die1->GetName(this, cu1);
Sean Callanan5b26f272012-02-04 08:49:35 +00005286 const char *name2 = decl_ctx_die2->GetName(this, cu2);
Greg Clayton890ff562012-02-02 05:48:16 +00005287 // If the string was from a DW_FORM_strp, then the pointer will often
5288 // be the same!
Greg Clayton5569e642012-02-06 01:44:54 +00005289 if (name1 == name2)
5290 continue;
5291
5292 // Name pointers are not equal, so only compare the strings
5293 // if both are not NULL.
5294 if (name1 && name2)
Greg Clayton890ff562012-02-02 05:48:16 +00005295 {
Greg Clayton5569e642012-02-06 01:44:54 +00005296 // If the strings don't compare, we are done...
5297 if (strcmp(name1, name2) != 0)
Greg Clayton890ff562012-02-02 05:48:16 +00005298 return false;
Greg Clayton5569e642012-02-06 01:44:54 +00005299 }
5300 else
5301 {
5302 // One name was NULL while the other wasn't
5303 return false;
Greg Clayton890ff562012-02-02 05:48:16 +00005304 }
5305 }
Greg Clayton80c26302012-02-05 06:12:47 +00005306 // We made it through all of the checks and the declaration contexts
5307 // are equal.
Greg Clayton890ff562012-02-02 05:48:16 +00005308 return true;
5309}
Greg Clayton220a0072011-12-09 08:48:30 +00005310
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00005311
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005312TypeSP
Greg Claytona8022fa2012-04-24 21:22:41 +00005313SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
5314{
5315 TypeSP type_sp;
5316
5317 const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
5318 if (dwarf_decl_ctx_count > 0)
5319 {
5320 const ConstString type_name(dwarf_decl_ctx[0].name);
5321 const dw_tag_t tag = dwarf_decl_ctx[0].tag;
5322
5323 if (type_name)
5324 {
Greg Clayton5160ce52013-03-27 23:08:40 +00005325 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
Greg Claytona8022fa2012-04-24 21:22:41 +00005326 if (log)
5327 {
Greg Clayton5160ce52013-03-27 23:08:40 +00005328 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00005329 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
5330 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
5331 dwarf_decl_ctx.GetQualifiedName());
5332 }
5333
5334 DIEArray die_offsets;
5335
5336 if (m_using_apple_tables)
5337 {
5338 if (m_apple_types_ap.get())
5339 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00005340 const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
5341 const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
5342 if (has_tag && has_qualified_name_hash)
Greg Claytona8022fa2012-04-24 21:22:41 +00005343 {
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00005344 const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
5345 const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
5346 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005347 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
Greg Claytoncb9c8cf2013-02-06 23:56:13 +00005348 m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
5349 }
5350 else if (has_tag)
5351 {
5352 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005353 GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
Greg Claytona8022fa2012-04-24 21:22:41 +00005354 m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
5355 }
5356 else
5357 {
5358 m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
5359 }
5360 }
5361 }
5362 else
5363 {
5364 if (!m_indexed)
5365 Index ();
5366
5367 m_type_index.Find (type_name, die_offsets);
5368 }
5369
5370 const size_t num_matches = die_offsets.size();
5371
5372
5373 DWARFCompileUnit* type_cu = NULL;
5374 const DWARFDebugInfoEntry* type_die = NULL;
5375 if (num_matches)
5376 {
5377 DWARFDebugInfo* debug_info = DebugInfo();
5378 for (size_t i=0; i<num_matches; ++i)
5379 {
5380 const dw_offset_t die_offset = die_offsets[i];
5381 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
5382
5383 if (type_die)
5384 {
5385 bool try_resolving_type = false;
5386
5387 // Don't try and resolve the DIE we are looking for with the DIE itself!
5388 const dw_tag_t type_tag = type_die->Tag();
5389 // Make sure the tags match
5390 if (type_tag == tag)
5391 {
5392 // The tags match, lets try resolving this type
5393 try_resolving_type = true;
5394 }
5395 else
5396 {
5397 // The tags don't match, but we need to watch our for a
5398 // forward declaration for a struct and ("struct foo")
5399 // ends up being a class ("class foo { ... };") or
5400 // vice versa.
5401 switch (type_tag)
5402 {
5403 case DW_TAG_class_type:
5404 // We had a "class foo", see if we ended up with a "struct foo { ... };"
5405 try_resolving_type = (tag == DW_TAG_structure_type);
5406 break;
5407 case DW_TAG_structure_type:
5408 // We had a "struct foo", see if we ended up with a "class foo { ... };"
5409 try_resolving_type = (tag == DW_TAG_class_type);
5410 break;
5411 default:
5412 // Tags don't match, don't event try to resolve
5413 // using this type whose name matches....
5414 break;
5415 }
5416 }
5417
5418 if (try_resolving_type)
5419 {
5420 DWARFDeclContext type_dwarf_decl_ctx;
5421 type_die->GetDWARFDeclContext (this, type_cu, type_dwarf_decl_ctx);
5422
5423 if (log)
5424 {
Greg Clayton5160ce52013-03-27 23:08:40 +00005425 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00005426 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
5427 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
5428 dwarf_decl_ctx.GetQualifiedName(),
5429 type_die->GetOffset(),
5430 type_dwarf_decl_ctx.GetQualifiedName());
5431 }
5432
5433 // Make sure the decl contexts match all the way up
5434 if (dwarf_decl_ctx == type_dwarf_decl_ctx)
5435 {
5436 Type *resolved_type = ResolveType (type_cu, type_die, false);
5437 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
5438 {
5439 type_sp = resolved_type->shared_from_this();
5440 break;
5441 }
5442 }
5443 }
5444 else
5445 {
5446 if (log)
5447 {
5448 std::string qualified_name;
5449 type_die->GetQualifiedName(this, type_cu, qualified_name);
Greg Clayton5160ce52013-03-27 23:08:40 +00005450 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytona8022fa2012-04-24 21:22:41 +00005451 "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
5452 DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
5453 dwarf_decl_ctx.GetQualifiedName(),
5454 type_die->GetOffset(),
5455 qualified_name.c_str());
5456 }
5457 }
5458 }
5459 else
5460 {
5461 if (m_using_apple_tables)
5462 {
5463 GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
5464 die_offset, type_name.GetCString());
5465 }
5466 }
5467
5468 }
5469 }
5470 }
5471 }
5472 return type_sp;
5473}
5474
Greg Clayton4116e932012-05-15 02:33:01 +00005475bool
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005476SymbolFileDWARF::CopyUniqueClassMethodTypes (SymbolFileDWARF *src_symfile,
Sean Callanan2367f8a2013-02-26 01:12:25 +00005477 Type *class_type,
Greg Clayton4116e932012-05-15 02:33:01 +00005478 DWARFCompileUnit* src_cu,
5479 const DWARFDebugInfoEntry *src_class_die,
5480 DWARFCompileUnit* dst_cu,
Sean Callanan2367f8a2013-02-26 01:12:25 +00005481 const DWARFDebugInfoEntry *dst_class_die,
Greg Claytond20deac2014-04-04 18:15:18 +00005482 DWARFDIECollection &failures)
Greg Clayton4116e932012-05-15 02:33:01 +00005483{
5484 if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
5485 return false;
5486 if (src_class_die->Tag() != dst_class_die->Tag())
5487 return false;
5488
5489 // We need to complete the class type so we can get all of the method types
5490 // parsed so we can then unique those types to their equivalent counterparts
5491 // in "dst_cu" and "dst_class_die"
5492 class_type->GetClangFullType();
5493
5494 const DWARFDebugInfoEntry *src_die;
5495 const DWARFDebugInfoEntry *dst_die;
5496 UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die;
5497 UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die;
Greg Clayton65ec1032012-11-12 21:27:20 +00005498 UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die_artificial;
5499 UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die_artificial;
Greg Clayton4116e932012-05-15 02:33:01 +00005500 for (src_die = src_class_die->GetFirstChild(); src_die != NULL; src_die = src_die->GetSibling())
5501 {
5502 if (src_die->Tag() == DW_TAG_subprogram)
5503 {
Greg Clayton84afacd2012-11-07 23:09:32 +00005504 // Make sure this is a declaration and not a concrete instance by looking
5505 // for DW_AT_declaration set to 1. Sometimes concrete function instances
5506 // are placed inside the class definitions and shouldn't be included in
5507 // the list of things are are tracking here.
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005508 if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_declaration, 0) == 1)
Greg Clayton84afacd2012-11-07 23:09:32 +00005509 {
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005510 const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
Greg Clayton84afacd2012-11-07 23:09:32 +00005511 if (src_name)
Greg Clayton65ec1032012-11-12 21:27:20 +00005512 {
5513 ConstString src_const_name(src_name);
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005514 if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_artificial, 0))
Greg Clayton65ec1032012-11-12 21:27:20 +00005515 src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
5516 else
5517 src_name_to_die.Append(src_const_name.GetCString(), src_die);
5518 }
Greg Clayton84afacd2012-11-07 23:09:32 +00005519 }
Greg Clayton4116e932012-05-15 02:33:01 +00005520 }
5521 }
5522 for (dst_die = dst_class_die->GetFirstChild(); dst_die != NULL; dst_die = dst_die->GetSibling())
5523 {
5524 if (dst_die->Tag() == DW_TAG_subprogram)
5525 {
Greg Clayton84afacd2012-11-07 23:09:32 +00005526 // Make sure this is a declaration and not a concrete instance by looking
5527 // for DW_AT_declaration set to 1. Sometimes concrete function instances
5528 // are placed inside the class definitions and shouldn't be included in
5529 // the list of things are are tracking here.
5530 if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_declaration, 0) == 1)
5531 {
5532 const char *dst_name = dst_die->GetMangledName (this, dst_cu);
5533 if (dst_name)
Greg Clayton65ec1032012-11-12 21:27:20 +00005534 {
5535 ConstString dst_const_name(dst_name);
5536 if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_artificial, 0))
5537 dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die);
5538 else
5539 dst_name_to_die.Append(dst_const_name.GetCString(), dst_die);
5540 }
Greg Clayton84afacd2012-11-07 23:09:32 +00005541 }
Greg Clayton4116e932012-05-15 02:33:01 +00005542 }
5543 }
5544 const uint32_t src_size = src_name_to_die.GetSize ();
5545 const uint32_t dst_size = dst_name_to_die.GetSize ();
Greg Clayton5160ce52013-03-27 23:08:40 +00005546 Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
Sean Callanan2367f8a2013-02-26 01:12:25 +00005547
5548 // Is everything kosher so we can go through the members at top speed?
5549 bool fast_path = true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005550
Sean Callanan2367f8a2013-02-26 01:12:25 +00005551 if (src_size != dst_size)
Greg Clayton4116e932012-05-15 02:33:01 +00005552 {
Sean Callanan2367f8a2013-02-26 01:12:25 +00005553 if (src_size != 0 && dst_size != 0)
5554 {
5555 if (log)
5556 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)",
5557 src_class_die->GetOffset(),
5558 dst_class_die->GetOffset(),
5559 src_size,
5560 dst_size);
5561 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005562
Sean Callanan2367f8a2013-02-26 01:12:25 +00005563 fast_path = false;
5564 }
5565
5566 uint32_t idx;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005567
Sean Callanan2367f8a2013-02-26 01:12:25 +00005568 if (fast_path)
5569 {
Greg Clayton4116e932012-05-15 02:33:01 +00005570 for (idx = 0; idx < src_size; ++idx)
5571 {
5572 src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
5573 dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
5574
5575 if (src_die->Tag() != dst_die->Tag())
5576 {
5577 if (log)
5578 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)",
5579 src_class_die->GetOffset(),
5580 dst_class_die->GetOffset(),
5581 src_die->GetOffset(),
5582 DW_TAG_value_to_name(src_die->Tag()),
5583 dst_die->GetOffset(),
5584 DW_TAG_value_to_name(src_die->Tag()));
Sean Callanan2367f8a2013-02-26 01:12:25 +00005585 fast_path = false;
Greg Clayton4116e932012-05-15 02:33:01 +00005586 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005587
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005588 const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
Greg Clayton4116e932012-05-15 02:33:01 +00005589 const char *dst_name = dst_die->GetMangledName (this, dst_cu);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005590
Greg Clayton4116e932012-05-15 02:33:01 +00005591 // Make sure the names match
5592 if (src_name == dst_name || (strcmp (src_name, dst_name) == 0))
5593 continue;
5594
5595 if (log)
5596 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)",
5597 src_class_die->GetOffset(),
5598 dst_class_die->GetOffset(),
5599 src_die->GetOffset(),
5600 src_name,
5601 dst_die->GetOffset(),
5602 dst_name);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005603
Sean Callanan2367f8a2013-02-26 01:12:25 +00005604 fast_path = false;
Greg Clayton4116e932012-05-15 02:33:01 +00005605 }
Sean Callanan2367f8a2013-02-26 01:12:25 +00005606 }
Greg Clayton4116e932012-05-15 02:33:01 +00005607
Sean Callanan2367f8a2013-02-26 01:12:25 +00005608 // Now do the work of linking the DeclContexts and Types.
5609 if (fast_path)
5610 {
5611 // We can do this quickly. Just run across the tables index-for-index since
5612 // we know each node has matching names and tags.
Greg Clayton4116e932012-05-15 02:33:01 +00005613 for (idx = 0; idx < src_size; ++idx)
5614 {
5615 src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
5616 dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005617
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005618 clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
Greg Clayton4116e932012-05-15 02:33:01 +00005619 if (src_decl_ctx)
5620 {
5621 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005622 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
5623 static_cast<void*>(src_decl_ctx),
5624 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton4116e932012-05-15 02:33:01 +00005625 LinkDeclContextToDIE (src_decl_ctx, dst_die);
5626 }
5627 else
5628 {
5629 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005630 log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found",
5631 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton4116e932012-05-15 02:33:01 +00005632 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005633
Greg Clayton4116e932012-05-15 02:33:01 +00005634 Type *src_child_type = m_die_to_type[src_die];
5635 if (src_child_type)
5636 {
5637 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005638 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
5639 static_cast<void*>(src_child_type),
5640 src_child_type->GetID(),
5641 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton4116e932012-05-15 02:33:01 +00005642 m_die_to_type[dst_die] = src_child_type;
5643 }
5644 else
5645 {
5646 if (log)
Greg Clayton65ec1032012-11-12 21:27:20 +00005647 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());
5648 }
5649 }
Sean Callanan2367f8a2013-02-26 01:12:25 +00005650 }
5651 else
5652 {
5653 // We must do this slowly. For each member of the destination, look
5654 // up a member in the source with the same name, check its tag, and
5655 // unique them if everything matches up. Report failures.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005656
Sean Callanan2367f8a2013-02-26 01:12:25 +00005657 if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
5658 {
5659 src_name_to_die.Sort();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005660
Sean Callanan2367f8a2013-02-26 01:12:25 +00005661 for (idx = 0; idx < dst_size; ++idx)
5662 {
5663 const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
5664 dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
5665 src_die = src_name_to_die.Find(dst_name, NULL);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005666
Sean Callanan2367f8a2013-02-26 01:12:25 +00005667 if (src_die && (src_die->Tag() == dst_die->Tag()))
5668 {
Greg Clayton5d650c6a2013-02-26 01:31:37 +00005669 clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
Sean Callanan2367f8a2013-02-26 01:12:25 +00005670 if (src_decl_ctx)
5671 {
5672 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005673 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
5674 static_cast<void*>(src_decl_ctx),
5675 src_die->GetOffset(),
5676 dst_die->GetOffset());
Sean Callanan2367f8a2013-02-26 01:12:25 +00005677 LinkDeclContextToDIE (src_decl_ctx, dst_die);
5678 }
5679 else
5680 {
5681 if (log)
5682 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());
5683 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005684
Sean Callanan2367f8a2013-02-26 01:12:25 +00005685 Type *src_child_type = m_die_to_type[src_die];
5686 if (src_child_type)
5687 {
5688 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005689 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
5690 static_cast<void*>(src_child_type),
5691 src_child_type->GetID(),
5692 src_die->GetOffset(),
5693 dst_die->GetOffset());
Sean Callanan2367f8a2013-02-26 01:12:25 +00005694 m_die_to_type[dst_die] = src_child_type;
5695 }
5696 else
5697 {
5698 if (log)
5699 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());
5700 }
5701 }
5702 else
5703 {
5704 if (log)
5705 log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die->GetOffset());
Greg Clayton65ec1032012-11-12 21:27:20 +00005706
Greg Claytond20deac2014-04-04 18:15:18 +00005707 failures.Append(dst_die);
Sean Callanan2367f8a2013-02-26 01:12:25 +00005708 }
5709 }
5710 }
5711 }
5712
5713 const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
5714 const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
5715
5716 UniqueCStringMap<const DWARFDebugInfoEntry *> name_to_die_artificial_not_in_src;
5717
5718 if (src_size_artificial && dst_size_artificial)
5719 {
5720 dst_name_to_die_artificial.Sort();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005721
Greg Clayton65ec1032012-11-12 21:27:20 +00005722 for (idx = 0; idx < src_size_artificial; ++idx)
5723 {
5724 const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
5725 src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
5726 dst_die = dst_name_to_die_artificial.Find(src_name_artificial, NULL);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005727
Greg Clayton65ec1032012-11-12 21:27:20 +00005728 if (dst_die)
5729 {
Greg Clayton65ec1032012-11-12 21:27:20 +00005730 // Both classes have the artificial types, link them
5731 clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
5732 if (src_decl_ctx)
5733 {
5734 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005735 log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
5736 static_cast<void*>(src_decl_ctx),
5737 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton65ec1032012-11-12 21:27:20 +00005738 LinkDeclContextToDIE (src_decl_ctx, dst_die);
5739 }
5740 else
5741 {
5742 if (log)
5743 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());
5744 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005745
Greg Clayton65ec1032012-11-12 21:27:20 +00005746 Type *src_child_type = m_die_to_type[src_die];
5747 if (src_child_type)
5748 {
5749 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005750 log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
5751 static_cast<void*>(src_child_type),
5752 src_child_type->GetID(),
5753 src_die->GetOffset(), dst_die->GetOffset());
Greg Clayton65ec1032012-11-12 21:27:20 +00005754 m_die_to_type[dst_die] = src_child_type;
5755 }
5756 else
5757 {
5758 if (log)
5759 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());
5760 }
5761 }
5762 }
Sean Callanan2367f8a2013-02-26 01:12:25 +00005763 }
Greg Clayton65ec1032012-11-12 21:27:20 +00005764
Sean Callanan2367f8a2013-02-26 01:12:25 +00005765 if (dst_size_artificial)
Greg Clayton4116e932012-05-15 02:33:01 +00005766 {
Sean Callanan2367f8a2013-02-26 01:12:25 +00005767 for (idx = 0; idx < dst_size_artificial; ++idx)
5768 {
5769 const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
5770 dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
5771 if (log)
5772 log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
5773
Greg Claytond20deac2014-04-04 18:15:18 +00005774 failures.Append(dst_die);
Sean Callanan2367f8a2013-02-26 01:12:25 +00005775 }
Greg Clayton4116e932012-05-15 02:33:01 +00005776 }
Sean Callanan2367f8a2013-02-26 01:12:25 +00005777
Greg Claytond20deac2014-04-04 18:15:18 +00005778 return (failures.Size() != 0);
Greg Clayton4116e932012-05-15 02:33:01 +00005779}
Greg Claytona8022fa2012-04-24 21:22:41 +00005780
5781TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00005782SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005783{
5784 TypeSP type_sp;
5785
Greg Clayton1be10fc2010-09-29 01:12:09 +00005786 if (type_is_new_ptr)
5787 *type_is_new_ptr = false;
Greg Clayton1fba87112012-02-09 20:03:49 +00005788
Todd Fiala0a70a842014-05-28 16:43:26 +00005789#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
Greg Clayton1fba87112012-02-09 20:03:49 +00005790 static DIEStack g_die_stack;
5791 DIEStack::ScopedPopper scoped_die_logger(g_die_stack);
5792#endif
Greg Clayton1be10fc2010-09-29 01:12:09 +00005793
Sean Callananc7fbf732010-08-06 00:32:49 +00005794 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005795 if (die != NULL)
5796 {
Greg Clayton5160ce52013-03-27 23:08:40 +00005797 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00005798 if (log)
Sean Callanan5b26f272012-02-04 08:49:35 +00005799 {
5800 const DWARFDebugInfoEntry *context_die;
5801 clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005802
Greg Clayton5160ce52013-03-27 23:08:40 +00005803 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 +00005804 die->GetOffset(),
5805 static_cast<void*>(context),
5806 context_die->GetOffset(),
5807 DW_TAG_value_to_name(die->Tag()),
5808 die->GetName(this, dwarf_cu));
5809
Todd Fiala0a70a842014-05-28 16:43:26 +00005810#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
Greg Clayton1fba87112012-02-09 20:03:49 +00005811 scoped_die_logger.Push (dwarf_cu, die);
Greg Clayton5160ce52013-03-27 23:08:40 +00005812 g_die_stack.LogDIEs(log, this);
Greg Clayton1fba87112012-02-09 20:03:49 +00005813#endif
Sean Callanan5b26f272012-02-04 08:49:35 +00005814 }
Greg Clayton3bffb082011-12-10 02:15:28 +00005815//
Greg Clayton5160ce52013-03-27 23:08:40 +00005816// Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Clayton3bffb082011-12-10 02:15:28 +00005817// if (log && dwarf_cu)
5818// {
5819// StreamString s;
5820// die->DumpLocation (this, dwarf_cu, s);
Greg Clayton5160ce52013-03-27 23:08:40 +00005821// GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
Greg Clayton3bffb082011-12-10 02:15:28 +00005822//
5823// }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005824
Greg Clayton594e5ed2010-09-27 21:07:38 +00005825 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00005826 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00005827 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005828 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00005829 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00005830 if (type_is_new_ptr)
5831 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005832
Greg Clayton594e5ed2010-09-27 21:07:38 +00005833 const dw_tag_t tag = die->Tag();
5834
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005835 bool is_forward_declaration = false;
5836 DWARFDebugInfoEntry::Attributes attributes;
5837 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00005838 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00005839 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
Greg Claytonfaac1112013-03-14 18:31:44 +00005840 uint64_t byte_size = 0;
Greg Clayton526e5af2010-11-13 03:52:47 +00005841 Declaration decl;
5842
Greg Clayton4957bf62010-09-30 21:49:03 +00005843 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton57ee3062013-07-11 22:46:58 +00005844 ClangASTType clang_type;
Greg Claytond20deac2014-04-04 18:15:18 +00005845 DWARFFormValue form_value;
5846
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005847 dw_attr_t attr;
5848
5849 switch (tag)
5850 {
5851 case DW_TAG_base_type:
5852 case DW_TAG_pointer_type:
5853 case DW_TAG_reference_type:
Sean Callanance8af862012-05-21 23:31:51 +00005854 case DW_TAG_rvalue_reference_type:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005855 case DW_TAG_typedef:
5856 case DW_TAG_const_type:
5857 case DW_TAG_restrict_type:
5858 case DW_TAG_volatile_type:
Greg Claytond4436412011-10-28 21:00:00 +00005859 case DW_TAG_unspecified_type:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005860 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005861 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00005862 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005863
Greg Claytond88d7592010-09-15 08:33:30 +00005864 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005865 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005866 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
5867
5868 if (num_attributes > 0)
5869 {
5870 uint32_t i;
5871 for (i=0; i<num_attributes; ++i)
5872 {
5873 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005874 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
5875 {
5876 switch (attr)
5877 {
5878 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
5879 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
5880 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
5881 case DW_AT_name:
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005882
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005883 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00005884 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
5885 // include the "&"...
5886 if (tag == DW_TAG_reference_type)
5887 {
5888 if (strchr (type_name_cstr, '&') == NULL)
5889 type_name_cstr = NULL;
5890 }
5891 if (type_name_cstr)
5892 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005893 break;
Greg Clayton23f59502012-07-17 03:23:13 +00005894 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005895 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
Greg Clayton54166af2014-11-22 01:58:59 +00005896 case DW_AT_type: encoding_uid = form_value.Reference(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005897 default:
5898 case DW_AT_sibling:
5899 break;
5900 }
5901 }
5902 }
5903 }
5904
Ed Mastea0191d12013-10-17 20:42:56 +00005905 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 +00005906
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005907 switch (tag)
5908 {
5909 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00005910 break;
5911
Greg Claytond4436412011-10-28 21:00:00 +00005912 case DW_TAG_unspecified_type:
Greg Clayton7fba2632013-07-01 21:01:52 +00005913 if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
5914 strcmp(type_name_cstr, "decltype(nullptr)") == 0 )
Greg Claytond4436412011-10-28 21:00:00 +00005915 {
5916 resolve_state = Type::eResolveStateFull;
Greg Clayton57ee3062013-07-11 22:46:58 +00005917 clang_type = ast.GetBasicType(eBasicTypeNullPtr);
Greg Claytond4436412011-10-28 21:00:00 +00005918 break;
5919 }
5920 // Fall through to base type below in case we can handle the type there...
5921
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005922 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00005923 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00005924 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
5925 encoding,
5926 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005927 break;
5928
Sean Callanance8af862012-05-21 23:31:51 +00005929 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
5930 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
5931 case DW_TAG_rvalue_reference_type: encoding_data_type = Type::eEncodingIsRValueReferenceUID; break;
5932 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
5933 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
5934 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
5935 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005936 }
5937
Greg Clayton57ee3062013-07-11 22:46:58 +00005938 if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00005939 {
Sean Callanan82587052013-01-03 00:05:56 +00005940 bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005941
Sean Callanan82587052013-01-03 00:05:56 +00005942 if (translation_unit_is_objc)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00005943 {
Sean Callanan82587052013-01-03 00:05:56 +00005944 if (type_name_cstr != NULL)
Greg Claytonc7f03b62012-01-12 04:33:28 +00005945 {
Sean Callanan82587052013-01-03 00:05:56 +00005946 static ConstString g_objc_type_name_id("id");
5947 static ConstString g_objc_type_name_Class("Class");
5948 static ConstString g_objc_type_name_selector("SEL");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005949
Sean Callanan82587052013-01-03 00:05:56 +00005950 if (type_name_const_str == g_objc_type_name_id)
5951 {
5952 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005953 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 +00005954 die->GetOffset(),
5955 DW_TAG_value_to_name(die->Tag()),
5956 die->GetName(this, dwarf_cu));
Greg Clayton57ee3062013-07-11 22:46:58 +00005957 clang_type = ast.GetBasicType(eBasicTypeObjCID);
Sean Callanan82587052013-01-03 00:05:56 +00005958 encoding_data_type = Type::eEncodingIsUID;
5959 encoding_uid = LLDB_INVALID_UID;
5960 resolve_state = Type::eResolveStateFull;
Greg Clayton526e5af2010-11-13 03:52:47 +00005961
Sean Callanan82587052013-01-03 00:05:56 +00005962 }
5963 else if (type_name_const_str == g_objc_type_name_Class)
5964 {
5965 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005966 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 +00005967 die->GetOffset(),
5968 DW_TAG_value_to_name(die->Tag()),
5969 die->GetName(this, dwarf_cu));
Greg Clayton57ee3062013-07-11 22:46:58 +00005970 clang_type = ast.GetBasicType(eBasicTypeObjCClass);
Sean Callanan82587052013-01-03 00:05:56 +00005971 encoding_data_type = Type::eEncodingIsUID;
5972 encoding_uid = LLDB_INVALID_UID;
5973 resolve_state = Type::eResolveStateFull;
5974 }
5975 else if (type_name_const_str == g_objc_type_name_selector)
5976 {
5977 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00005978 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 +00005979 die->GetOffset(),
5980 DW_TAG_value_to_name(die->Tag()),
5981 die->GetName(this, dwarf_cu));
Greg Clayton57ee3062013-07-11 22:46:58 +00005982 clang_type = ast.GetBasicType(eBasicTypeObjCSel);
Sean Callanan82587052013-01-03 00:05:56 +00005983 encoding_data_type = Type::eEncodingIsUID;
5984 encoding_uid = LLDB_INVALID_UID;
5985 resolve_state = Type::eResolveStateFull;
5986 }
Greg Claytonc7f03b62012-01-12 04:33:28 +00005987 }
Sean Callanan82587052013-01-03 00:05:56 +00005988 else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
Greg Claytonc7f03b62012-01-12 04:33:28 +00005989 {
Sean Callanan82587052013-01-03 00:05:56 +00005990 // 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 +00005991
Sean Callanan82587052013-01-03 00:05:56 +00005992 DWARFDebugInfoEntry* encoding_die = dwarf_cu->GetDIEPtr(encoding_uid);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005993
Sean Callanan82587052013-01-03 00:05:56 +00005994 if (encoding_die && encoding_die->Tag() == DW_TAG_structure_type)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00005995 {
Sean Callanan82587052013-01-03 00:05:56 +00005996 if (const char *struct_name = encoding_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL))
5997 {
5998 if (!strcmp(struct_name, "objc_object"))
5999 {
6000 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00006001 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 +00006002 die->GetOffset(),
6003 DW_TAG_value_to_name(die->Tag()),
6004 die->GetName(this, dwarf_cu));
Greg Clayton57ee3062013-07-11 22:46:58 +00006005 clang_type = ast.GetBasicType(eBasicTypeObjCID);
Sean Callanan82587052013-01-03 00:05:56 +00006006 encoding_data_type = Type::eEncodingIsUID;
6007 encoding_uid = LLDB_INVALID_UID;
6008 resolve_state = Type::eResolveStateFull;
6009 }
6010 }
6011 }
Greg Claytonc7f03b62012-01-12 04:33:28 +00006012 }
Greg Claytonb0b9fe62010-08-03 00:35:52 +00006013 }
6014 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006015
Greg Clayton81c22f62011-10-19 18:09:39 +00006016 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006017 this,
6018 type_name_const_str,
6019 byte_size,
6020 NULL,
6021 encoding_uid,
6022 encoding_data_type,
6023 &decl,
6024 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00006025 resolve_state));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006026
Greg Clayton594e5ed2010-09-27 21:07:38 +00006027 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006028
6029// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
6030// if (encoding_type != NULL)
6031// {
6032// if (encoding_type != DIE_IS_BEING_PARSED)
6033// type_sp->SetEncodingType(encoding_type);
6034// else
6035// m_indirect_fixups.push_back(type_sp.get());
6036// }
6037 }
6038 break;
6039
6040 case DW_TAG_structure_type:
6041 case DW_TAG_union_type:
6042 case DW_TAG_class_type:
6043 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006044 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00006045 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Greg Clayton23f59502012-07-17 03:23:13 +00006046 bool byte_size_valid = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006047
Greg Clayton9e409562010-07-28 02:04:09 +00006048 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton18774842011-11-29 23:40:34 +00006049 bool is_complete_objc_class = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006050 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00006051 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006052 if (num_attributes > 0)
6053 {
6054 uint32_t i;
6055 for (i=0; i<num_attributes; ++i)
6056 {
6057 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006058 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
6059 {
6060 switch (attr)
6061 {
Greg Clayton9e409562010-07-28 02:04:09 +00006062 case DW_AT_decl_file:
Greg Claytonc7f03b62012-01-12 04:33:28 +00006063 if (dwarf_cu->DW_AT_decl_file_attributes_are_invalid())
Ed Maste4c24b122013-10-17 20:13:14 +00006064 {
6065 // llvm-gcc outputs invalid DW_AT_decl_file attributes that always
6066 // point to the compile unit file, so we clear this invalid value
6067 // so that we can still unique types efficiently.
Greg Claytonc7f03b62012-01-12 04:33:28 +00006068 decl.SetFile(FileSpec ("<invalid>", false));
Ed Maste4c24b122013-10-17 20:13:14 +00006069 }
Greg Claytonc7f03b62012-01-12 04:33:28 +00006070 else
6071 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
Greg Clayton9e409562010-07-28 02:04:09 +00006072 break;
6073
6074 case DW_AT_decl_line:
6075 decl.SetLine(form_value.Unsigned());
6076 break;
6077
6078 case DW_AT_decl_column:
6079 decl.SetColumn(form_value.Unsigned());
6080 break;
6081
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006082 case DW_AT_name:
6083 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00006084 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006085 break;
Greg Clayton9e409562010-07-28 02:04:09 +00006086
6087 case DW_AT_byte_size:
6088 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00006089 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00006090 break;
6091
6092 case DW_AT_accessibility:
6093 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
6094 break;
6095
6096 case DW_AT_declaration:
Greg Clayton1c8ef472013-04-05 23:27:21 +00006097 is_forward_declaration = form_value.Boolean();
Greg Clayton9e409562010-07-28 02:04:09 +00006098 break;
6099
6100 case DW_AT_APPLE_runtime_class:
6101 class_language = (LanguageType)form_value.Signed();
6102 break;
6103
Greg Clayton18774842011-11-29 23:40:34 +00006104 case DW_AT_APPLE_objc_complete_type:
6105 is_complete_objc_class = form_value.Signed();
6106 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006107
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006108 case DW_AT_allocated:
6109 case DW_AT_associated:
6110 case DW_AT_data_location:
6111 case DW_AT_description:
6112 case DW_AT_start_scope:
6113 case DW_AT_visibility:
6114 default:
6115 case DW_AT_sibling:
6116 break;
6117 }
6118 }
6119 }
6120 }
Greg Claytond20deac2014-04-04 18:15:18 +00006121
6122 // UniqueDWARFASTType is large, so don't create a local variables on the
6123 // stack, put it on the heap. This function is often called recursively
6124 // and clang isn't good and sharing the stack space for variables in different blocks.
6125 std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());
Sean Callanan8e8072d2012-02-07 21:13:38 +00006126
Greg Clayton123edca2012-03-02 00:07:15 +00006127 // Only try and unique the type if it has a name.
6128 if (type_name_const_str &&
6129 GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Sean Callanan8e8072d2012-02-07 21:13:38 +00006130 this,
6131 dwarf_cu,
6132 die,
6133 decl,
6134 byte_size_valid ? byte_size : -1,
Greg Claytond20deac2014-04-04 18:15:18 +00006135 *unique_ast_entry_ap))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006136 {
Sean Callanan8e8072d2012-02-07 21:13:38 +00006137 // We have already parsed this type or from another
6138 // compile unit. GCC loves to use the "one definition
6139 // rule" which can result in multiple definitions
6140 // of the same class over and over in each compile
6141 // unit.
Greg Claytond20deac2014-04-04 18:15:18 +00006142 type_sp = unique_ast_entry_ap->m_type_sp;
Sean Callanan8e8072d2012-02-07 21:13:38 +00006143 if (type_sp)
Greg Claytonc615ce42010-11-09 04:42:43 +00006144 {
Sean Callanan8e8072d2012-02-07 21:13:38 +00006145 m_die_to_type[die] = type_sp.get();
6146 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00006147 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006148 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006149
Daniel Malead01b2952012-11-29 21:49:15 +00006150 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 +00006151
6152 int tag_decl_kind = -1;
6153 AccessType default_accessibility = eAccessNone;
6154 if (tag == DW_TAG_structure_type)
6155 {
6156 tag_decl_kind = clang::TTK_Struct;
6157 default_accessibility = eAccessPublic;
6158 }
6159 else if (tag == DW_TAG_union_type)
6160 {
6161 tag_decl_kind = clang::TTK_Union;
6162 default_accessibility = eAccessPublic;
6163 }
6164 else if (tag == DW_TAG_class_type)
6165 {
6166 tag_decl_kind = clang::TTK_Class;
6167 default_accessibility = eAccessPrivate;
6168 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006169
Greg Clayton3a5f29a2011-11-30 02:48:28 +00006170 if (byte_size_valid && byte_size == 0 && type_name_cstr &&
6171 die->HasChildren() == false &&
6172 sc.comp_unit->GetLanguage() == eLanguageTypeObjC)
6173 {
6174 // Work around an issue with clang at the moment where
6175 // forward declarations for objective C classes are emitted
6176 // as:
6177 // DW_TAG_structure_type [2]
6178 // DW_AT_name( "ForwardObjcClass" )
6179 // DW_AT_byte_size( 0x00 )
6180 // DW_AT_decl_file( "..." )
6181 // DW_AT_decl_line( 1 )
6182 //
6183 // Note that there is no DW_AT_declaration and there are
6184 // no children, and the byte size is zero.
6185 is_forward_declaration = true;
6186 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006187
Sean Callanan7457f8d2012-04-25 01:03:57 +00006188 if (class_language == eLanguageTypeObjC ||
6189 class_language == eLanguageTypeObjC_plus_plus)
Greg Clayton18774842011-11-29 23:40:34 +00006190 {
Greg Claytonc7f03b62012-01-12 04:33:28 +00006191 if (!is_complete_objc_class && Supports_DW_AT_APPLE_objc_complete_type(dwarf_cu))
Greg Clayton901c5ca2011-12-03 04:40:03 +00006192 {
6193 // We have a valid eSymbolTypeObjCClass class symbol whose
6194 // name matches the current objective C class that we
6195 // are trying to find and this DIE isn't the complete
6196 // definition (we checked is_complete_objc_class above and
6197 // know it is false), so the real definition is in here somewhere
Greg Claytonc7f03b62012-01-12 04:33:28 +00006198 type_sp = FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006199
Greg Clayton1f746072012-08-29 21:13:06 +00006200 if (!type_sp && GetDebugMapSymfile ())
Greg Clayton901c5ca2011-12-03 04:40:03 +00006201 {
6202 // We weren't able to find a full declaration in
6203 // this DWARF, see if we have a declaration anywhere
6204 // else...
Greg Claytonc7f03b62012-01-12 04:33:28 +00006205 type_sp = m_debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
Greg Clayton901c5ca2011-12-03 04:40:03 +00006206 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006207
Greg Clayton901c5ca2011-12-03 04:40:03 +00006208 if (type_sp)
6209 {
6210 if (log)
6211 {
Greg Clayton5160ce52013-03-27 23:08:40 +00006212 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00006213 "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 +00006214 static_cast<void*>(this),
Greg Claytone38a5ed2012-01-05 03:57:59 +00006215 die->GetOffset(),
6216 DW_TAG_value_to_name(tag),
6217 type_name_cstr,
6218 type_sp->GetID());
Greg Clayton901c5ca2011-12-03 04:40:03 +00006219 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006220
Greg Clayton901c5ca2011-12-03 04:40:03 +00006221 // We found a real definition for this type elsewhere
6222 // so lets use it and cache the fact that we found
6223 // a complete type for this die
6224 m_die_to_type[die] = type_sp.get();
6225 return type_sp;
6226 }
6227 }
6228 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006229
Greg Clayton901c5ca2011-12-03 04:40:03 +00006230
6231 if (is_forward_declaration)
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006232 {
6233 // We have a forward declaration to a type and we need
6234 // to try and find a full declaration. We look in the
6235 // current type index just in case we have a forward
6236 // declaration followed by an actual declarations in the
6237 // DWARF. If this fails, we need to look elsewhere...
Greg Claytonc982b3d2011-11-28 01:45:00 +00006238 if (log)
6239 {
Greg Clayton5160ce52013-03-27 23:08:40 +00006240 GetObjectFile()->GetModule()->LogMessage (log,
Greg Claytone38a5ed2012-01-05 03:57:59 +00006241 "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type",
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006242 static_cast<void*>(this),
Greg Claytone38a5ed2012-01-05 03:57:59 +00006243 die->GetOffset(),
6244 DW_TAG_value_to_name(tag),
6245 type_name_cstr);
Greg Claytonc982b3d2011-11-28 01:45:00 +00006246 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006247
Greg Claytona8022fa2012-04-24 21:22:41 +00006248 DWARFDeclContext die_decl_ctx;
6249 die->GetDWARFDeclContext(this, dwarf_cu, die_decl_ctx);
6250
6251 //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
6252 type_sp = FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006253
Greg Clayton1f746072012-08-29 21:13:06 +00006254 if (!type_sp && GetDebugMapSymfile ())
Greg Clayton4272cc72011-02-02 02:24:04 +00006255 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006256 // We weren't able to find a full declaration in
6257 // this DWARF, see if we have a declaration anywhere
6258 // else...
Greg Claytona8022fa2012-04-24 21:22:41 +00006259 type_sp = m_debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
Greg Clayton4272cc72011-02-02 02:24:04 +00006260 }
6261
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006262 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00006263 {
Greg Claytonc982b3d2011-11-28 01:45:00 +00006264 if (log)
6265 {
Greg Clayton5160ce52013-03-27 23:08:40 +00006266 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00006267 "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 +00006268 static_cast<void*>(this),
Greg Claytone38a5ed2012-01-05 03:57:59 +00006269 die->GetOffset(),
6270 DW_TAG_value_to_name(tag),
6271 type_name_cstr,
6272 type_sp->GetID());
Greg Claytonc982b3d2011-11-28 01:45:00 +00006273 }
6274
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006275 // We found a real definition for this type elsewhere
6276 // so lets use it and cache the fact that we found
6277 // a complete type for this die
6278 m_die_to_type[die] = type_sp.get();
6279 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00006280 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006281 }
6282 assert (tag_decl_kind != -1);
6283 bool clang_type_was_created = false;
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006284 clang_type.SetClangType(ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
Greg Clayton57ee3062013-07-11 22:46:58 +00006285 if (!clang_type)
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006286 {
Sean Callanan4d04c6a2012-02-09 22:54:11 +00006287 const DWARFDebugInfoEntry *decl_ctx_die;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006288
Sean Callanan4d04c6a2012-02-09 22:54:11 +00006289 clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
Greg Clayton55561e92011-10-26 03:31:36 +00006290 if (accessibility == eAccessNone && decl_ctx)
6291 {
6292 // Check the decl context that contains this class/struct/union.
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00006293 // If it is a class we must give it an accessibility.
Greg Clayton55561e92011-10-26 03:31:36 +00006294 const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
6295 if (DeclKindIsCXXClass (containing_decl_kind))
6296 accessibility = default_accessibility;
6297 }
6298
Greg Claytonc4ffd662013-03-08 01:37:30 +00006299 ClangASTMetadata metadata;
6300 metadata.SetUserID(MakeUserID(die->GetOffset()));
6301 metadata.SetIsDynamicCXXType(ClassOrStructIsVirtual (dwarf_cu, die));
6302
Greg Claytonf0705c82011-10-22 03:33:13 +00006303 if (type_name_cstr && strchr (type_name_cstr, '<'))
6304 {
6305 ClangASTContext::TemplateParameterInfos template_param_infos;
6306 if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos))
6307 {
6308 clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00006309 accessibility,
Greg Claytonf0705c82011-10-22 03:33:13 +00006310 type_name_cstr,
6311 tag_decl_kind,
6312 template_param_infos);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006313
Greg Claytonf0705c82011-10-22 03:33:13 +00006314 clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx,
6315 class_template_decl,
6316 tag_decl_kind,
6317 template_param_infos);
6318 clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
6319 clang_type_was_created = true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006320
Greg Claytond0029442013-03-27 01:48:02 +00006321 GetClangASTContext().SetMetadata (class_template_decl, metadata);
6322 GetClangASTContext().SetMetadata (class_specialization_decl, metadata);
Greg Claytonf0705c82011-10-22 03:33:13 +00006323 }
6324 }
6325
6326 if (!clang_type_was_created)
6327 {
6328 clang_type_was_created = true;
Greg Clayton55561e92011-10-26 03:31:36 +00006329 clang_type = ast.CreateRecordType (decl_ctx,
6330 accessibility,
6331 type_name_cstr,
Greg Claytonf0705c82011-10-22 03:33:13 +00006332 tag_decl_kind,
Sean Callanan60217122012-04-13 00:10:03 +00006333 class_language,
Jim Ingham379397632012-10-27 02:54:13 +00006334 &metadata);
Greg Claytonf0705c82011-10-22 03:33:13 +00006335 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006336 }
6337
6338 // Store a forward declaration to this class type in case any
6339 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00006340 // types for function prototypes.
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006341 LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
Greg Clayton81c22f62011-10-19 18:09:39 +00006342 type_sp.reset (new Type (MakeUserID(die->GetOffset()),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006343 this,
6344 type_name_const_str,
6345 byte_size,
6346 NULL,
6347 LLDB_INVALID_UID,
6348 Type::eEncodingIsUID,
6349 &decl,
6350 clang_type,
6351 Type::eResolveStateForward));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006352
Sean Callanan72772842012-02-22 23:57:45 +00006353 type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00006354
6355
6356 // Add our type to the unique type map so we don't
6357 // end up creating many copies of the same type over
6358 // and over in the ASTContext for our module
Greg Claytond20deac2014-04-04 18:15:18 +00006359 unique_ast_entry_ap->m_type_sp = type_sp;
6360 unique_ast_entry_ap->m_symfile = this;
6361 unique_ast_entry_ap->m_cu = dwarf_cu;
6362 unique_ast_entry_ap->m_die = die;
6363 unique_ast_entry_ap->m_declaration = decl;
6364 unique_ast_entry_ap->m_byte_size = byte_size;
Greg Claytone576ab22011-02-15 00:19:15 +00006365 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
Greg Claytond20deac2014-04-04 18:15:18 +00006366 *unique_ast_entry_ap);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006367
Greg Clayton0ec71a02013-08-10 00:09:35 +00006368 if (is_forward_declaration && die->HasChildren())
6369 {
6370 // Check to see if the DIE actually has a definition, some version of GCC will
6371 // emit DIEs with DW_AT_declaration set to true, but yet still have subprogram,
6372 // members, or inheritance, so we can't trust it
6373 const DWARFDebugInfoEntry *child_die = die->GetFirstChild();
6374 while (child_die)
6375 {
6376 switch (child_die->Tag())
6377 {
6378 case DW_TAG_inheritance:
6379 case DW_TAG_subprogram:
6380 case DW_TAG_member:
6381 case DW_TAG_APPLE_property:
Greg Clayton4c484ec2014-02-07 19:21:56 +00006382 case DW_TAG_class_type:
6383 case DW_TAG_structure_type:
6384 case DW_TAG_enumeration_type:
6385 case DW_TAG_typedef:
6386 case DW_TAG_union_type:
Greg Clayton0ec71a02013-08-10 00:09:35 +00006387 child_die = NULL;
6388 is_forward_declaration = false;
6389 break;
6390 default:
6391 child_die = child_die->GetSibling();
6392 break;
6393 }
6394 }
6395 }
6396
Sean Callanan12014a02011-12-08 23:45:45 +00006397 if (!is_forward_declaration)
Greg Clayton219cf312012-03-30 00:51:13 +00006398 {
6399 // Always start the definition for a class type so that
6400 // if the class has child classes or types that require
6401 // the class to be created for use as their decl contexts
6402 // the class will be ready to accept these child definitions.
Sean Callanan12014a02011-12-08 23:45:45 +00006403 if (die->HasChildren() == false)
6404 {
6405 // No children for this struct/union/class, lets finish it
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006406 clang_type.StartTagDeclarationDefinition ();
6407 clang_type.CompleteTagDeclarationDefinition ();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006408
Sean Callanan433cd222012-10-19 01:37:25 +00006409 if (tag == DW_TAG_structure_type) // this only applies in C
6410 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006411 clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006412
Greg Clayton57ee3062013-07-11 22:46:58 +00006413 if (record_decl)
Greg Claytond20deac2014-04-04 18:15:18 +00006414 m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
Sean Callanan433cd222012-10-19 01:37:25 +00006415 }
Sean Callanan12014a02011-12-08 23:45:45 +00006416 }
6417 else if (clang_type_was_created)
6418 {
Greg Clayton219cf312012-03-30 00:51:13 +00006419 // Start the definition if the class is not objective C since
6420 // the underlying decls respond to isCompleteDefinition(). Objective
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +00006421 // C decls don't respond to isCompleteDefinition() so we can't
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00006422 // start the declaration definition right away. For C++ class/union/structs
Greg Clayton219cf312012-03-30 00:51:13 +00006423 // we want to start the definition in case the class is needed as the
6424 // declaration context for a contained class or type without the need
6425 // to complete that type..
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006426
Sean Callanan7457f8d2012-04-25 01:03:57 +00006427 if (class_language != eLanguageTypeObjC &&
6428 class_language != eLanguageTypeObjC_plus_plus)
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006429 clang_type.StartTagDeclarationDefinition ();
Greg Clayton219cf312012-03-30 00:51:13 +00006430
Sean Callanan12014a02011-12-08 23:45:45 +00006431 // Leave this as a forward declaration until we need
6432 // to know the details of the type. lldb_private::Type
6433 // will automatically call the SymbolFile virtual function
6434 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
6435 // When the definition needs to be defined.
Greg Clayton57ee3062013-07-11 22:46:58 +00006436 m_forward_decl_die_to_clang_type[die] = clang_type.GetOpaqueQualType();
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006437 m_forward_decl_clang_type_to_die[clang_type.RemoveFastQualifiers().GetOpaqueQualType()] = die;
6438 clang_type.SetHasExternalStorage (true);
Sean Callanan12014a02011-12-08 23:45:45 +00006439 }
Greg Claytonc615ce42010-11-09 04:42:43 +00006440 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006441
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006442 }
6443 break;
6444
6445 case DW_TAG_enumeration_type:
6446 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006447 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00006448 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006449
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006450 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006451
Greg Claytond88d7592010-09-15 08:33:30 +00006452 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006453 if (num_attributes > 0)
6454 {
6455 uint32_t i;
6456
6457 for (i=0; i<num_attributes; ++i)
6458 {
6459 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006460 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
6461 {
6462 switch (attr)
6463 {
Greg Clayton7a345282010-11-09 23:46:37 +00006464 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
6465 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
6466 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006467 case DW_AT_name:
6468 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00006469 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006470 break;
Greg Clayton54166af2014-11-22 01:58:59 +00006471 case DW_AT_type: encoding_uid = form_value.Reference(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00006472 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
6473 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00006474 case DW_AT_declaration: break; //is_forward_declaration = form_value.Boolean(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006475 case DW_AT_allocated:
6476 case DW_AT_associated:
6477 case DW_AT_bit_stride:
6478 case DW_AT_byte_stride:
6479 case DW_AT_data_location:
6480 case DW_AT_description:
6481 case DW_AT_start_scope:
6482 case DW_AT_visibility:
6483 case DW_AT_specification:
6484 case DW_AT_abstract_origin:
6485 case DW_AT_sibling:
6486 break;
6487 }
6488 }
6489 }
6490
Daniel Malead01b2952012-11-29 21:49:15 +00006491 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 +00006492
Greg Clayton57ee3062013-07-11 22:46:58 +00006493 ClangASTType enumerator_clang_type;
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006494 clang_type.SetClangType (ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
Greg Clayton57ee3062013-07-11 22:46:58 +00006495 if (!clang_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00006496 {
Greg Clayton5d14fc02013-03-06 06:23:54 +00006497 if (encoding_uid != DW_INVALID_OFFSET)
6498 {
6499 Type *enumerator_type = ResolveTypeUID(encoding_uid);
6500 if (enumerator_type)
6501 enumerator_clang_type = enumerator_type->GetClangFullType();
6502 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006503
Greg Clayton57ee3062013-07-11 22:46:58 +00006504 if (!enumerator_clang_type)
Greg Clayton5d14fc02013-03-06 06:23:54 +00006505 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
6506 DW_ATE_signed,
6507 byte_size * 8);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006508
Greg Claytonca512b32011-01-14 04:54:56 +00006509 clang_type = ast.CreateEnumerationType (type_name_cstr,
Greg Claytoncb5860a2011-10-13 23:49:28 +00006510 GetClangDeclContextContainingDIE (dwarf_cu, die, NULL),
Greg Claytonca512b32011-01-14 04:54:56 +00006511 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006512 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00006513 }
6514 else
6515 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006516 enumerator_clang_type = clang_type.GetEnumerationIntegerType ();
Greg Clayton1be10fc2010-09-29 01:12:09 +00006517 }
6518
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006519 LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006520
Greg Clayton81c22f62011-10-19 18:09:39 +00006521 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006522 this,
6523 type_name_const_str,
6524 byte_size,
6525 NULL,
6526 encoding_uid,
6527 Type::eEncodingIsUID,
6528 &decl,
6529 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00006530 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006531
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006532 clang_type.StartTagDeclarationDefinition ();
Greg Clayton6beaaa62011-01-17 03:46:26 +00006533 if (die->HasChildren())
6534 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00006535 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
Greg Clayton3e067532013-03-05 23:54:39 +00006536 bool is_signed = false;
Greg Clayton57ee3062013-07-11 22:46:58 +00006537 enumerator_clang_type.IsIntegerType(is_signed);
Greg Clayton3e067532013-03-05 23:54:39 +00006538 ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00006539 }
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006540 clang_type.CompleteTagDeclarationDefinition ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006541 }
6542 }
6543 break;
6544
Jim Inghamb0be4422010-08-12 01:20:14 +00006545 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006546 case DW_TAG_subprogram:
6547 case DW_TAG_subroutine_type:
6548 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006549 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00006550 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006551
Greg Clayton23f59502012-07-17 03:23:13 +00006552 //const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006553 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00006554 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006555 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00006556 bool is_static = false;
6557 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00006558 bool is_explicit = false;
Sean Callanandbb58392011-11-02 01:38:59 +00006559 bool is_artificial = false;
Greg Clayton72da3972011-08-16 18:40:23 +00006560 dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
6561 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
Jim Ingham379397632012-10-27 02:54:13 +00006562 dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
Greg Clayton0fffff52010-09-24 05:15:53 +00006563
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006564 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00006565 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006566
6567
Greg Claytond88d7592010-09-15 08:33:30 +00006568 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006569 if (num_attributes > 0)
6570 {
6571 uint32_t i;
6572 for (i=0; i<num_attributes; ++i)
6573 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00006574 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006575 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
6576 {
6577 switch (attr)
6578 {
6579 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
6580 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
6581 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
6582 case DW_AT_name:
6583 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00006584 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006585 break;
6586
Greg Clayton71415542012-12-08 00:24:40 +00006587 case DW_AT_linkage_name:
Greg Clayton23f59502012-07-17 03:23:13 +00006588 case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00006589 case DW_AT_type: type_die_offset = form_value.Reference(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00006590 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00006591 case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
6592 case DW_AT_inline: is_inline = form_value.Boolean(); break;
6593 case DW_AT_virtuality: is_virtual = form_value.Boolean(); break;
6594 case DW_AT_explicit: is_explicit = form_value.Boolean(); break;
6595 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006596
Greg Claytonf51de672010-10-01 02:31:07 +00006597
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006598 case DW_AT_external:
6599 if (form_value.Unsigned())
6600 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00006601 if (storage == clang::SC_None)
6602 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006603 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00006604 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006605 }
6606 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006607
Greg Clayton72da3972011-08-16 18:40:23 +00006608 case DW_AT_specification:
Greg Clayton54166af2014-11-22 01:58:59 +00006609 specification_die_offset = form_value.Reference();
Greg Clayton72da3972011-08-16 18:40:23 +00006610 break;
6611
6612 case DW_AT_abstract_origin:
Greg Clayton54166af2014-11-22 01:58:59 +00006613 abstract_origin_die_offset = form_value.Reference();
Greg Clayton72da3972011-08-16 18:40:23 +00006614 break;
6615
Jim Ingham379397632012-10-27 02:54:13 +00006616 case DW_AT_object_pointer:
Greg Clayton54166af2014-11-22 01:58:59 +00006617 object_pointer_die_offset = form_value.Reference();
Jim Ingham379397632012-10-27 02:54:13 +00006618 break;
6619
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006620 case DW_AT_allocated:
6621 case DW_AT_associated:
6622 case DW_AT_address_class:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006623 case DW_AT_calling_convention:
6624 case DW_AT_data_location:
6625 case DW_AT_elemental:
6626 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006627 case DW_AT_frame_base:
6628 case DW_AT_high_pc:
6629 case DW_AT_low_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006630 case DW_AT_prototyped:
6631 case DW_AT_pure:
6632 case DW_AT_ranges:
6633 case DW_AT_recursive:
6634 case DW_AT_return_addr:
6635 case DW_AT_segment:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006636 case DW_AT_start_scope:
6637 case DW_AT_static_link:
6638 case DW_AT_trampoline:
6639 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006640 case DW_AT_vtable_elem_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006641 case DW_AT_description:
6642 case DW_AT_sibling:
6643 break;
6644 }
6645 }
6646 }
Greg Clayton24739922010-10-13 03:15:28 +00006647 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006648
Jim Ingham379397632012-10-27 02:54:13 +00006649 std::string object_pointer_name;
6650 if (object_pointer_die_offset != DW_INVALID_OFFSET)
6651 {
6652 // Get the name from the object pointer die
6653 StreamString s;
6654 if (DWARFDebugInfoEntry::GetName (this, dwarf_cu, object_pointer_die_offset, s))
6655 {
6656 object_pointer_name.assign(s.GetData());
6657 }
6658 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006659
Daniel Malead01b2952012-11-29 21:49:15 +00006660 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 +00006661
Greg Clayton57ee3062013-07-11 22:46:58 +00006662 ClangASTType return_clang_type;
Greg Clayton24739922010-10-13 03:15:28 +00006663 Type *func_type = NULL;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006664
Greg Clayton24739922010-10-13 03:15:28 +00006665 if (type_die_offset != DW_INVALID_OFFSET)
6666 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00006667
Greg Clayton24739922010-10-13 03:15:28 +00006668 if (func_type)
Greg Clayton42ce2f32011-12-12 21:50:19 +00006669 return_clang_type = func_type->GetClangForwardType();
Greg Clayton24739922010-10-13 03:15:28 +00006670 else
Greg Clayton57ee3062013-07-11 22:46:58 +00006671 return_clang_type = ast.GetBasicType(eBasicTypeVoid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006672
Greg Claytonf51de672010-10-01 02:31:07 +00006673
Greg Clayton57ee3062013-07-11 22:46:58 +00006674 std::vector<ClangASTType> function_param_types;
Greg Clayton24739922010-10-13 03:15:28 +00006675 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006676
Greg Clayton24739922010-10-13 03:15:28 +00006677 // Parse the function children for the parameters
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006678
Greg Claytoncb5860a2011-10-13 23:49:28 +00006679 const DWARFDebugInfoEntry *decl_ctx_die = NULL;
6680 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
Greg Clayton5113dc82011-08-12 06:47:54 +00006681 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
6682
Greg Claytonf0705c82011-10-22 03:33:13 +00006683 const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
Greg Clayton5113dc82011-08-12 06:47:54 +00006684 // Start off static. This will be set to false in ParseChildParameters(...)
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00006685 // if we find a "this" parameters as the first parameter
Greg Clayton5113dc82011-08-12 06:47:54 +00006686 if (is_cxx_method)
Sean Callanan763d72a2011-08-02 22:21:50 +00006687 is_static = true;
Greg Claytond20deac2014-04-04 18:15:18 +00006688
Greg Clayton24739922010-10-13 03:15:28 +00006689 if (die->HasChildren())
6690 {
Greg Clayton0fffff52010-09-24 05:15:53 +00006691 bool skip_artificial = true;
Jim Ingham379397632012-10-27 02:54:13 +00006692 ParseChildParameters (sc,
Greg Clayton5113dc82011-08-12 06:47:54 +00006693 containing_decl_ctx,
Jim Ingham379397632012-10-27 02:54:13 +00006694 dwarf_cu,
6695 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00006696 skip_artificial,
6697 is_static,
Greg Clayton03969752014-02-24 18:53:11 +00006698 is_variadic,
Jim Ingham379397632012-10-27 02:54:13 +00006699 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00006700 function_param_decls,
Greg Claytond20deac2014-04-04 18:15:18 +00006701 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00006702 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006703
Greg Clayton24739922010-10-13 03:15:28 +00006704 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006705 clang_type = ast.CreateFunctionType (return_clang_type,
Greg Clayton9cb25c42012-10-30 17:02:18 +00006706 function_param_types.data(),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006707 function_param_types.size(),
6708 is_variadic,
6709 type_quals);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006710
Sean Callanande9ce872013-05-09 23:13:13 +00006711 bool ignore_containing_context = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006712
Greg Clayton24739922010-10-13 03:15:28 +00006713 if (type_name_cstr)
6714 {
6715 bool type_handled = false;
Greg Clayton24739922010-10-13 03:15:28 +00006716 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006717 {
Greg Clayton1b3815c2013-01-30 00:18:29 +00006718 ObjCLanguageRuntime::MethodName objc_method (type_name_cstr, true);
6719 if (objc_method.IsValid(true))
Greg Clayton0fffff52010-09-24 05:15:53 +00006720 {
Greg Clayton57ee3062013-07-11 22:46:58 +00006721 ClangASTType class_opaque_type;
Greg Clayton1b3815c2013-01-30 00:18:29 +00006722 ConstString class_name(objc_method.GetClassName());
Greg Clayton7c810422012-01-18 23:40:49 +00006723 if (class_name)
Greg Clayton0fffff52010-09-24 05:15:53 +00006724 {
Greg Clayton278a16b2012-01-19 00:52:59 +00006725 TypeSP complete_objc_class_type_sp (FindCompleteObjCDefinitionTypeForDIE (NULL, class_name, false));
Greg Claytonc7f03b62012-01-12 04:33:28 +00006726
6727 if (complete_objc_class_type_sp)
Greg Clayton0fffff52010-09-24 05:15:53 +00006728 {
Greg Clayton57ee3062013-07-11 22:46:58 +00006729 ClangASTType type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006730 if (type_clang_forward_type.IsObjCObjectOrInterfaceType ())
Greg Claytonc7f03b62012-01-12 04:33:28 +00006731 class_opaque_type = type_clang_forward_type;
Greg Clayton0fffff52010-09-24 05:15:53 +00006732 }
Greg Clayton24739922010-10-13 03:15:28 +00006733 }
Greg Clayton0fffff52010-09-24 05:15:53 +00006734
Greg Clayton24739922010-10-13 03:15:28 +00006735 if (class_opaque_type)
6736 {
6737 // If accessibility isn't set to anything valid, assume public for
6738 // now...
6739 if (accessibility == eAccessNone)
6740 accessibility = eAccessPublic;
6741
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006742 clang::ObjCMethodDecl *objc_method_decl = class_opaque_type.AddMethodToObjCObjectType (type_name_cstr,
6743 clang_type,
6744 accessibility,
6745 is_artificial);
Greg Clayton24739922010-10-13 03:15:28 +00006746 type_handled = objc_method_decl != NULL;
Sean Callanan464a5b52012-10-04 22:06:29 +00006747 if (type_handled)
6748 {
6749 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Claytond0029442013-03-27 01:48:02 +00006750 GetClangASTContext().SetMetadataAsUserID (objc_method_decl, MakeUserID(die->GetOffset()));
Sean Callanan464a5b52012-10-04 22:06:29 +00006751 }
Sean Callananc3a1d562013-02-06 23:21:59 +00006752 else
6753 {
Jason Molendac1a65832013-03-07 22:44:42 +00006754 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 +00006755 die->GetOffset(),
6756 tag,
6757 DW_TAG_value_to_name(tag));
6758 }
Greg Clayton24739922010-10-13 03:15:28 +00006759 }
6760 }
Greg Clayton5113dc82011-08-12 06:47:54 +00006761 else if (is_cxx_method)
Greg Clayton24739922010-10-13 03:15:28 +00006762 {
6763 // Look at the parent of this DIE and see if is is
6764 // a class or struct and see if this is actually a
6765 // C++ method
Greg Claytoncb5860a2011-10-13 23:49:28 +00006766 Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
Greg Clayton24739922010-10-13 03:15:28 +00006767 if (class_type)
6768 {
Greg Clayton4116e932012-05-15 02:33:01 +00006769 if (class_type->GetID() != MakeUserID(decl_ctx_die->GetOffset()))
6770 {
6771 // We uniqued the parent class of this function to another class
6772 // so we now need to associate all dies under "decl_ctx_die" to
6773 // DIEs in the DIE for "class_type"...
Greg Clayton5d650c6a2013-02-26 01:31:37 +00006774 SymbolFileDWARF *class_symfile = NULL;
Greg Clayton4116e932012-05-15 02:33:01 +00006775 DWARFCompileUnitSP class_type_cu_sp;
Greg Clayton5d650c6a2013-02-26 01:31:37 +00006776 const DWARFDebugInfoEntry *class_type_die = NULL;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006777
Sean Callanan2367f8a2013-02-26 01:12:25 +00006778 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
6779 if (debug_map_symfile)
6780 {
6781 class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
6782 class_type_die = class_symfile->DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
6783 }
6784 else
6785 {
6786 class_symfile = this;
6787 class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
6788 }
Greg Clayton4116e932012-05-15 02:33:01 +00006789 if (class_type_die)
6790 {
Greg Claytond20deac2014-04-04 18:15:18 +00006791 DWARFDIECollection failures;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006792
Sean Callanan2367f8a2013-02-26 01:12:25 +00006793 CopyUniqueClassMethodTypes (class_symfile,
6794 class_type,
6795 class_type_cu_sp.get(),
6796 class_type_die,
6797 dwarf_cu,
6798 decl_ctx_die,
6799 failures);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006800
Sean Callanan2367f8a2013-02-26 01:12:25 +00006801 // FIXME do something with these failures that's smarter than
6802 // just dropping them on the ground. Unfortunately classes don't
6803 // like having stuff added to them after their definitions are
6804 // complete...
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006805
Sean Callanan2367f8a2013-02-26 01:12:25 +00006806 type_ptr = m_die_to_type[die];
6807 if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
Greg Clayton4116e932012-05-15 02:33:01 +00006808 {
Sean Callanan2367f8a2013-02-26 01:12:25 +00006809 type_sp = type_ptr->shared_from_this();
6810 break;
Greg Clayton4116e932012-05-15 02:33:01 +00006811 }
6812 }
6813 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006814
Greg Clayton72da3972011-08-16 18:40:23 +00006815 if (specification_die_offset != DW_INVALID_OFFSET)
Greg Clayton0fffff52010-09-24 05:15:53 +00006816 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00006817 // We have a specification which we are going to base our function
6818 // prototype off of, so we need this type to be completed so that the
6819 // m_die_to_decl_ctx for the method in the specification has a valid
6820 // clang decl context.
Greg Clayton8eb732e2011-12-13 04:34:06 +00006821 class_type->GetClangForwardType();
Greg Clayton72da3972011-08-16 18:40:23 +00006822 // If we have a specification, then the function type should have been
6823 // made with the specification and not with this die.
6824 DWARFCompileUnitSP spec_cu_sp;
6825 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
Eric Christopher6cc6e602012-03-25 19:37:33 +00006826 clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, spec_die);
Greg Clayton5cf58b92011-10-05 22:22:08 +00006827 if (spec_clang_decl_ctx)
6828 {
6829 LinkDeclContextToDIE(spec_clang_decl_ctx, die);
6830 }
6831 else
Jim Inghamc1663042011-09-29 22:12:35 +00006832 {
Daniel Malead01b2952012-11-29 21:49:15 +00006833 GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x) has no decl\n",
Greg Claytone38a5ed2012-01-05 03:57:59 +00006834 MakeUserID(die->GetOffset()),
6835 specification_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00006836 }
Greg Clayton72da3972011-08-16 18:40:23 +00006837 type_handled = true;
6838 }
6839 else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
6840 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00006841 // We have a specification which we are going to base our function
6842 // prototype off of, so we need this type to be completed so that the
6843 // m_die_to_decl_ctx for the method in the abstract origin has a valid
6844 // clang decl context.
Greg Clayton8eb732e2011-12-13 04:34:06 +00006845 class_type->GetClangForwardType();
Greg Clayton5cf58b92011-10-05 22:22:08 +00006846
Greg Clayton72da3972011-08-16 18:40:23 +00006847 DWARFCompileUnitSP abs_cu_sp;
6848 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
Eric Christopher6cc6e602012-03-25 19:37:33 +00006849 clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, abs_die);
Greg Clayton5cf58b92011-10-05 22:22:08 +00006850 if (abs_clang_decl_ctx)
6851 {
6852 LinkDeclContextToDIE (abs_clang_decl_ctx, die);
6853 }
6854 else
Jim Inghamc1663042011-09-29 22:12:35 +00006855 {
Daniel Malead01b2952012-11-29 21:49:15 +00006856 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 +00006857 MakeUserID(die->GetOffset()),
6858 abstract_origin_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00006859 }
Greg Clayton72da3972011-08-16 18:40:23 +00006860 type_handled = true;
6861 }
6862 else
6863 {
Greg Clayton57ee3062013-07-11 22:46:58 +00006864 ClangASTType class_opaque_type = class_type->GetClangForwardType();
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006865 if (class_opaque_type.IsCXXClassType ())
Greg Clayton931180e2011-01-27 06:44:37 +00006866 {
Greg Clayton57ee3062013-07-11 22:46:58 +00006867 if (class_opaque_type.IsBeingDefined ())
Greg Clayton72da3972011-08-16 18:40:23 +00006868 {
Greg Clayton20568dd2011-10-13 23:13:20 +00006869 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
6870 // in the DWARF for C++ methods... Default to public for now...
6871 if (accessibility == eAccessNone)
6872 accessibility = eAccessPublic;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006873
Greg Clayton20568dd2011-10-13 23:13:20 +00006874 if (!is_static && !die->HasChildren())
6875 {
6876 // We have a C++ member function with no children (this pointer!)
6877 // and clang will get mad if we try and make a function that isn't
6878 // well formed in the DWARF, so we will just skip it...
6879 type_handled = true;
6880 }
6881 else
6882 {
6883 clang::CXXMethodDecl *cxx_method_decl;
6884 // REMOVE THE CRASH DESCRIPTION BELOW
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00006885 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 +00006886 type_name_cstr,
6887 class_type->GetName().GetCString(),
Greg Clayton81c22f62011-10-19 18:09:39 +00006888 MakeUserID(die->GetOffset()),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00006889 m_obj_file->GetFileSpec().GetPath().c_str());
Greg Clayton20568dd2011-10-13 23:13:20 +00006890
Sean Callananc1b732d2011-11-01 18:07:13 +00006891 const bool is_attr_used = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006892
Pavel Labathc7c30eb2015-06-08 23:38:06 +00006893 cxx_method_decl = class_opaque_type.AddMethodToCXXRecordType (type_name_cstr,
6894 clang_type,
6895 accessibility,
6896 is_virtual,
6897 is_static,
6898 is_inline,
6899 is_explicit,
6900 is_attr_used,
6901 is_artificial);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006902
Greg Clayton20568dd2011-10-13 23:13:20 +00006903 type_handled = cxx_method_decl != NULL;
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006904
6905 if (type_handled)
Jim Ingham379397632012-10-27 02:54:13 +00006906 {
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006907 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
6908
6909 Host::SetCrashDescription (NULL);
6910
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006911
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006912 ClangASTMetadata metadata;
6913 metadata.SetUserID(MakeUserID(die->GetOffset()));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006914
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006915 if (!object_pointer_name.empty())
6916 {
6917 metadata.SetObjectPtrName(object_pointer_name.c_str());
6918 if (log)
Greg Claytond0029442013-03-27 01:48:02 +00006919 log->Printf ("Setting object pointer name: %s on method object %p.\n",
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006920 object_pointer_name.c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006921 static_cast<void*>(cxx_method_decl));
Sean Callanan4ac7ec72012-10-31 02:01:58 +00006922 }
Greg Claytond0029442013-03-27 01:48:02 +00006923 GetClangASTContext().SetMetadata (cxx_method_decl, metadata);
Jim Ingham379397632012-10-27 02:54:13 +00006924 }
Sean Callananb0640dc2013-04-09 23:22:08 +00006925 else
6926 {
Sean Callanande9ce872013-05-09 23:13:13 +00006927 ignore_containing_context = true;
Sean Callananb0640dc2013-04-09 23:22:08 +00006928 }
Greg Clayton20568dd2011-10-13 23:13:20 +00006929 }
Greg Clayton72da3972011-08-16 18:40:23 +00006930 }
6931 else
6932 {
Greg Clayton20568dd2011-10-13 23:13:20 +00006933 // We were asked to parse the type for a method in a class, yet the
6934 // class hasn't been asked to complete itself through the
6935 // clang::ExternalASTSource protocol, so we need to just have the
6936 // class complete itself and do things the right way, then our
6937 // DIE should then have an entry in the m_die_to_type map. First
6938 // we need to modify the m_die_to_type so it doesn't think we are
6939 // trying to parse this DIE anymore...
6940 m_die_to_type[die] = NULL;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006941
Greg Clayton20568dd2011-10-13 23:13:20 +00006942 // Now we get the full type to force our class type to complete itself
6943 // using the clang::ExternalASTSource protocol which will parse all
6944 // base classes and all methods (including the method for this DIE).
6945 class_type->GetClangFullType();
Greg Clayton2c5f0e92011-08-04 21:02:57 +00006946
Greg Clayton20568dd2011-10-13 23:13:20 +00006947 // The type for this DIE should have been filled in the function call above
6948 type_ptr = m_die_to_type[die];
Greg Claytone5476db2012-06-01 20:32:35 +00006949 if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
Greg Clayton20568dd2011-10-13 23:13:20 +00006950 {
Greg Claytone1cd1be2012-01-29 20:56:30 +00006951 type_sp = type_ptr->shared_from_this();
Greg Clayton20568dd2011-10-13 23:13:20 +00006952 break;
6953 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006954
Sean Callanan02eee4d2012-04-12 23:10:00 +00006955 // FIXME This is fixing some even uglier behavior but we really need to
6956 // uniq the methods of each class as well as the class itself.
6957 // <rdar://problem/11240464>
6958 type_handled = true;
Greg Clayton72da3972011-08-16 18:40:23 +00006959 }
Greg Clayton931180e2011-01-27 06:44:37 +00006960 }
Greg Clayton0fffff52010-09-24 05:15:53 +00006961 }
6962 }
Greg Clayton0fffff52010-09-24 05:15:53 +00006963 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006964 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006965
Greg Clayton24739922010-10-13 03:15:28 +00006966 if (!type_handled)
6967 {
6968 // We just have a function that isn't part of a class
Sean Callanande9ce872013-05-09 23:13:13 +00006969 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (ignore_containing_context ? GetClangASTContext().GetTranslationUnitDecl() : containing_decl_ctx,
Greg Clayton147e1fa2011-10-14 22:47:18 +00006970 type_name_cstr,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006971 clang_type,
6972 storage,
6973 is_inline);
Greg Clayton3c2e3ae2012-02-06 06:42:51 +00006974
6975// if (template_param_infos.GetSize() > 0)
6976// {
6977// clang::FunctionTemplateDecl *func_template_decl = ast.CreateFunctionTemplateDecl (containing_decl_ctx,
6978// function_decl,
6979// type_name_cstr,
6980// template_param_infos);
6981//
6982// ast.CreateFunctionTemplateSpecializationInfo (function_decl,
6983// func_template_decl,
6984// template_param_infos);
6985// }
Greg Clayton24739922010-10-13 03:15:28 +00006986 // Add the decl to our DIE to decl context map
6987 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00006988 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00006989 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00006990 ast.SetFunctionParameters (function_decl,
6991 &function_param_decls.front(),
6992 function_param_decls.size());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006993
Jim Ingham379397632012-10-27 02:54:13 +00006994 ClangASTMetadata metadata;
6995 metadata.SetUserID(MakeUserID(die->GetOffset()));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00006996
Jim Ingham379397632012-10-27 02:54:13 +00006997 if (!object_pointer_name.empty())
6998 {
6999 metadata.SetObjectPtrName(object_pointer_name.c_str());
Jim Ingham2cffda3f2012-10-30 23:34:07 +00007000 if (log)
Greg Claytond0029442013-03-27 01:48:02 +00007001 log->Printf ("Setting object pointer name: %s on function object %p.",
Jim Ingham2cffda3f2012-10-30 23:34:07 +00007002 object_pointer_name.c_str(),
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007003 static_cast<void*>(function_decl));
Jim Ingham379397632012-10-27 02:54:13 +00007004 }
Greg Claytond0029442013-03-27 01:48:02 +00007005 GetClangASTContext().SetMetadata (function_decl, metadata);
Greg Clayton24739922010-10-13 03:15:28 +00007006 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007007 }
Greg Clayton81c22f62011-10-19 18:09:39 +00007008 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00007009 this,
7010 type_name_const_str,
7011 0,
7012 NULL,
7013 LLDB_INVALID_UID,
7014 Type::eEncodingIsUID,
7015 &decl,
7016 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00007017 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00007018 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007019 }
7020 break;
7021
7022 case DW_TAG_array_type:
7023 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007024 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00007025 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007026
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007027 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007028 int64_t first_index = 0;
7029 uint32_t byte_stride = 0;
7030 uint32_t bit_stride = 0;
Greg Clayton1c8ef472013-04-05 23:27:21 +00007031 bool is_vector = false;
Greg Claytond88d7592010-09-15 08:33:30 +00007032 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007033
7034 if (num_attributes > 0)
7035 {
7036 uint32_t i;
7037 for (i=0; i<num_attributes; ++i)
7038 {
7039 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007040 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
7041 {
7042 switch (attr)
7043 {
7044 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
7045 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
7046 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
7047 case DW_AT_name:
7048 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00007049 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007050 break;
7051
Greg Clayton54166af2014-11-22 01:58:59 +00007052 case DW_AT_type: type_die_offset = form_value.Reference(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00007053 case DW_AT_byte_size: break; // byte_size = form_value.Unsigned(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007054 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
7055 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00007056 case DW_AT_GNU_vector: is_vector = form_value.Boolean(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00007057 case DW_AT_accessibility: break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00007058 case DW_AT_declaration: break; // is_forward_declaration = form_value.Boolean(); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007059 case DW_AT_allocated:
7060 case DW_AT_associated:
7061 case DW_AT_data_location:
7062 case DW_AT_description:
7063 case DW_AT_ordering:
7064 case DW_AT_start_scope:
7065 case DW_AT_visibility:
7066 case DW_AT_specification:
7067 case DW_AT_abstract_origin:
7068 case DW_AT_sibling:
7069 break;
7070 }
7071 }
7072 }
7073
Daniel Malead01b2952012-11-29 21:49:15 +00007074 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 +00007075
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007076 Type *element_type = ResolveTypeUID(type_die_offset);
7077
7078 if (element_type)
7079 {
7080 std::vector<uint64_t> element_orders;
7081 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
7082 if (byte_stride == 0 && bit_stride == 0)
7083 byte_stride = element_type->GetByteSize();
Greg Clayton57ee3062013-07-11 22:46:58 +00007084 ClangASTType array_element_type = element_type->GetClangForwardType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007085 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
Siva Chandra89ce9552015-01-05 23:06:14 +00007086 if (element_orders.size() > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007087 {
Siva Chandra89ce9552015-01-05 23:06:14 +00007088 uint64_t num_elements = 0;
7089 std::vector<uint64_t>::const_reverse_iterator pos;
7090 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
7091 for (pos = element_orders.rbegin(); pos != end; ++pos)
7092 {
7093 num_elements = *pos;
7094 clang_type = ast.CreateArrayType (array_element_type,
7095 num_elements,
7096 is_vector);
7097 array_element_type = clang_type;
7098 array_element_bit_stride = num_elements ?
7099 array_element_bit_stride * num_elements :
7100 array_element_bit_stride;
7101 }
7102 }
7103 else
7104 {
7105 clang_type = ast.CreateArrayType (array_element_type, 0, is_vector);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007106 }
7107 ConstString empty_name;
Greg Clayton81c22f62011-10-19 18:09:39 +00007108 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00007109 this,
7110 empty_name,
7111 array_element_bit_stride / 8,
7112 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00007113 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00007114 Type::eEncodingIsUID,
7115 &decl,
7116 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00007117 Type::eResolveStateFull));
7118 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007119 }
7120 }
7121 }
7122 break;
7123
Greg Clayton9b81a312010-06-12 01:20:30 +00007124 case DW_TAG_ptr_to_member_type:
7125 {
7126 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
7127 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
7128
Greg Claytond88d7592010-09-15 08:33:30 +00007129 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007130
Greg Clayton9b81a312010-06-12 01:20:30 +00007131 if (num_attributes > 0) {
7132 uint32_t i;
7133 for (i=0; i<num_attributes; ++i)
7134 {
7135 attr = attributes.AttributeAtIndex(i);
Greg Clayton9b81a312010-06-12 01:20:30 +00007136 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
7137 {
7138 switch (attr)
7139 {
7140 case DW_AT_type:
Greg Clayton54166af2014-11-22 01:58:59 +00007141 type_die_offset = form_value.Reference(); break;
Greg Clayton9b81a312010-06-12 01:20:30 +00007142 case DW_AT_containing_type:
Greg Clayton54166af2014-11-22 01:58:59 +00007143 containing_type_die_offset = form_value.Reference(); break;
Greg Clayton9b81a312010-06-12 01:20:30 +00007144 }
7145 }
7146 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007147
Greg Clayton9b81a312010-06-12 01:20:30 +00007148 Type *pointee_type = ResolveTypeUID(type_die_offset);
7149 Type *class_type = ResolveTypeUID(containing_type_die_offset);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007150
Greg Clayton57ee3062013-07-11 22:46:58 +00007151 ClangASTType pointee_clang_type = pointee_type->GetClangForwardType();
7152 ClangASTType class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00007153
Pavel Labathc7c30eb2015-06-08 23:38:06 +00007154 clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00007155
Enrico Granata1cd5e922015-01-28 00:07:51 +00007156 byte_size = clang_type.GetByteSize(nullptr);
Greg Clayton9b81a312010-06-12 01:20:30 +00007157
Greg Clayton81c22f62011-10-19 18:09:39 +00007158 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00007159 this,
7160 type_name_const_str,
7161 byte_size,
7162 NULL,
7163 LLDB_INVALID_UID,
7164 Type::eEncodingIsUID,
7165 NULL,
7166 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00007167 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00007168 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00007169
Greg Clayton9b81a312010-06-12 01:20:30 +00007170 break;
7171 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007172 default:
Greg Clayton84afacd2012-11-07 23:09:32 +00007173 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",
7174 die->GetOffset(),
7175 tag,
7176 DW_TAG_value_to_name(tag));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007177 break;
7178 }
7179
7180 if (type_sp.get())
7181 {
7182 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
7183 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
7184
7185 SymbolContextScope * symbol_context_scope = NULL;
7186 if (sc_parent_tag == DW_TAG_compile_unit)
7187 {
7188 symbol_context_scope = sc.comp_unit;
7189 }
Jason Molenda60db6e42014-10-16 01:40:16 +00007190 else if (sc.function != NULL && sc_parent_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007191 {
Greg Clayton81c22f62011-10-19 18:09:39 +00007192 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007193 if (symbol_context_scope == NULL)
7194 symbol_context_scope = sc.function;
7195 }
7196
7197 if (symbol_context_scope != NULL)
7198 {
7199 type_sp->SetSymbolContextScope(symbol_context_scope);
7200 }
7201
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00007202 // We are ready to put this type into the uniqued list up at the module level
7203 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00007204
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00007205 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007206 }
7207 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00007208 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007209 {
Greg Claytone1cd1be2012-01-29 20:56:30 +00007210 type_sp = type_ptr->shared_from_this();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007211 }
7212 }
7213 return type_sp;
7214}
7215
7216size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00007217SymbolFileDWARF::ParseTypes
7218(
7219 const SymbolContext& sc,
7220 DWARFCompileUnit* dwarf_cu,
7221 const DWARFDebugInfoEntry *die,
7222 bool parse_siblings,
7223 bool parse_children
7224)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007225{
7226 size_t types_added = 0;
7227 while (die != NULL)
7228 {
7229 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00007230 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007231 {
7232 if (type_is_new)
7233 ++types_added;
7234 }
7235
7236 if (parse_children && die->HasChildren())
7237 {
7238 if (die->Tag() == DW_TAG_subprogram)
7239 {
7240 SymbolContext child_sc(sc);
Greg Clayton81c22f62011-10-19 18:09:39 +00007241 child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007242 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
7243 }
7244 else
7245 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
7246 }
7247
7248 if (parse_siblings)
7249 die = die->GetSibling();
7250 else
7251 die = NULL;
7252 }
7253 return types_added;
7254}
7255
7256
7257size_t
7258SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
7259{
7260 assert(sc.comp_unit && sc.function);
7261 size_t functions_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00007262 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007263 if (dwarf_cu)
7264 {
7265 dw_offset_t function_die_offset = sc.function->GetID();
7266 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
7267 if (function_die)
7268 {
Greg Claytondd7feaf2011-08-12 17:54:33 +00007269 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007270 }
7271 }
7272
7273 return functions_added;
7274}
7275
7276
7277size_t
7278SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
7279{
7280 // At least a compile unit must be valid
7281 assert(sc.comp_unit);
7282 size_t types_added = 0;
Greg Clayton1f746072012-08-29 21:13:06 +00007283 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007284 if (dwarf_cu)
7285 {
7286 if (sc.function)
7287 {
7288 dw_offset_t function_die_offset = sc.function->GetID();
7289 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
7290 if (func_die && func_die->HasChildren())
7291 {
7292 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
7293 }
7294 }
7295 else
7296 {
7297 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
7298 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
7299 {
7300 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
7301 }
7302 }
7303 }
7304
7305 return types_added;
7306}
7307
7308size_t
7309SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
7310{
7311 if (sc.comp_unit != NULL)
7312 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00007313 DWARFDebugInfo* info = DebugInfo();
7314 if (info == NULL)
7315 return 0;
7316
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007317 if (sc.function)
7318 {
Greg Clayton9422dd62013-03-04 21:46:16 +00007319 DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get();
7320
7321 if (dwarf_cu == NULL)
7322 return 0;
7323
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007324 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00007325
Greg Claytonc7bece562013-01-25 18:06:21 +00007326 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
7327 if (func_lo_pc != LLDB_INVALID_ADDRESS)
Greg Claytone38a5ed2012-01-05 03:57:59 +00007328 {
7329 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Greg Claytonc662ec82011-06-17 22:10:16 +00007330
Greg Claytone38a5ed2012-01-05 03:57:59 +00007331 // Let all blocks know they have parse all their variables
7332 sc.function->GetBlock (false).SetDidParseVariables (true, true);
7333 return num_variables;
7334 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007335 }
7336 else if (sc.comp_unit)
7337 {
Greg Clayton9422dd62013-03-04 21:46:16 +00007338 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get();
7339
7340 if (dwarf_cu == NULL)
7341 return 0;
7342
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007343 uint32_t vars_added = 0;
7344 VariableListSP variables (sc.comp_unit->GetVariableList(false));
7345
7346 if (variables.get() == NULL)
7347 {
7348 variables.reset(new VariableList());
7349 sc.comp_unit->SetVariableList(variables);
7350
Greg Claytond4a2b372011-09-12 23:21:58 +00007351 DWARFCompileUnit* match_dwarf_cu = NULL;
7352 const DWARFDebugInfoEntry* die = NULL;
7353 DIEArray die_offsets;
Greg Clayton97fbc342011-10-20 22:30:33 +00007354 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00007355 {
Greg Clayton97fbc342011-10-20 22:30:33 +00007356 if (m_apple_names_ap.get())
Greg Claytond1767f02011-12-08 02:13:16 +00007357 {
7358 DWARFMappedHash::DIEInfoArray hash_data_array;
7359 if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
7360 dwarf_cu->GetNextCompileUnitOffset(),
7361 hash_data_array))
7362 {
7363 DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
7364 }
7365 }
Greg Clayton7f995132011-10-04 22:41:51 +00007366 }
7367 else
7368 {
7369 // Index if we already haven't to make sure the compile units
7370 // get indexed and make their global DIE index list
7371 if (!m_indexed)
7372 Index ();
7373
7374 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
7375 dwarf_cu->GetNextCompileUnitOffset(),
7376 die_offsets);
7377 }
7378
7379 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00007380 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007381 {
Greg Claytond4a2b372011-09-12 23:21:58 +00007382 DWARFDebugInfo* debug_info = DebugInfo();
7383 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007384 {
Greg Claytond4a2b372011-09-12 23:21:58 +00007385 const dw_offset_t die_offset = die_offsets[i];
7386 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
Greg Clayton95d87902011-11-11 03:16:25 +00007387 if (die)
Greg Claytond4a2b372011-09-12 23:21:58 +00007388 {
Greg Clayton95d87902011-11-11 03:16:25 +00007389 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
7390 if (var_sp)
7391 {
7392 variables->AddVariableIfUnique (var_sp);
7393 ++vars_added;
7394 }
Greg Claytond4a2b372011-09-12 23:21:58 +00007395 }
Greg Clayton95d87902011-11-11 03:16:25 +00007396 else
7397 {
7398 if (m_using_apple_tables)
7399 {
Greg Claytone38a5ed2012-01-05 03:57:59 +00007400 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 +00007401 }
7402 }
7403
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007404 }
7405 }
7406 }
7407 return vars_added;
7408 }
7409 }
7410 return 0;
7411}
7412
7413
7414VariableSP
7415SymbolFileDWARF::ParseVariableDIE
7416(
7417 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00007418 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00007419 const DWARFDebugInfoEntry *die,
7420 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007421)
7422{
Greg Clayton83c5cd92010-11-14 22:13:40 +00007423 VariableSP var_sp (m_die_to_variable_sp[die]);
7424 if (var_sp)
7425 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007426
7427 const dw_tag_t tag = die->Tag();
Richard Mitton0a558352013-10-17 21:14:00 +00007428 ModuleSP module = GetObjectFile()->GetModule();
Greg Clayton7f995132011-10-04 22:41:51 +00007429
7430 if ((tag == DW_TAG_variable) ||
7431 (tag == DW_TAG_constant) ||
7432 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007433 {
Greg Clayton7f995132011-10-04 22:41:51 +00007434 DWARFDebugInfoEntry::Attributes attributes;
7435 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
7436 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007437 {
Greg Clayton7f995132011-10-04 22:41:51 +00007438 const char *name = NULL;
7439 const char *mangled = NULL;
7440 Declaration decl;
7441 uint32_t i;
Greg Claytond1767f02011-12-08 02:13:16 +00007442 lldb::user_id_t type_uid = LLDB_INVALID_UID;
Greg Clayton7f995132011-10-04 22:41:51 +00007443 DWARFExpression location;
7444 bool is_external = false;
7445 bool is_artificial = false;
7446 bool location_is_const_value_data = false;
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007447 bool has_explicit_location = false;
Enrico Granata4ec130d2014-08-11 19:16:35 +00007448 DWARFFormValue const_value;
Greg Clayton23f59502012-07-17 03:23:13 +00007449 //AccessType accessibility = eAccessNone;
Greg Clayton7f995132011-10-04 22:41:51 +00007450
7451 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007452 {
Greg Clayton7f995132011-10-04 22:41:51 +00007453 dw_attr_t attr = attributes.AttributeAtIndex(i);
7454 DWARFFormValue form_value;
Greg Clayton54166af2014-11-22 01:58:59 +00007455
Greg Clayton7f995132011-10-04 22:41:51 +00007456 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007457 {
Greg Clayton7f995132011-10-04 22:41:51 +00007458 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007459 {
Greg Clayton7f995132011-10-04 22:41:51 +00007460 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
7461 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
7462 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
7463 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton71415542012-12-08 00:24:40 +00007464 case DW_AT_linkage_name:
Greg Clayton7f995132011-10-04 22:41:51 +00007465 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton54166af2014-11-22 01:58:59 +00007466 case DW_AT_type: type_uid = form_value.Reference(); break;
Greg Clayton1c8ef472013-04-05 23:27:21 +00007467 case DW_AT_external: is_external = form_value.Boolean(); break;
Greg Clayton7f995132011-10-04 22:41:51 +00007468 case DW_AT_const_value:
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007469 // If we have already found a DW_AT_location attribute, ignore this attribute.
7470 if (!has_explicit_location)
7471 {
7472 location_is_const_value_data = true;
7473 // The constant value will be either a block, a data value or a string.
Ed Masteeeae7212013-10-24 20:43:47 +00007474 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007475 if (DWARFFormValue::IsBlockForm(form_value.Form()))
7476 {
7477 // Retrieve the value as a block expression.
7478 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
7479 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00007480 location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007481 }
7482 else if (DWARFFormValue::IsDataForm(form_value.Form()))
7483 {
7484 // Retrieve the value as a data expression.
Greg Clayton54166af2014-11-22 01:58:59 +00007485 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007486 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
7487 uint32_t data_length = fixed_form_sizes[form_value.Form()];
Enrico Granata4ec130d2014-08-11 19:16:35 +00007488 if (data_length == 0)
7489 {
7490 const uint8_t *data_pointer = form_value.BlockData();
7491 if (data_pointer)
7492 {
Jason Molenda18f5fd32014-10-16 07:52:17 +00007493 form_value.Unsigned();
Enrico Granata4ec130d2014-08-11 19:16:35 +00007494 }
7495 else if (DWARFFormValue::IsDataForm(form_value.Form()))
7496 {
7497 // we need to get the byte size of the type later after we create the variable
7498 const_value = form_value;
7499 }
7500 }
7501 else
7502 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007503 }
7504 else
7505 {
7506 // Retrieve the value as a string expression.
7507 if (form_value.Form() == DW_FORM_strp)
7508 {
Greg Clayton54166af2014-11-22 01:58:59 +00007509 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007510 uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
7511 uint32_t data_length = fixed_form_sizes[form_value.Form()];
Richard Mitton0a558352013-10-17 21:14:00 +00007512 location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007513 }
7514 else
7515 {
7516 const char *str = form_value.AsCString(&debug_info_data);
7517 uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
7518 uint32_t string_length = strlen(str) + 1;
Richard Mitton0a558352013-10-17 21:14:00 +00007519 location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007520 }
7521 }
7522 }
7523 break;
Greg Clayton7f995132011-10-04 22:41:51 +00007524 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007525 {
Andrew Kaylorb32581f2013-02-13 19:57:06 +00007526 location_is_const_value_data = false;
7527 has_explicit_location = true;
Greg Clayton7f995132011-10-04 22:41:51 +00007528 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007529 {
Ed Masteeeae7212013-10-24 20:43:47 +00007530 const DWARFDataExtractor& debug_info_data = get_debug_info_data();
Greg Clayton7f995132011-10-04 22:41:51 +00007531
7532 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
7533 uint32_t block_length = form_value.Unsigned();
Richard Mitton0a558352013-10-17 21:14:00 +00007534 location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
Greg Clayton7f995132011-10-04 22:41:51 +00007535 }
7536 else
7537 {
Ed Masteeeae7212013-10-24 20:43:47 +00007538 const DWARFDataExtractor& debug_loc_data = get_debug_loc_data();
Greg Clayton7f995132011-10-04 22:41:51 +00007539 const dw_offset_t debug_loc_offset = form_value.Unsigned();
7540
7541 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
7542 if (loc_list_length > 0)
7543 {
Richard Mitton0a558352013-10-17 21:14:00 +00007544 location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
Greg Clayton7f995132011-10-04 22:41:51 +00007545 assert (func_low_pc != LLDB_INVALID_ADDRESS);
Greg Clayton54166af2014-11-22 01:58:59 +00007546 location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
Greg Clayton7f995132011-10-04 22:41:51 +00007547 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007548 }
7549 }
Greg Clayton7f995132011-10-04 22:41:51 +00007550 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007551
Greg Clayton1c8ef472013-04-05 23:27:21 +00007552 case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
Greg Clayton23f59502012-07-17 03:23:13 +00007553 case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7f995132011-10-04 22:41:51 +00007554 case DW_AT_declaration:
7555 case DW_AT_description:
7556 case DW_AT_endianity:
7557 case DW_AT_segment:
7558 case DW_AT_start_scope:
7559 case DW_AT_visibility:
7560 default:
7561 case DW_AT_abstract_origin:
7562 case DW_AT_sibling:
7563 case DW_AT_specification:
7564 break;
7565 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007566 }
7567 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007568
Greg Clayton9e9f2192013-05-17 00:55:28 +00007569 ValueType scope = eValueTypeInvalid;
7570
7571 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
7572 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
7573 SymbolContextScope * symbol_context_scope = NULL;
7574
Siva Chandra0783ab92015-03-24 18:32:27 +00007575 if (!mangled)
7576 {
7577 // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
7578 // generate fully qualified names of global variables with commands like "frame var j".
7579 // For example, if j were an int variable holding a value 4 and declared in a namespace
7580 // B which in turn is contained in a namespace A, the command "frame var j" returns
7581 // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
7582 // to generate a fully qualified name from the declaration context.
7583 if (die->GetParent()->Tag() == DW_TAG_compile_unit &&
7584 LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()))
7585 {
7586 DWARFDeclContext decl_ctx;
7587
7588 die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx);
7589 mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
7590 }
7591 }
7592
Greg Clayton9e9f2192013-05-17 00:55:28 +00007593 // DWARF doesn't specify if a DW_TAG_variable is a local, global
7594 // or static variable, so we have to do a little digging by
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00007595 // looking at the location of a variable to see if it contains
Greg Clayton9e9f2192013-05-17 00:55:28 +00007596 // a DW_OP_addr opcode _somewhere_ in the definition. I say
7597 // somewhere because clang likes to combine small global variables
7598 // into the same symbol and have locations like:
7599 // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
7600 // So if we don't have a DW_TAG_formal_parameter, we can look at
7601 // the location to see if it contains a DW_OP_addr opcode, and
7602 // then we can correctly classify our variables.
7603 if (tag == DW_TAG_formal_parameter)
7604 scope = eValueTypeVariableArgument;
7605 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007606 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007607 bool op_error = false;
7608 // Check if the location has a DW_OP_addr with any address value...
7609 lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
7610 if (!location_is_const_value_data)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007611 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007612 location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
7613 if (op_error)
Greg Clayton96c09682012-01-04 22:56:43 +00007614 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007615 StreamString strm;
7616 location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
7617 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 +00007618 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00007619 }
Greg Claytond1767f02011-12-08 02:13:16 +00007620
Greg Clayton9e9f2192013-05-17 00:55:28 +00007621 if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
7622 {
7623 if (is_external)
7624 scope = eValueTypeVariableGlobal;
7625 else
7626 scope = eValueTypeVariableStatic;
7627
7628
7629 SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
7630
7631 if (debug_map_symfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007632 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007633 // When leaving the DWARF in the .o files on darwin,
7634 // when we have a global variable that wasn't initialized,
7635 // the .o file might not have allocated a virtual
7636 // address for the global variable. In this case it will
7637 // have created a symbol for the global variable
7638 // that is undefined/data and external and the value will
7639 // be the byte size of the variable. When we do the
7640 // address map in SymbolFileDWARFDebugMap we rely on
7641 // having an address, we need to do some magic here
7642 // so we can get the correct address for our global
7643 // variable. The address for all of these entries
7644 // will be zero, and there will be an undefined symbol
7645 // in this object file, and the executable will have
7646 // a matching symbol with a good address. So here we
7647 // dig up the correct address and replace it in the
7648 // location for the variable, and set the variable's
7649 // symbol context scope to be that of the main executable
7650 // so the file address will resolve correctly.
7651 bool linked_oso_file_addr = false;
7652 if (is_external && location_DW_OP_addr == 0)
Greg Clayton9422dd62013-03-04 21:46:16 +00007653 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007654 // we have a possible uninitialized extern global
7655 ConstString const_name(mangled ? mangled : name);
7656 ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
7657 if (debug_map_objfile)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007658 {
Greg Clayton3046e662013-07-10 01:23:25 +00007659 Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
Greg Clayton9e9f2192013-05-17 00:55:28 +00007660 if (debug_map_symtab)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007661 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007662 Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
7663 eSymbolTypeData,
7664 Symtab::eDebugYes,
7665 Symtab::eVisibilityExtern);
7666 if (exe_symbol)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007667 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007668 if (exe_symbol->ValueIsAddress())
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007669 {
Greg Clayton358cf1e2015-06-25 21:46:34 +00007670 const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
Greg Clayton9e9f2192013-05-17 00:55:28 +00007671 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007672 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007673 if (location.Update_DW_OP_addr (exe_file_addr))
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007674 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007675 linked_oso_file_addr = true;
7676 symbol_context_scope = exe_symbol;
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007677 }
7678 }
7679 }
7680 }
7681 }
7682 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00007683 }
Greg Clayton9422dd62013-03-04 21:46:16 +00007684
Greg Clayton9e9f2192013-05-17 00:55:28 +00007685 if (!linked_oso_file_addr)
7686 {
7687 // The DW_OP_addr is not zero, but it contains a .o file address which
7688 // needs to be linked up correctly.
7689 const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
7690 if (exe_file_addr != LLDB_INVALID_ADDRESS)
Greg Clayton9422dd62013-03-04 21:46:16 +00007691 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007692 // Update the file address for this variable
7693 location.Update_DW_OP_addr (exe_file_addr);
7694 }
7695 else
7696 {
7697 // Variable didn't make it into the final executable
7698 return var_sp;
Greg Clayton9422dd62013-03-04 21:46:16 +00007699 }
Greg Claytond1767f02011-12-08 02:13:16 +00007700 }
Greg Clayton2fc93ea2011-11-13 04:15:56 +00007701 }
Greg Clayton5cf58b92011-10-05 22:22:08 +00007702 }
7703 else
7704 {
Greg Clayton9e9f2192013-05-17 00:55:28 +00007705 scope = eValueTypeVariableLocal;
Greg Clayton5cf58b92011-10-05 22:22:08 +00007706 }
Greg Clayton7f995132011-10-04 22:41:51 +00007707 }
Greg Clayton9e9f2192013-05-17 00:55:28 +00007708
7709 if (symbol_context_scope == NULL)
7710 {
7711 switch (parent_tag)
7712 {
7713 case DW_TAG_subprogram:
7714 case DW_TAG_inlined_subroutine:
7715 case DW_TAG_lexical_block:
7716 if (sc.function)
7717 {
7718 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
7719 if (symbol_context_scope == NULL)
7720 symbol_context_scope = sc.function;
7721 }
7722 break;
7723
7724 default:
7725 symbol_context_scope = sc.comp_unit;
7726 break;
7727 }
7728 }
7729
7730 if (symbol_context_scope)
7731 {
Enrico Granata4ec130d2014-08-11 19:16:35 +00007732 SymbolFileTypeSP type_sp(new SymbolFileType(*this, type_uid));
7733
7734 if (const_value.Form() && type_sp && type_sp->GetType())
7735 location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), dwarf_cu->GetAddressByteSize());
7736
Greg Clayton9e9f2192013-05-17 00:55:28 +00007737 var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
7738 name,
7739 mangled,
Enrico Granata4ec130d2014-08-11 19:16:35 +00007740 type_sp,
Greg Clayton9e9f2192013-05-17 00:55:28 +00007741 scope,
7742 symbol_context_scope,
7743 &decl,
7744 location,
7745 is_external,
7746 is_artificial));
7747
7748 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
7749 }
7750 else
7751 {
7752 // Not ready to parse this variable yet. It might be a global
7753 // or static variable that is in a function scope and the function
7754 // in the symbol context wasn't filled in yet
7755 return var_sp;
7756 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007757 }
Greg Clayton7f995132011-10-04 22:41:51 +00007758 // Cache var_sp even if NULL (the variable was just a specification or
7759 // was missing vital information to be able to be displayed in the debugger
7760 // (missing location due to optimization, etc)) so we don't re-parse
7761 // this DIE over and over later...
7762 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007763 }
7764 return var_sp;
7765}
7766
Greg Claytonc662ec82011-06-17 22:10:16 +00007767
7768const DWARFDebugInfoEntry *
7769SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
7770 dw_offset_t spec_block_die_offset,
7771 DWARFCompileUnit **result_die_cu_handle)
7772{
7773 // Give the concrete function die specified by "func_die_offset", find the
7774 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
7775 // to "spec_block_die_offset"
7776 DWARFDebugInfo* info = DebugInfo();
7777
7778 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
7779 if (die)
7780 {
7781 assert (*result_die_cu_handle);
7782 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
7783 }
7784 return NULL;
7785}
7786
7787
7788const DWARFDebugInfoEntry *
7789SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
7790 const DWARFDebugInfoEntry *die,
7791 dw_offset_t spec_block_die_offset,
7792 DWARFCompileUnit **result_die_cu_handle)
7793{
7794 if (die)
7795 {
7796 switch (die->Tag())
7797 {
7798 case DW_TAG_subprogram:
7799 case DW_TAG_inlined_subroutine:
7800 case DW_TAG_lexical_block:
7801 {
7802 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
7803 {
7804 *result_die_cu_handle = dwarf_cu;
7805 return die;
7806 }
7807
7808 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
7809 {
7810 *result_die_cu_handle = dwarf_cu;
7811 return die;
7812 }
7813 }
7814 break;
7815 }
7816
7817 // Give the concrete function die specified by "func_die_offset", find the
7818 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
7819 // to "spec_block_die_offset"
7820 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
7821 {
7822 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
7823 child_die,
7824 spec_block_die_offset,
7825 result_die_cu_handle);
7826 if (result_die)
7827 return result_die;
7828 }
7829 }
7830
7831 *result_die_cu_handle = NULL;
7832 return NULL;
7833}
7834
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007835size_t
7836SymbolFileDWARF::ParseVariables
7837(
7838 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00007839 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00007840 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007841 const DWARFDebugInfoEntry *orig_die,
7842 bool parse_siblings,
7843 bool parse_children,
7844 VariableList* cc_variable_list
7845)
7846{
7847 if (orig_die == NULL)
7848 return 0;
7849
Greg Claytonc662ec82011-06-17 22:10:16 +00007850 VariableListSP variable_list_sp;
7851
7852 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007853 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00007854 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007855 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007856 dw_tag_t tag = die->Tag();
7857
7858 // Check to see if we have already parsed this variable or constant?
7859 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007860 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007861 if (cc_variable_list)
7862 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007863 }
7864 else
7865 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007866 // We haven't already parsed it, lets do that now.
7867 if ((tag == DW_TAG_variable) ||
7868 (tag == DW_TAG_constant) ||
7869 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007870 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007871 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00007872 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007873 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
7874 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
7875 switch (parent_tag)
7876 {
7877 case DW_TAG_compile_unit:
7878 if (sc.comp_unit != NULL)
7879 {
7880 variable_list_sp = sc.comp_unit->GetVariableList(false);
7881 if (variable_list_sp.get() == NULL)
7882 {
7883 variable_list_sp.reset(new VariableList());
7884 sc.comp_unit->SetVariableList(variable_list_sp);
7885 }
7886 }
7887 else
7888 {
Daniel Malead01b2952012-11-29 21:49:15 +00007889 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 +00007890 MakeUserID(sc_parent_die->GetOffset()),
7891 DW_TAG_value_to_name (parent_tag),
7892 MakeUserID(orig_die->GetOffset()),
7893 DW_TAG_value_to_name (orig_die->Tag()));
Greg Claytonc662ec82011-06-17 22:10:16 +00007894 }
7895 break;
7896
7897 case DW_TAG_subprogram:
7898 case DW_TAG_inlined_subroutine:
7899 case DW_TAG_lexical_block:
7900 if (sc.function != NULL)
7901 {
7902 // Check to see if we already have parsed the variables for the given scope
7903
Greg Clayton81c22f62011-10-19 18:09:39 +00007904 Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Greg Claytonc662ec82011-06-17 22:10:16 +00007905 if (block == NULL)
7906 {
7907 // This must be a specification or abstract origin with
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +00007908 // a concrete block counterpart in the current function. We need
Greg Claytonc662ec82011-06-17 22:10:16 +00007909 // to find the concrete block so we can correctly add the
7910 // variable to it
7911 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
7912 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
7913 sc_parent_die->GetOffset(),
7914 &concrete_block_die_cu);
7915 if (concrete_block_die)
Greg Clayton81c22f62011-10-19 18:09:39 +00007916 block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset()));
Greg Claytonc662ec82011-06-17 22:10:16 +00007917 }
7918
7919 if (block != NULL)
7920 {
7921 const bool can_create = false;
7922 variable_list_sp = block->GetBlockVariableList (can_create);
7923 if (variable_list_sp.get() == NULL)
7924 {
7925 variable_list_sp.reset(new VariableList());
7926 block->SetVariableList(variable_list_sp);
7927 }
7928 }
7929 }
7930 break;
7931
7932 default:
Daniel Malead01b2952012-11-29 21:49:15 +00007933 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 +00007934 MakeUserID(orig_die->GetOffset()),
7935 DW_TAG_value_to_name (orig_die->Tag()));
Greg Claytonc662ec82011-06-17 22:10:16 +00007936 break;
7937 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00007938 }
Greg Claytonc662ec82011-06-17 22:10:16 +00007939
7940 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007941 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00007942 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
7943 if (var_sp)
7944 {
Greg Claytonc662ec82011-06-17 22:10:16 +00007945 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00007946 if (cc_variable_list)
7947 cc_variable_list->AddVariableIfUnique (var_sp);
7948 ++vars_added;
7949 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007950 }
7951 }
7952 }
Greg Claytonc662ec82011-06-17 22:10:16 +00007953
7954 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
7955
7956 if (!skip_children && parse_children && die->HasChildren())
7957 {
7958 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
7959 }
7960
7961 if (parse_siblings)
7962 die = die->GetSibling();
7963 else
7964 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007965 }
Greg Claytonc662ec82011-06-17 22:10:16 +00007966 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007967}
7968
7969//------------------------------------------------------------------
7970// PluginInterface protocol
7971//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00007972ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007973SymbolFileDWARF::GetPluginName()
7974{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00007975 return GetPluginNameStatic();
7976}
7977
7978uint32_t
7979SymbolFileDWARF::GetPluginVersion()
7980{
7981 return 1;
7982}
7983
7984void
Greg Clayton6beaaa62011-01-17 03:46:26 +00007985SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
7986{
7987 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
Greg Clayton57ee3062013-07-11 22:46:58 +00007988 ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00007989 if (clang_type)
7990 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
7991}
7992
7993void
7994SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
7995{
7996 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
Greg Clayton57ee3062013-07-11 22:46:58 +00007997 ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
Greg Clayton6beaaa62011-01-17 03:46:26 +00007998 if (clang_type)
7999 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
8000}
8001
Greg Claytona2721472011-06-25 00:44:06 +00008002void
Sean Callanancc427fa2011-07-30 02:42:06 +00008003SymbolFileDWARF::DumpIndexes ()
8004{
8005 StreamFile s(stdout, false);
8006
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00008007 s.Printf ("DWARF index for (%s) '%s':",
Sean Callanancc427fa2011-07-30 02:42:06 +00008008 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +00008009 GetObjectFile()->GetFileSpec().GetPath().c_str());
Sean Callanancc427fa2011-07-30 02:42:06 +00008010 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
8011 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
8012 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
8013 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
8014 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
8015 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
8016 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
8017 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
8018}
8019
8020void
8021SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
8022 const char *name,
8023 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00008024{
Sean Callanancc427fa2011-07-30 02:42:06 +00008025 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00008026
8027 if (iter == m_decl_ctx_to_die.end())
8028 return;
8029
Greg Claytoncb5860a2011-10-13 23:49:28 +00008030 for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos)
Greg Claytona2721472011-06-25 00:44:06 +00008031 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00008032 const DWARFDebugInfoEntry *context_die = *pos;
8033
8034 if (!results)
8035 return;
8036
8037 DWARFDebugInfo* info = DebugInfo();
8038
8039 DIEArray die_offsets;
8040
8041 DWARFCompileUnit* dwarf_cu = NULL;
8042 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton220a0072011-12-09 08:48:30 +00008043
8044 if (m_using_apple_tables)
8045 {
8046 if (m_apple_types_ap.get())
8047 m_apple_types_ap->FindByName (name, die_offsets);
8048 }
8049 else
8050 {
8051 if (!m_indexed)
8052 Index ();
8053
8054 m_type_index.Find (ConstString(name), die_offsets);
8055 }
8056
Greg Clayton220a0072011-12-09 08:48:30 +00008057 const size_t num_matches = die_offsets.size();
Greg Claytoncb5860a2011-10-13 23:49:28 +00008058
8059 if (num_matches)
Greg Claytona2721472011-06-25 00:44:06 +00008060 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00008061 for (size_t i = 0; i < num_matches; ++i)
8062 {
8063 const dw_offset_t die_offset = die_offsets[i];
8064 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Greg Claytond4a2b372011-09-12 23:21:58 +00008065
Greg Claytoncb5860a2011-10-13 23:49:28 +00008066 if (die->GetParent() != context_die)
8067 continue;
8068
8069 Type *matching_type = ResolveType (dwarf_cu, die);
8070
Pavel Labathc7c30eb2015-06-08 23:38:06 +00008071 clang::QualType qual_type = matching_type->GetClangForwardType().GetQualType();
Greg Claytoncb5860a2011-10-13 23:49:28 +00008072
8073 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
8074 {
8075 clang::TagDecl *tag_decl = tag_type->getDecl();
8076 results->push_back(tag_decl);
8077 }
8078 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
8079 {
8080 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
8081 results->push_back(typedef_decl);
8082 }
Greg Claytona2721472011-06-25 00:44:06 +00008083 }
8084 }
8085 }
8086}
8087
8088void
8089SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
Greg Clayton85ae2e12011-10-18 23:36:41 +00008090 const clang::DeclContext *decl_context,
8091 clang::DeclarationName decl_name,
Greg Claytona2721472011-06-25 00:44:06 +00008092 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
8093{
Greg Clayton85ae2e12011-10-18 23:36:41 +00008094
8095 switch (decl_context->getDeclKind())
8096 {
8097 case clang::Decl::Namespace:
8098 case clang::Decl::TranslationUnit:
8099 {
8100 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
8101 symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results);
8102 }
8103 break;
8104 default:
8105 break;
8106 }
Greg Claytona2721472011-06-25 00:44:06 +00008107}
Greg Claytoncaab74e2012-01-28 00:48:57 +00008108
Zachary Turner504f38d2015-03-24 16:24:50 +00008109bool
8110SymbolFileDWARF::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size,
8111 uint64_t &alignment,
Zachary Turnera98fac22015-03-24 18:56:08 +00008112 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
8113 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
8114 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
Greg Claytoncaab74e2012-01-28 00:48:57 +00008115{
8116 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
8117 return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets);
8118}
8119
Zachary Turner504f38d2015-03-24 16:24:50 +00008120bool
8121SymbolFileDWARF::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
Zachary Turnera98fac22015-03-24 18:56:08 +00008122 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
8123 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
8124 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
Greg Claytoncaab74e2012-01-28 00:48:57 +00008125{
Greg Clayton5160ce52013-03-27 23:08:40 +00008126 Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Greg Claytoncaab74e2012-01-28 00:48:57 +00008127 RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
8128 bool success = false;
8129 base_offsets.clear();
8130 vbase_offsets.clear();
8131 if (pos != m_record_decl_to_layout_map.end())
8132 {
8133 bit_size = pos->second.bit_size;
8134 alignment = pos->second.alignment;
8135 field_offsets.swap(pos->second.field_offsets);
Greg Clayton2508b9b2012-11-01 23:20:02 +00008136 base_offsets.swap (pos->second.base_offsets);
8137 vbase_offsets.swap (pos->second.vbase_offsets);
Greg Claytoncaab74e2012-01-28 00:48:57 +00008138 m_record_decl_to_layout_map.erase(pos);
8139 success = true;
8140 }
8141 else
8142 {
8143 bit_size = 0;
8144 alignment = 0;
8145 field_offsets.clear();
8146 }
8147
8148 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00008149 GetObjectFile()->GetModule()->LogMessage (log,
Daniel Malead01b2952012-11-29 21:49:15 +00008150 "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 +00008151 static_cast<const void*>(record_decl),
8152 bit_size, alignment,
8153 static_cast<uint32_t>(field_offsets.size()),
8154 static_cast<uint32_t>(base_offsets.size()),
8155 static_cast<uint32_t>(vbase_offsets.size()),
Greg Claytoncaab74e2012-01-28 00:48:57 +00008156 success);
8157 return success;
8158}
8159
8160
Greg Clayton1f746072012-08-29 21:13:06 +00008161SymbolFileDWARFDebugMap *
8162SymbolFileDWARF::GetDebugMapSymfile ()
8163{
8164 if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
8165 {
8166 lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
8167 if (module_sp)
8168 {
8169 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
8170 if (sym_vendor)
8171 m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
8172 }
8173 }
8174 return m_debug_map_symfile;
8175}
8176
Greg Claytoncaab74e2012-01-28 00:48:57 +00008177