blob: cd143a96ee7982b7e78f5e0cdd9f4f087ffa38cf [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"
17#include "clang/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
Greg Clayton7fedea22010-11-16 02:10:54 +000023#include "clang/Sema/DeclSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024
25#include "lldb/Core/Module.h"
26#include "lldb/Core/PluginManager.h"
27#include "lldb/Core/RegularExpression.h"
28#include "lldb/Core/Scalar.h"
29#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000030#include "lldb/Core/StreamFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Core/Timer.h"
32#include "lldb/Core/Value.h"
33
34#include "lldb/Symbol/Block.h"
35#include "lldb/Symbol/CompileUnit.h"
36#include "lldb/Symbol/LineTable.h"
37#include "lldb/Symbol/ObjectFile.h"
38#include "lldb/Symbol/SymbolVendor.h"
39#include "lldb/Symbol/VariableList.h"
40
41#include "DWARFCompileUnit.h"
42#include "DWARFDebugAbbrev.h"
43#include "DWARFDebugAranges.h"
44#include "DWARFDebugInfo.h"
45#include "DWARFDebugInfoEntry.h"
46#include "DWARFDebugLine.h"
47#include "DWARFDebugPubnames.h"
48#include "DWARFDebugRanges.h"
49#include "DWARFDIECollection.h"
50#include "DWARFFormValue.h"
51#include "DWARFLocationList.h"
52#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000053#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054
55#include <map>
56
Greg Clayton62742b12010-11-11 01:09:45 +000057//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000058
59#ifdef ENABLE_DEBUG_PRINTF
60#include <stdio.h>
61#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
62#else
63#define DEBUG_PRINTF(fmt, ...)
64#endif
65
Greg Clayton594e5ed2010-09-27 21:07:38 +000066#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067
68using namespace lldb;
69using namespace lldb_private;
70
71
Sean Callananc7fbf732010-08-06 00:32:49 +000072static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000073DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074{
75 switch (dwarf_accessibility)
76 {
Sean Callananc7fbf732010-08-06 00:32:49 +000077 case DW_ACCESS_public: return eAccessPublic;
78 case DW_ACCESS_private: return eAccessPrivate;
79 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000080 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081 }
Sean Callananc7fbf732010-08-06 00:32:49 +000082 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083}
84
85void
86SymbolFileDWARF::Initialize()
87{
88 LogChannelDWARF::Initialize();
89 PluginManager::RegisterPlugin (GetPluginNameStatic(),
90 GetPluginDescriptionStatic(),
91 CreateInstance);
92}
93
94void
95SymbolFileDWARF::Terminate()
96{
97 PluginManager::UnregisterPlugin (CreateInstance);
98 LogChannelDWARF::Initialize();
99}
100
101
102const char *
103SymbolFileDWARF::GetPluginNameStatic()
104{
105 return "symbol-file.dwarf2";
106}
107
108const char *
109SymbolFileDWARF::GetPluginDescriptionStatic()
110{
111 return "DWARF and DWARF3 debug symbol file reader.";
112}
113
114
115SymbolFile*
116SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
117{
118 return new SymbolFileDWARF(obj_file);
119}
120
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000121
122ClangASTContext &
123SymbolFileDWARF::GetClangASTContext()
124{
125 return GetTypeList()->GetClangASTContext();
126}
127
128TypeList *
129SymbolFileDWARF::GetTypeList ()
130{
131 if (m_debug_map_symfile)
132 return m_debug_map_symfile->GetTypeList();
133 return m_obj_file->GetModule()->GetTypeList();
134
135}
136
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137//----------------------------------------------------------------------
138// Gets the first parent that is a lexical block, function or inlined
139// subroutine, or compile unit.
140//----------------------------------------------------------------------
141static const DWARFDebugInfoEntry *
142GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
143{
144 const DWARFDebugInfoEntry *die;
145 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
146 {
147 dw_tag_t tag = die->Tag();
148
149 switch (tag)
150 {
151 case DW_TAG_compile_unit:
152 case DW_TAG_subprogram:
153 case DW_TAG_inlined_subroutine:
154 case DW_TAG_lexical_block:
155 return die;
156 }
157 }
158 return NULL;
159}
160
161
Greg Clayton450e3f32010-10-12 02:24:53 +0000162SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
163 SymbolFile (objfile),
164 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000165 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166 m_flags(),
167 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168 m_data_debug_frame(),
169 m_data_debug_info(),
170 m_data_debug_line(),
171 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172 m_data_debug_ranges(),
173 m_data_debug_str(),
174 m_abbr(),
175 m_aranges(),
176 m_info(),
177 m_line(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000178 m_function_basename_index(),
179 m_function_fullname_index(),
180 m_function_method_index(),
181 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000182 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000183 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000184 m_type_index(),
185 m_namespace_index(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186 m_indexed(false),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000187 m_ranges()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188{
189}
190
191SymbolFileDWARF::~SymbolFileDWARF()
192{
193}
194
195bool
196SymbolFileDWARF::SupportedVersion(uint16_t version)
197{
198 return version == 2 || version == 3;
199}
200
201uint32_t
202SymbolFileDWARF::GetAbilities ()
203{
204 uint32_t abilities = 0;
205 if (m_obj_file != NULL)
206 {
207 const Section* section = NULL;
208 const SectionList *section_list = m_obj_file->GetSectionList();
209 if (section_list == NULL)
210 return 0;
211
212 uint64_t debug_abbrev_file_size = 0;
213 uint64_t debug_aranges_file_size = 0;
214 uint64_t debug_frame_file_size = 0;
215 uint64_t debug_info_file_size = 0;
216 uint64_t debug_line_file_size = 0;
217 uint64_t debug_loc_file_size = 0;
218 uint64_t debug_macinfo_file_size = 0;
219 uint64_t debug_pubnames_file_size = 0;
220 uint64_t debug_pubtypes_file_size = 0;
221 uint64_t debug_ranges_file_size = 0;
222 uint64_t debug_str_file_size = 0;
223
224 static ConstString g_dwarf_section_name ("__DWARF");
225
226 section = section_list->FindSectionByName(g_dwarf_section_name).get();
227
228 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000229 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000230 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
Greg Clayton4ceb9982010-07-21 22:54:26 +0000231 section_list = &section->GetChildren ();
232 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000233
Greg Clayton4ceb9982010-07-21 22:54:26 +0000234 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235 if (section != NULL)
236 {
237 debug_info_file_size = section->GetByteSize();
238
Greg Clayton4ceb9982010-07-21 22:54:26 +0000239 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240 if (section)
241 debug_abbrev_file_size = section->GetByteSize();
242 else
243 m_flags.Set (flagsGotDebugAbbrevData);
244
Greg Clayton4ceb9982010-07-21 22:54:26 +0000245 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246 if (section)
247 debug_aranges_file_size = section->GetByteSize();
248 else
249 m_flags.Set (flagsGotDebugArangesData);
250
Greg Clayton4ceb9982010-07-21 22:54:26 +0000251 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252 if (section)
253 debug_frame_file_size = section->GetByteSize();
254 else
255 m_flags.Set (flagsGotDebugFrameData);
256
Greg Clayton4ceb9982010-07-21 22:54:26 +0000257 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258 if (section)
259 debug_line_file_size = section->GetByteSize();
260 else
261 m_flags.Set (flagsGotDebugLineData);
262
Greg Clayton4ceb9982010-07-21 22:54:26 +0000263 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264 if (section)
265 debug_loc_file_size = section->GetByteSize();
266 else
267 m_flags.Set (flagsGotDebugLocData);
268
Greg Clayton4ceb9982010-07-21 22:54:26 +0000269 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270 if (section)
271 debug_macinfo_file_size = section->GetByteSize();
272 else
273 m_flags.Set (flagsGotDebugMacInfoData);
274
Greg Clayton4ceb9982010-07-21 22:54:26 +0000275 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276 if (section)
277 debug_pubnames_file_size = section->GetByteSize();
278 else
279 m_flags.Set (flagsGotDebugPubNamesData);
280
Greg Clayton4ceb9982010-07-21 22:54:26 +0000281 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282 if (section)
283 debug_pubtypes_file_size = section->GetByteSize();
284 else
285 m_flags.Set (flagsGotDebugPubTypesData);
286
Greg Clayton4ceb9982010-07-21 22:54:26 +0000287 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288 if (section)
289 debug_ranges_file_size = section->GetByteSize();
290 else
291 m_flags.Set (flagsGotDebugRangesData);
292
Greg Clayton4ceb9982010-07-21 22:54:26 +0000293 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 if (section)
295 debug_str_file_size = section->GetByteSize();
296 else
297 m_flags.Set (flagsGotDebugStrData);
298 }
299
300 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
301 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
302
303 if (debug_line_file_size > 0)
304 abilities |= LineTables;
305
306 if (debug_aranges_file_size > 0)
307 abilities |= AddressAcceleratorTable;
308
309 if (debug_pubnames_file_size > 0)
310 abilities |= FunctionAcceleratorTable;
311
312 if (debug_pubtypes_file_size > 0)
313 abilities |= TypeAcceleratorTable;
314
315 if (debug_macinfo_file_size > 0)
316 abilities |= MacroInformation;
317
318 if (debug_frame_file_size > 0)
319 abilities |= CallFrameInformation;
320 }
321 return abilities;
322}
323
324const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000325SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326{
327 if (m_flags.IsClear (got_flag))
328 {
329 m_flags.Set (got_flag);
330 const SectionList *section_list = m_obj_file->GetSectionList();
331 if (section_list)
332 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000333 Section *section = section_list->FindSectionByType(sect_type, true).get();
334 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335 {
336 // See if we memory mapped the DWARF segment?
337 if (m_dwarf_data.GetByteSize())
338 {
339 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
340 }
341 else
342 {
343 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
344 data.Clear();
345 }
346 }
347 }
348 }
349 return data;
350}
351
352const DataExtractor&
353SymbolFileDWARF::get_debug_abbrev_data()
354{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000355 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000356}
357
358const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359SymbolFileDWARF::get_debug_frame_data()
360{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000361 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362}
363
364const DataExtractor&
365SymbolFileDWARF::get_debug_info_data()
366{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000367 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368}
369
370const DataExtractor&
371SymbolFileDWARF::get_debug_line_data()
372{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000373 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374}
375
376const DataExtractor&
377SymbolFileDWARF::get_debug_loc_data()
378{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000379 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380}
381
382const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383SymbolFileDWARF::get_debug_ranges_data()
384{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000385 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386}
387
388const DataExtractor&
389SymbolFileDWARF::get_debug_str_data()
390{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000391 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392}
393
394
395DWARFDebugAbbrev*
396SymbolFileDWARF::DebugAbbrev()
397{
398 if (m_abbr.get() == NULL)
399 {
400 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
401 if (debug_abbrev_data.GetByteSize() > 0)
402 {
403 m_abbr.reset(new DWARFDebugAbbrev());
404 if (m_abbr.get())
405 m_abbr->Parse(debug_abbrev_data);
406 }
407 }
408 return m_abbr.get();
409}
410
411const DWARFDebugAbbrev*
412SymbolFileDWARF::DebugAbbrev() const
413{
414 return m_abbr.get();
415}
416
417DWARFDebugAranges*
418SymbolFileDWARF::DebugAranges()
419{
Greg Clayton016a95e2010-09-14 02:20:48 +0000420 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
421 // and we are already parsing all of the DWARF because the .debug_pubnames
422 // is useless (it only mentions symbols that are externally visible), so
423 // don't use the .debug_aranges section, we should be using a debug aranges
424 // we got from SymbolFileDWARF::Index().
425
426 if (!m_indexed)
427 Index();
428
429
430// if (m_aranges.get() == NULL)
431// {
432// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
433// m_aranges.reset(new DWARFDebugAranges());
434// if (m_aranges.get())
435// {
436// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
437// if (debug_aranges_data.GetByteSize() > 0)
438// m_aranges->Extract(debug_aranges_data);
439// else
440// m_aranges->Generate(this);
441// }
442// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443 return m_aranges.get();
444}
445
446const DWARFDebugAranges*
447SymbolFileDWARF::DebugAranges() const
448{
449 return m_aranges.get();
450}
451
452
453DWARFDebugInfo*
454SymbolFileDWARF::DebugInfo()
455{
456 if (m_info.get() == NULL)
457 {
458 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
459 if (get_debug_info_data().GetByteSize() > 0)
460 {
461 m_info.reset(new DWARFDebugInfo());
462 if (m_info.get())
463 {
464 m_info->SetDwarfData(this);
465 }
466 }
467 }
468 return m_info.get();
469}
470
471const DWARFDebugInfo*
472SymbolFileDWARF::DebugInfo() const
473{
474 return m_info.get();
475}
476
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477DWARFCompileUnit*
478SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
479{
480 DWARFDebugInfo* info = DebugInfo();
481 if (info)
482 return info->GetCompileUnit(cu_uid).get();
483 return NULL;
484}
485
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486
487DWARFDebugRanges*
488SymbolFileDWARF::DebugRanges()
489{
490 if (m_ranges.get() == NULL)
491 {
492 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
493 if (get_debug_ranges_data().GetByteSize() > 0)
494 {
495 m_ranges.reset(new DWARFDebugRanges());
496 if (m_ranges.get())
497 m_ranges->Extract(this);
498 }
499 }
500 return m_ranges.get();
501}
502
503const DWARFDebugRanges*
504SymbolFileDWARF::DebugRanges() const
505{
506 return m_ranges.get();
507}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508
509bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000510SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511{
Greg Clayton96d7d742010-11-10 23:42:09 +0000512 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000513 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000514 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515 if (cu_die)
516 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000517 const char * cu_die_name = cu_die->GetName(this, curr_cu);
518 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
519 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520 if (cu_die_name)
521 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000522 FileSpec cu_file_spec;
523
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
525 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000526 // If we have a full path to the compile unit, we don't need to resolve
527 // the file. This can be expensive e.g. when the source files are NFS mounted.
528 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 }
530 else
531 {
532 std::string fullpath(cu_comp_dir);
533 if (*fullpath.rbegin() != '/')
534 fullpath += '/';
535 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000536 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000537 }
538
Greg Clayton96d7d742010-11-10 23:42:09 +0000539 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), class_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540 if (compile_unit_sp.get())
541 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000542 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000543 return true;
544 }
545 }
546 }
547 }
548 return false;
549}
550
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000551uint32_t
552SymbolFileDWARF::GetNumCompileUnits()
553{
554 DWARFDebugInfo* info = DebugInfo();
555 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557 return 0;
558}
559
560CompUnitSP
561SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
562{
563 CompUnitSP comp_unit;
564 DWARFDebugInfo* info = DebugInfo();
565 if (info)
566 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000567 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
568 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000569 {
570 // Our symbol vendor shouldn't be asking us to add a compile unit that
571 // has already been added to it, which this DWARF plug-in knows as it
572 // stores the lldb compile unit (CompileUnit) pointer in each
573 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000574 assert(curr_cu->GetUserData() == NULL);
575 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000576 }
577 }
578 return comp_unit;
579}
580
581static void
582AddRangesToBlock
583(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000584 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000585 DWARFDebugRanges::RangeList& ranges,
586 addr_t block_base_addr
587)
588{
589 ranges.SubtractOffset (block_base_addr);
590 size_t range_idx = 0;
591 const DWARFDebugRanges::Range *debug_range;
592 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
593 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000594 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000595 }
596}
597
598
599Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000600SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000601{
602 DWARFDebugRanges::RangeList func_ranges;
603 const char *name = NULL;
604 const char *mangled = NULL;
605 int decl_file = 0;
606 int decl_line = 0;
607 int decl_column = 0;
608 int call_file = 0;
609 int call_line = 0;
610 int call_column = 0;
611 DWARFExpression frame_base;
612
Greg Claytonc93237c2010-10-01 20:48:32 +0000613 assert (die->Tag() == DW_TAG_subprogram);
614
615 if (die->Tag() != DW_TAG_subprogram)
616 return NULL;
617
618 const DWARFDebugInfoEntry *parent_die = die->GetParent();
619 switch (parent_die->Tag())
620 {
621 case DW_TAG_structure_type:
622 case DW_TAG_class_type:
623 // We have methods of a class or struct
624 {
625 Type *class_type = ResolveType (dwarf_cu, parent_die);
626 if (class_type)
627 class_type->GetClangType();
628 }
629 break;
630
631 default:
632 // Parse the function prototype as a type that can then be added to concrete function instance
633 ParseTypes (sc, dwarf_cu, die, false, false);
634 break;
635 }
636
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637 //FixupTypes();
638
639 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
640 {
641 // Union of all ranges in the function DIE (if the function is discontiguous)
642 AddressRange func_range;
643 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
644 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
645 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
646 {
647 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
648 if (func_range.GetBaseAddress().IsValid())
649 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
650 }
651
652 if (func_range.GetBaseAddress().IsValid())
653 {
654 Mangled func_name;
655 if (mangled)
656 func_name.SetValue(mangled, true);
657 else if (name)
658 func_name.SetValue(name, false);
659
660 FunctionSP func_sp;
661 std::auto_ptr<Declaration> decl_ap;
662 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000663 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
664 decl_line,
665 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000666
Greg Clayton594e5ed2010-09-27 21:07:38 +0000667 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000668
669 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
670
671 func_range.GetBaseAddress().ResolveLinkedAddress();
672
673 func_sp.reset(new Function (sc.comp_unit,
674 die->GetOffset(), // UserID is the DIE offset
675 die->GetOffset(),
676 func_name,
677 func_type,
678 func_range)); // first address range
679
680 if (func_sp.get() != NULL)
681 {
682 func_sp->GetFrameBaseExpression() = frame_base;
683 sc.comp_unit->AddFunction(func_sp);
684 return func_sp.get();
685 }
686 }
687 }
688 return NULL;
689}
690
691size_t
692SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
693{
694 assert (sc.comp_unit);
695 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000696 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697 if (dwarf_cu)
698 {
699 DWARFDIECollection function_dies;
700 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
701 size_t func_idx;
702 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
703 {
704 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
705 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
706 {
707 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
708 ++functions_added;
709 }
710 }
711 //FixupTypes();
712 }
713 return functions_added;
714}
715
716bool
717SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
718{
719 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000720 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
721 assert (curr_cu);
722 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000723
724 if (cu_die)
725 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000726 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
727 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000728
729 // All file indexes in DWARF are one based and a file of index zero is
730 // supposed to be the compile unit itself.
731 support_files.Append (*sc.comp_unit);
732
733 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
734 }
735 return false;
736}
737
738struct ParseDWARFLineTableCallbackInfo
739{
740 LineTable* line_table;
741 const SectionList *section_list;
742 lldb::addr_t prev_sect_file_base_addr;
743 lldb::addr_t curr_sect_file_base_addr;
744 bool is_oso_for_debug_map;
745 bool prev_in_final_executable;
746 DWARFDebugLine::Row prev_row;
747 SectionSP prev_section_sp;
748 SectionSP curr_section_sp;
749};
750
751//----------------------------------------------------------------------
752// ParseStatementTableCallback
753//----------------------------------------------------------------------
754static void
755ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
756{
757 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
758 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
759 {
760 // Just started parsing the line table
761 }
762 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
763 {
764 // Done parsing line table, nothing to do for the cleanup
765 }
766 else
767 {
768 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
769 // We have a new row, lets append it
770
771 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
772 {
773 info->prev_section_sp = info->curr_section_sp;
774 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
775 // If this is an end sequence entry, then we subtract one from the
776 // address to make sure we get an address that is not the end of
777 // a section.
778 if (state.end_sequence && state.address != 0)
779 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
780 else
781 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
782
783 if (info->curr_section_sp.get())
784 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
785 else
786 info->curr_sect_file_base_addr = 0;
787 }
788 if (info->curr_section_sp.get())
789 {
790 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
791 // Check for the fancy section magic to determine if we
792
793 if (info->is_oso_for_debug_map)
794 {
795 // When this is a debug map object file that contains DWARF
796 // (referenced from an N_OSO debug map nlist entry) we will have
797 // a file address in the file range for our section from the
798 // original .o file, and a load address in the executable that
799 // contains the debug map.
800 //
801 // If the sections for the file range and load range are
802 // different, we have a remapped section for the function and
803 // this address is resolved. If they are the same, then the
804 // function for this address didn't make it into the final
805 // executable.
806 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
807
808 // If we are doing DWARF with debug map, then we need to carefully
809 // add each line table entry as there may be gaps as functions
810 // get moved around or removed.
811 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
812 {
813 if (info->prev_in_final_executable)
814 {
815 bool terminate_previous_entry = false;
816 if (!curr_in_final_executable)
817 {
818 // Check for the case where the previous line entry
819 // in a function made it into the final executable,
820 // yet the current line entry falls in a function
821 // that didn't. The line table used to be contiguous
822 // through this address range but now it isn't. We
823 // need to terminate the previous line entry so
824 // that we can reconstruct the line range correctly
825 // for it and to keep the line table correct.
826 terminate_previous_entry = true;
827 }
828 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
829 {
830 // Check for cases where the line entries used to be
831 // contiguous address ranges, but now they aren't.
832 // This can happen when order files specify the
833 // ordering of the functions.
834 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
835 Section *curr_sect = info->curr_section_sp.get();
836 Section *prev_sect = info->prev_section_sp.get();
837 assert (curr_sect->GetLinkedSection());
838 assert (prev_sect->GetLinkedSection());
839 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
840 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
841 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
842 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
843 if (object_file_addr_delta != linked_file_addr_delta)
844 terminate_previous_entry = true;
845 }
846
847 if (terminate_previous_entry)
848 {
849 line_table->InsertLineEntry (info->prev_section_sp,
850 state.address - info->prev_sect_file_base_addr,
851 info->prev_row.line,
852 info->prev_row.column,
853 info->prev_row.file,
854 false, // is_stmt
855 false, // basic_block
856 false, // state.prologue_end
857 false, // state.epilogue_begin
858 true); // end_sequence);
859 }
860 }
861 }
862
863 if (curr_in_final_executable)
864 {
865 line_table->InsertLineEntry (info->curr_section_sp,
866 curr_line_section_offset,
867 state.line,
868 state.column,
869 state.file,
870 state.is_stmt,
871 state.basic_block,
872 state.prologue_end,
873 state.epilogue_begin,
874 state.end_sequence);
875 info->prev_section_sp = info->curr_section_sp;
876 }
877 else
878 {
879 // If the current address didn't make it into the final
880 // executable, the current section will be the __text
881 // segment in the .o file, so we need to clear this so
882 // we can catch the next function that did make it into
883 // the final executable.
884 info->prev_section_sp.reset();
885 info->curr_section_sp.reset();
886 }
887
888 info->prev_in_final_executable = curr_in_final_executable;
889 }
890 else
891 {
892 // We are not in an object file that contains DWARF for an
893 // N_OSO, this is just a normal DWARF file. The DWARF spec
894 // guarantees that the addresses will be in increasing order
895 // so, since we store line tables in file address order, we
896 // can always just append the line entry without needing to
897 // search for the correct insertion point (we don't need to
898 // use LineEntry::InsertLineEntry()).
899 line_table->AppendLineEntry (info->curr_section_sp,
900 curr_line_section_offset,
901 state.line,
902 state.column,
903 state.file,
904 state.is_stmt,
905 state.basic_block,
906 state.prologue_end,
907 state.epilogue_begin,
908 state.end_sequence);
909 }
910 }
911
912 info->prev_row = state;
913 }
914}
915
916bool
917SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
918{
919 assert (sc.comp_unit);
920 if (sc.comp_unit->GetLineTable() != NULL)
921 return true;
922
923 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
924 if (dwarf_cu)
925 {
926 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
927 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
928 if (cu_line_offset != DW_INVALID_OFFSET)
929 {
930 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
931 if (line_table_ap.get())
932 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000933 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000934 uint32_t offset = cu_line_offset;
935 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
936 sc.comp_unit->SetLineTable(line_table_ap.release());
937 return true;
938 }
939 }
940 }
941 return false;
942}
943
944size_t
945SymbolFileDWARF::ParseFunctionBlocks
946(
947 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000948 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +0000949 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000950 const DWARFDebugInfoEntry *die,
951 addr_t subprogram_low_pc,
952 bool parse_siblings,
953 bool parse_children
954)
955{
956 size_t blocks_added = 0;
957 while (die != NULL)
958 {
959 dw_tag_t tag = die->Tag();
960
961 switch (tag)
962 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000963 case DW_TAG_inlined_subroutine:
Jim Inghamb0be4422010-08-12 01:20:14 +0000964 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000965 case DW_TAG_lexical_block:
966 {
967 DWARFDebugRanges::RangeList ranges;
968 const char *name = NULL;
969 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000970 Block *block = NULL;
971 if (tag != DW_TAG_subprogram)
972 {
973 BlockSP block_sp(new Block (die->GetOffset()));
974 parent_block->AddChild(block_sp);
975 block = block_sp.get();
976 }
977 else
978 {
979 block = parent_block;
980 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000982 int decl_file = 0;
983 int decl_line = 0;
984 int decl_column = 0;
985 int call_file = 0;
986 int call_line = 0;
987 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000988 if (die->GetDIENamesAndRanges (this,
989 dwarf_cu,
990 name,
991 mangled_name,
992 ranges,
993 decl_file, decl_line, decl_column,
994 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995 {
996 if (tag == DW_TAG_subprogram)
997 {
998 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
999 subprogram_low_pc = ranges.LowestAddress(0);
1000 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001001 else if (tag == DW_TAG_inlined_subroutine)
1002 {
1003 // We get called here for inlined subroutines in two ways.
1004 // The first time is when we are making the Function object
1005 // for this inlined concrete instance. Since we're creating a top level block at
1006 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1007 // adjust the containing address.
1008 // The second time is when we are parsing the blocks inside the function that contains
1009 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1010 // function the offset will be for that function.
1011 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1012 {
1013 subprogram_low_pc = ranges.LowestAddress(0);
1014 }
1015 }
1016
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001017 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001018
1019 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1020 {
1021 std::auto_ptr<Declaration> decl_ap;
1022 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001023 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1024 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001025
1026 std::auto_ptr<Declaration> call_ap;
1027 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001028 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1029 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001030
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001031 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032 }
1033
1034 ++blocks_added;
1035
1036 if (parse_children && die->HasChildren())
1037 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001038 blocks_added += ParseFunctionBlocks (sc,
1039 block,
1040 dwarf_cu,
1041 die->GetFirstChild(),
1042 subprogram_low_pc,
1043 true,
1044 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001045 }
1046 }
1047 }
1048 break;
1049 default:
1050 break;
1051 }
1052
1053 if (parse_siblings)
1054 die = die->GetSibling();
1055 else
1056 die = NULL;
1057 }
1058 return blocks_added;
1059}
1060
1061size_t
1062SymbolFileDWARF::ParseChildMembers
1063(
1064 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001065 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001067 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001068 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001069 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1070 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001071 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001072 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001073 bool &is_a_class
1074)
1075{
1076 if (parent_die == NULL)
1077 return 0;
1078
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079 size_t count = 0;
1080 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001081 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1082
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001083 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1084 {
1085 dw_tag_t tag = die->Tag();
1086
1087 switch (tag)
1088 {
1089 case DW_TAG_member:
1090 {
1091 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001092 const size_t num_attributes = die->GetAttributes (this,
1093 dwarf_cu,
1094 fixed_form_sizes,
1095 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096 if (num_attributes > 0)
1097 {
1098 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001099 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001100 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001101 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001102 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001103 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001104 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001105 size_t byte_size = 0;
1106 size_t bit_offset = 0;
1107 size_t bit_size = 0;
1108 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001109 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001110 {
1111 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1112 DWARFFormValue form_value;
1113 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1114 {
1115 switch (attr)
1116 {
1117 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1118 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1119 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1120 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1121 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1122 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1123 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1124 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1125 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001126// if (form_value.BlockData())
1127// {
1128// Value initialValue(0);
1129// Value memberOffset(0);
1130// const DataExtractor& debug_info_data = get_debug_info_data();
1131// uint32_t block_length = form_value.Unsigned();
1132// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1133// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1134// {
1135// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1136// }
1137// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001138 break;
1139
Greg Clayton8cf05932010-07-22 18:30:50 +00001140 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001141 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001142 case DW_AT_declaration:
1143 case DW_AT_description:
1144 case DW_AT_mutable:
1145 case DW_AT_visibility:
1146 default:
1147 case DW_AT_sibling:
1148 break;
1149 }
1150 }
1151 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001152
1153 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1154
1155 if (class_language == eLanguageTypeObjC ||
1156 class_language == eLanguageTypeObjC_plus_plus)
1157 accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001158
Greg Clayton24739922010-10-13 03:15:28 +00001159 if (is_artificial == false)
1160 {
1161 Type *member_type = ResolveTypeUID(encoding_uid);
1162 assert(member_type);
1163 if (accessibility == eAccessNone)
1164 accessibility = default_accessibility;
1165 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166
Greg Claytonba2d22d2010-11-13 22:57:37 +00001167 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1168 name,
1169 member_type->GetClangLayoutType(),
1170 accessibility,
1171 bit_size);
Greg Clayton24739922010-10-13 03:15:28 +00001172 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001173 }
1174 }
1175 break;
1176
1177 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001178 // Let the type parsing code handle this one for us.
1179 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180 break;
1181
1182 case DW_TAG_inheritance:
1183 {
1184 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001185 if (default_accessibility == eAccessNone)
1186 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001187 // TODO: implement DW_TAG_inheritance type parsing
1188 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001189 const size_t num_attributes = die->GetAttributes (this,
1190 dwarf_cu,
1191 fixed_form_sizes,
1192 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001193 if (num_attributes > 0)
1194 {
1195 Declaration decl;
1196 DWARFExpression location;
1197 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001198 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001199 bool is_virtual = false;
1200 bool is_base_of_class = true;
1201 off_t member_offset = 0;
1202 uint32_t i;
1203 for (i=0; i<num_attributes; ++i)
1204 {
1205 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1206 DWARFFormValue form_value;
1207 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1208 {
1209 switch (attr)
1210 {
1211 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1212 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1213 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1214 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1215 case DW_AT_data_member_location:
1216 if (form_value.BlockData())
1217 {
1218 Value initialValue(0);
1219 Value memberOffset(0);
1220 const DataExtractor& debug_info_data = get_debug_info_data();
1221 uint32_t block_length = form_value.Unsigned();
1222 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001223 if (DWARFExpression::Evaluate (NULL,
1224 NULL,
1225 debug_info_data,
1226 NULL,
1227 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001228 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001229 block_offset,
1230 block_length,
1231 eRegisterKindDWARF,
1232 &initialValue,
1233 memberOffset,
1234 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001235 {
1236 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1237 }
1238 }
1239 break;
1240
1241 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001242 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001243 break;
1244
1245 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1246 default:
1247 case DW_AT_sibling:
1248 break;
1249 }
1250 }
1251 }
1252
Greg Clayton526e5af2010-11-13 03:52:47 +00001253 Type *base_class_type = ResolveTypeUID(encoding_uid);
1254 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001255
1256 if (class_language == eLanguageTypeObjC)
1257 {
Greg Clayton526e5af2010-11-13 03:52:47 +00001258 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_type->GetClangType());
Greg Clayton9e409562010-07-28 02:04:09 +00001259 }
1260 else
1261 {
Greg Claytonba2d22d2010-11-13 22:57:37 +00001262 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_type->GetClangType(),
1263 accessibility,
1264 is_virtual,
1265 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001266 assert(base_classes.back());
1267 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001268 }
1269 }
1270 break;
1271
1272 default:
1273 break;
1274 }
1275 }
1276 return count;
1277}
1278
1279
1280clang::DeclContext*
1281SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1282{
1283 DWARFDebugInfo* debug_info = DebugInfo();
1284 if (debug_info)
1285 {
1286 DWARFCompileUnitSP cu_sp;
1287 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1288 if (die)
1289 return GetClangDeclContextForDIE (cu_sp.get(), die);
1290 }
1291 return NULL;
1292}
1293
1294Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001295SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001296{
1297 DWARFDebugInfo* debug_info = DebugInfo();
1298 if (debug_info)
1299 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001300 DWARFCompileUnitSP cu_sp;
1301 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001302 if (type_die != NULL)
Greg Clayton594e5ed2010-09-27 21:07:38 +00001303 return ResolveType (cu_sp.get(), type_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001304 }
1305 return NULL;
1306}
1307
Greg Clayton1be10fc2010-09-29 01:12:09 +00001308lldb::clang_type_t
1309SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1310{
1311 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Claytonc93237c2010-10-01 20:48:32 +00001312 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (ClangASTType::RemoveFastQualifiers(clang_type));
Greg Clayton1be10fc2010-09-29 01:12:09 +00001313 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001314 {
1315 // We have already resolved this type...
1316 return clang_type;
1317 }
1318 // Once we start resolving this type, remove it from the forward declaration
1319 // map in case anyone child members or other types require this type to get resolved.
1320 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1321 // are done.
1322 m_forward_decl_clang_type_to_die.erase (ClangASTType::RemoveFastQualifiers(clang_type));
1323
Greg Clayton1be10fc2010-09-29 01:12:09 +00001324
Greg Clayton450e3f32010-10-12 02:24:53 +00001325 DWARFDebugInfo* debug_info = DebugInfo();
1326
Greg Clayton96d7d742010-11-10 23:42:09 +00001327 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001328 Type *type = m_die_to_type.lookup (die);
1329
1330 const dw_tag_t tag = die->Tag();
1331
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001332 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1333 die->GetOffset(),
1334 DW_TAG_value_to_name(tag),
1335 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001336 assert (clang_type);
1337 DWARFDebugInfoEntry::Attributes attributes;
1338
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001339 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001340
1341 switch (tag)
1342 {
1343 case DW_TAG_structure_type:
1344 case DW_TAG_union_type:
1345 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001346 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001347 if (die->HasChildren())
1348 {
1349 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001350 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1351 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001352 class_language = eLanguageTypeObjC;
1353
1354 int tag_decl_kind = -1;
1355 AccessType default_accessibility = eAccessNone;
1356 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001357 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001358 tag_decl_kind = clang::TTK_Struct;
1359 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001360 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001361 else if (tag == DW_TAG_union_type)
1362 {
1363 tag_decl_kind = clang::TTK_Union;
1364 default_accessibility = eAccessPublic;
1365 }
1366 else if (tag == DW_TAG_class_type)
1367 {
1368 tag_decl_kind = clang::TTK_Class;
1369 default_accessibility = eAccessPrivate;
1370 }
1371
Greg Clayton96d7d742010-11-10 23:42:09 +00001372 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001373 std::vector<clang::CXXBaseSpecifier *> base_classes;
1374 std::vector<int> member_accessibilities;
1375 bool is_a_class = false;
1376 // Parse members and base classes first
1377 DWARFDIECollection member_function_dies;
1378
1379 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001380 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001381 die,
1382 clang_type,
1383 class_language,
1384 base_classes,
1385 member_accessibilities,
1386 member_function_dies,
1387 default_accessibility,
1388 is_a_class);
1389
1390 // Now parse any methods if there were any...
1391 size_t num_functions = member_function_dies.Size();
1392 if (num_functions > 0)
1393 {
1394 for (size_t i=0; i<num_functions; ++i)
1395 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001396 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001397 }
1398 }
1399
Greg Clayton450e3f32010-10-12 02:24:53 +00001400 if (class_language == eLanguageTypeObjC)
1401 {
1402 std::string class_str (ClangASTContext::GetTypeName (clang_type));
1403 if (!class_str.empty())
1404 {
1405
1406 ConstString class_name (class_str.c_str());
1407 std::vector<NameToDIE::Info> method_die_infos;
1408 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1409 {
1410 DWARFCompileUnit* method_cu = NULL;
1411 DWARFCompileUnit* prev_method_cu = NULL;
1412 const size_t num_objc_methods = method_die_infos.size();
1413 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1414 {
1415 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1416
1417 if (method_cu != prev_method_cu)
1418 method_cu->ExtractDIEsIfNeeded (false);
1419
1420 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1421
1422 ResolveType (method_cu, method_die);
1423 }
1424 }
1425 }
1426 }
1427
Greg Claytonc93237c2010-10-01 20:48:32 +00001428 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1429 // need to tell the clang type it is actually a class.
1430 if (class_language != eLanguageTypeObjC)
1431 {
1432 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001433 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001434 }
1435
1436 // Since DW_TAG_structure_type gets used for both classes
1437 // and structures, we may need to set any DW_TAG_member
1438 // fields to have a "private" access if none was specified.
1439 // When we parsed the child members we tracked that actual
1440 // accessibility value for each DW_TAG_member in the
1441 // "member_accessibilities" array. If the value for the
1442 // member is zero, then it was set to the "default_accessibility"
1443 // which for structs was "public". Below we correct this
1444 // by setting any fields to "private" that weren't correctly
1445 // set.
1446 if (is_a_class && !member_accessibilities.empty())
1447 {
1448 // This is a class and all members that didn't have
1449 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001450 ast.SetDefaultAccessForRecordFields (clang_type,
1451 eAccessPrivate,
1452 &member_accessibilities.front(),
1453 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001454 }
1455
1456 if (!base_classes.empty())
1457 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001458 ast.SetBaseClassesForClassType (clang_type,
1459 &base_classes.front(),
1460 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001461
1462 // Clang will copy each CXXBaseSpecifier in "base_classes"
1463 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001464 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1465 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001466 }
1467
1468 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001469 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001470 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001471
1472 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001473 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001474 if (die->HasChildren())
1475 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001476 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1477 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001478 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001479 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001480 return clang_type;
1481
1482 default:
1483 assert(false && "not a forward clang type decl!");
1484 break;
1485 }
1486 return NULL;
1487}
1488
Greg Claytonc685f8e2010-09-15 04:15:46 +00001489Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001490SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001491{
1492 if (type_die != NULL)
1493 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001494 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001495 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001496 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001497 if (assert_not_being_parsed)
1498 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001499 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001500 }
1501 return NULL;
1502}
1503
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001504CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001505SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001506{
1507 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001508 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001509 {
1510 // The symbol vendor doesn't know about this compile unit, we
1511 // need to parse and add it to the symbol vendor object.
1512 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001513 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001514 if (dc_cu.get())
1515 {
1516 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001517 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001518 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001519
1520 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001521
1522 if (m_debug_map_symfile)
1523 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001524 }
1525 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001526 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001527}
1528
1529bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001530SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001531{
1532 sc.Clear();
1533 // Check if the symbol vendor already knows about this compile unit?
1534 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton96d7d742010-11-10 23:42:09 +00001535 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001536
1537 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1538 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001539 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001540
1541 return sc.function != NULL;
1542}
1543
1544uint32_t
1545SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1546{
1547 Timer scoped_timer(__PRETTY_FUNCTION__,
1548 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1549 so_addr.GetSection(),
1550 so_addr.GetOffset(),
1551 resolve_scope);
1552 uint32_t resolved = 0;
1553 if (resolve_scope & ( eSymbolContextCompUnit |
1554 eSymbolContextFunction |
1555 eSymbolContextBlock |
1556 eSymbolContextLineEntry))
1557 {
1558 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1559
1560 DWARFDebugAranges* debug_aranges = DebugAranges();
1561 DWARFDebugInfo* debug_info = DebugInfo();
1562 if (debug_aranges)
1563 {
1564 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1565 if (cu_offset != DW_INVALID_OFFSET)
1566 {
1567 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001568 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1569 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001570 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001571 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001572 assert(sc.comp_unit != NULL);
1573 resolved |= eSymbolContextCompUnit;
1574
1575 if (resolve_scope & eSymbolContextLineEntry)
1576 {
1577 LineTable *line_table = sc.comp_unit->GetLineTable();
1578 if (line_table == NULL)
1579 {
1580 if (ParseCompileUnitLineTable(sc))
1581 line_table = sc.comp_unit->GetLineTable();
1582 }
1583 if (line_table != NULL)
1584 {
1585 if (so_addr.IsLinkedAddress())
1586 {
1587 Address linked_addr (so_addr);
1588 linked_addr.ResolveLinkedAddress();
1589 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1590 {
1591 resolved |= eSymbolContextLineEntry;
1592 }
1593 }
1594 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1595 {
1596 resolved |= eSymbolContextLineEntry;
1597 }
1598 }
1599 }
1600
1601 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1602 {
1603 DWARFDebugInfoEntry *function_die = NULL;
1604 DWARFDebugInfoEntry *block_die = NULL;
1605 if (resolve_scope & eSymbolContextBlock)
1606 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001607 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001608 }
1609 else
1610 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001611 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001612 }
1613
1614 if (function_die != NULL)
1615 {
1616 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1617 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001618 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001619 }
1620
1621 if (sc.function != NULL)
1622 {
1623 resolved |= eSymbolContextFunction;
1624
1625 if (resolve_scope & eSymbolContextBlock)
1626 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001627 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001628
1629 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001630 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001631 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001632 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001633 if (sc.block)
1634 resolved |= eSymbolContextBlock;
1635 }
1636 }
1637 }
1638 }
1639 }
1640 }
1641 }
1642 return resolved;
1643}
1644
1645
1646
1647uint32_t
1648SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1649{
1650 const uint32_t prev_size = sc_list.GetSize();
1651 if (resolve_scope & eSymbolContextCompUnit)
1652 {
1653 DWARFDebugInfo* debug_info = DebugInfo();
1654 if (debug_info)
1655 {
1656 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001657 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001658
Greg Clayton96d7d742010-11-10 23:42:09 +00001659 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001660 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001661 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001662 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1663 if (check_inlines || file_spec_matches_cu_file_spec)
1664 {
1665 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001666 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001667 assert(sc.comp_unit != NULL);
1668
1669 uint32_t file_idx = UINT32_MAX;
1670
1671 // If we are looking for inline functions only and we don't
1672 // find it in the support files, we are done.
1673 if (check_inlines)
1674 {
1675 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1676 if (file_idx == UINT32_MAX)
1677 continue;
1678 }
1679
1680 if (line != 0)
1681 {
1682 LineTable *line_table = sc.comp_unit->GetLineTable();
1683
1684 if (line_table != NULL && line != 0)
1685 {
1686 // We will have already looked up the file index if
1687 // we are searching for inline entries.
1688 if (!check_inlines)
1689 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1690
1691 if (file_idx != UINT32_MAX)
1692 {
1693 uint32_t found_line;
1694 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1695 found_line = sc.line_entry.line;
1696
Greg Clayton016a95e2010-09-14 02:20:48 +00001697 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001698 {
1699 sc.function = NULL;
1700 sc.block = NULL;
1701 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1702 {
1703 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1704 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1705 {
1706 DWARFDebugInfoEntry *function_die = NULL;
1707 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001708 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001709
1710 if (function_die != NULL)
1711 {
1712 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1713 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001714 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001715 }
1716
1717 if (sc.function != NULL)
1718 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001719 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001720
1721 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001722 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001723 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001724 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001725 }
1726 }
1727 }
1728
1729 sc_list.Append(sc);
1730 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1731 }
1732 }
1733 }
1734 else if (file_spec_matches_cu_file_spec && !check_inlines)
1735 {
1736 // only append the context if we aren't looking for inline call sites
1737 // by file and line and if the file spec matches that of the compile unit
1738 sc_list.Append(sc);
1739 }
1740 }
1741 else if (file_spec_matches_cu_file_spec && !check_inlines)
1742 {
1743 // only append the context if we aren't looking for inline call sites
1744 // by file and line and if the file spec matches that of the compile unit
1745 sc_list.Append(sc);
1746 }
1747
1748 if (!check_inlines)
1749 break;
1750 }
1751 }
1752 }
1753 }
1754 return sc_list.GetSize() - prev_size;
1755}
1756
1757void
1758SymbolFileDWARF::Index ()
1759{
1760 if (m_indexed)
1761 return;
1762 m_indexed = true;
1763 Timer scoped_timer (__PRETTY_FUNCTION__,
1764 "SymbolFileDWARF::Index (%s)",
1765 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1766
1767 DWARFDebugInfo* debug_info = DebugInfo();
1768 if (debug_info)
1769 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001770 m_aranges.reset(new DWARFDebugAranges());
1771
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001772 uint32_t cu_idx = 0;
1773 const uint32_t num_compile_units = GetNumCompileUnits();
1774 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1775 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001776 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001777
Greg Clayton96d7d742010-11-10 23:42:09 +00001778 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001779
Greg Clayton96d7d742010-11-10 23:42:09 +00001780 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00001781 m_function_basename_index,
1782 m_function_fullname_index,
1783 m_function_method_index,
1784 m_function_selector_index,
1785 m_objc_class_selectors_index,
1786 m_global_index,
1787 m_type_index,
1788 m_namespace_index,
1789 DebugRanges(),
1790 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001791
1792 // Keep memory down by clearing DIEs if this generate function
1793 // caused them to be parsed
1794 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001795 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001796 }
1797
Greg Clayton016a95e2010-09-14 02:20:48 +00001798 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001799
Greg Clayton24739922010-10-13 03:15:28 +00001800#if defined (ENABLE_DEBUG_PRINTF)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001801 StreamFile s(stdout);
Greg Clayton24739922010-10-13 03:15:28 +00001802 s.Printf ("DWARF index for (%s) '%s/%s':",
1803 GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1804 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1805 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001806 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1807 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1808 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1809 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1810 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1811 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001812 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001813 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001814#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001815 }
1816}
1817
1818uint32_t
1819SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1820{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001821 DWARFDebugInfo* info = DebugInfo();
1822 if (info == NULL)
1823 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001824
1825 // If we aren't appending the results to this list, then clear the list
1826 if (!append)
1827 variables.Clear();
1828
1829 // Remember how many variables are in the list before we search in case
1830 // we are appending the results to a variable list.
1831 const uint32_t original_size = variables.GetSize();
1832
1833 // Index the DWARF if we haven't already
1834 if (!m_indexed)
1835 Index ();
1836
Greg Claytonc685f8e2010-09-15 04:15:46 +00001837 SymbolContext sc;
1838 sc.module_sp = m_obj_file->GetModule()->GetSP();
1839 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001840
Greg Clayton96d7d742010-11-10 23:42:09 +00001841 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001842 DWARFCompileUnit* prev_cu = NULL;
1843 const DWARFDebugInfoEntry* die = NULL;
1844 std::vector<NameToDIE::Info> die_info_array;
1845 const size_t num_matches = m_global_index.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001846 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001847 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001848 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001849
Greg Clayton96d7d742010-11-10 23:42:09 +00001850 if (curr_cu != prev_cu)
1851 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001852
Greg Clayton96d7d742010-11-10 23:42:09 +00001853 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001854
Greg Clayton96d7d742010-11-10 23:42:09 +00001855 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001856 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001857
Greg Clayton96d7d742010-11-10 23:42:09 +00001858 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001859
1860 if (variables.GetSize() - original_size >= max_matches)
1861 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001862 }
1863
1864 // Return the number of variable that were appended to the list
1865 return variables.GetSize() - original_size;
1866}
1867
1868uint32_t
1869SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1870{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001871 DWARFDebugInfo* info = DebugInfo();
1872 if (info == NULL)
1873 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001874
1875 // If we aren't appending the results to this list, then clear the list
1876 if (!append)
1877 variables.Clear();
1878
1879 // Remember how many variables are in the list before we search in case
1880 // we are appending the results to a variable list.
1881 const uint32_t original_size = variables.GetSize();
1882
1883 // Index the DWARF if we haven't already
1884 if (!m_indexed)
1885 Index ();
1886
Greg Claytonc685f8e2010-09-15 04:15:46 +00001887 SymbolContext sc;
1888 sc.module_sp = m_obj_file->GetModule()->GetSP();
1889 assert (sc.module_sp);
1890
Greg Clayton96d7d742010-11-10 23:42:09 +00001891 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001892 DWARFCompileUnit* prev_cu = NULL;
1893 const DWARFDebugInfoEntry* die = NULL;
1894 std::vector<NameToDIE::Info> die_info_array;
1895 const size_t num_matches = m_global_index.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001896 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001897 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001898 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001899
Greg Clayton96d7d742010-11-10 23:42:09 +00001900 if (curr_cu != prev_cu)
1901 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001902
Greg Clayton96d7d742010-11-10 23:42:09 +00001903 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001904
Greg Clayton96d7d742010-11-10 23:42:09 +00001905 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001906 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001907
Greg Clayton96d7d742010-11-10 23:42:09 +00001908 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001909
Greg Claytonc685f8e2010-09-15 04:15:46 +00001910 if (variables.GetSize() - original_size >= max_matches)
1911 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001912 }
1913
1914 // Return the number of variable that were appended to the list
1915 return variables.GetSize() - original_size;
1916}
1917
1918
Greg Clayton0c5cd902010-06-28 21:30:43 +00001919void
1920SymbolFileDWARF::FindFunctions
1921(
1922 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001923 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00001924 SymbolContextList& sc_list
1925)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001926{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001927 DWARFDebugInfo* info = DebugInfo();
1928 if (info == NULL)
1929 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001930
Greg Claytonc685f8e2010-09-15 04:15:46 +00001931 SymbolContext sc;
1932 sc.module_sp = m_obj_file->GetModule()->GetSP();
1933 assert (sc.module_sp);
1934
Greg Clayton96d7d742010-11-10 23:42:09 +00001935 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001936 DWARFCompileUnit* prev_cu = NULL;
1937 const DWARFDebugInfoEntry* die = NULL;
1938 std::vector<NameToDIE::Info> die_info_array;
Greg Claytond7e05462010-11-14 00:22:48 +00001939 const size_t num_matches = name_to_die.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001940 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001941 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001942 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001943
Greg Clayton96d7d742010-11-10 23:42:09 +00001944 if (curr_cu != prev_cu)
1945 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001946
Greg Clayton96d7d742010-11-10 23:42:09 +00001947 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytond7e05462010-11-14 00:22:48 +00001948
1949 const DWARFDebugInfoEntry* inlined_die = NULL;
1950 if (die->Tag() == DW_TAG_inlined_subroutine)
1951 {
1952 inlined_die = die;
1953
1954 while ((die = die->GetParent()) != NULL)
1955 {
1956 if (die->Tag() == DW_TAG_subprogram)
1957 break;
1958 }
1959 }
1960 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00001961 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00001962 {
Greg Claytond7e05462010-11-14 00:22:48 +00001963 Address addr;
1964 // Parse all blocks if needed
1965 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001966 {
Greg Claytond7e05462010-11-14 00:22:48 +00001967 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
1968 assert (sc.block != NULL);
1969 if (sc.block->GetStartAddress (addr) == false)
1970 addr.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001971 }
Greg Claytond7e05462010-11-14 00:22:48 +00001972 else
1973 {
1974 sc.block = NULL;
1975 addr = sc.function->GetAddressRange().GetBaseAddress();
1976 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001977
Greg Claytond7e05462010-11-14 00:22:48 +00001978 if (addr.IsValid())
1979 {
1980
1981 // We found the function, so we should find the line table
1982 // and line table entry as well
1983 LineTable *line_table = sc.comp_unit->GetLineTable();
1984 if (line_table == NULL)
1985 {
1986 if (ParseCompileUnitLineTable(sc))
1987 line_table = sc.comp_unit->GetLineTable();
1988 }
1989 if (line_table != NULL)
1990 line_table->FindLineEntryByAddress (addr, sc.line_entry);
1991
1992 sc_list.Append(sc);
1993 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001994 }
1995 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001996}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001997
Greg Claytonc685f8e2010-09-15 04:15:46 +00001998
1999void
2000SymbolFileDWARF::FindFunctions
2001(
2002 const RegularExpression &regex,
2003 const NameToDIE &name_to_die,
2004 SymbolContextList& sc_list
2005)
2006{
2007 DWARFDebugInfo* info = DebugInfo();
2008 if (info == NULL)
2009 return;
2010
2011 SymbolContext sc;
2012 sc.module_sp = m_obj_file->GetModule()->GetSP();
2013 assert (sc.module_sp);
2014
Greg Clayton96d7d742010-11-10 23:42:09 +00002015 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002016 DWARFCompileUnit* prev_cu = NULL;
2017 const DWARFDebugInfoEntry* die = NULL;
2018 std::vector<NameToDIE::Info> die_info_array;
2019 const size_t num_matches = name_to_die.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002020 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002021 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002022 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002023
Greg Clayton96d7d742010-11-10 23:42:09 +00002024 if (curr_cu != prev_cu)
2025 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002026
Greg Clayton96d7d742010-11-10 23:42:09 +00002027 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonab843392010-12-03 17:49:14 +00002028
2029 const DWARFDebugInfoEntry* inlined_die = NULL;
2030 if (die->Tag() == DW_TAG_inlined_subroutine)
2031 {
2032 inlined_die = die;
2033
2034 while ((die = die->GetParent()) != NULL)
2035 {
2036 if (die->Tag() == DW_TAG_subprogram)
2037 break;
2038 }
2039 }
2040 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002041 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002042 {
Greg Claytonab843392010-12-03 17:49:14 +00002043 Address addr;
2044 // Parse all blocks if needed
2045 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002046 {
Greg Claytonab843392010-12-03 17:49:14 +00002047 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2048 assert (sc.block != NULL);
2049 if (sc.block->GetStartAddress (addr) == false)
2050 addr.Clear();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002051 }
Greg Claytonab843392010-12-03 17:49:14 +00002052 else
2053 {
2054 sc.block = NULL;
2055 addr = sc.function->GetAddressRange().GetBaseAddress();
2056 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002057
Greg Claytonab843392010-12-03 17:49:14 +00002058 if (addr.IsValid())
2059 {
2060
2061 // We found the function, so we should find the line table
2062 // and line table entry as well
2063 LineTable *line_table = sc.comp_unit->GetLineTable();
2064 if (line_table == NULL)
2065 {
2066 if (ParseCompileUnitLineTable(sc))
2067 line_table = sc.comp_unit->GetLineTable();
2068 }
2069 if (line_table != NULL)
2070 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2071
2072 sc_list.Append(sc);
2073 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002074 }
2075 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00002076}
2077
2078uint32_t
2079SymbolFileDWARF::FindFunctions
2080(
2081 const ConstString &name,
2082 uint32_t name_type_mask,
2083 bool append,
2084 SymbolContextList& sc_list
2085)
2086{
2087 Timer scoped_timer (__PRETTY_FUNCTION__,
2088 "SymbolFileDWARF::FindFunctions (name = '%s')",
2089 name.AsCString());
2090
Greg Clayton0c5cd902010-06-28 21:30:43 +00002091 // If we aren't appending the results to this list, then clear the list
2092 if (!append)
2093 sc_list.Clear();
2094
2095 // Remember how many sc_list are in the list before we search in case
2096 // we are appending the results to a variable list.
2097 uint32_t original_size = sc_list.GetSize();
2098
2099 // Index the DWARF if we haven't already
2100 if (!m_indexed)
2101 Index ();
2102
2103 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002104 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002105
2106 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002107 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002108
2109 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002110 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002111
2112 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002113 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002114
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002115 // Return the number of variable that were appended to the list
2116 return sc_list.GetSize() - original_size;
2117}
2118
2119
2120uint32_t
2121SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2122{
2123 Timer scoped_timer (__PRETTY_FUNCTION__,
2124 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2125 regex.GetText());
2126
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002127 // If we aren't appending the results to this list, then clear the list
2128 if (!append)
2129 sc_list.Clear();
2130
2131 // Remember how many sc_list are in the list before we search in case
2132 // we are appending the results to a variable list.
2133 uint32_t original_size = sc_list.GetSize();
2134
2135 // Index the DWARF if we haven't already
2136 if (!m_indexed)
2137 Index ();
2138
Greg Claytonc685f8e2010-09-15 04:15:46 +00002139 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002140
Greg Claytonc685f8e2010-09-15 04:15:46 +00002141 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002142
2143 // Return the number of variable that were appended to the list
2144 return sc_list.GetSize() - original_size;
2145}
2146
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002147uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002148SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002149{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002150 DWARFDebugInfo* info = DebugInfo();
2151 if (info == NULL)
2152 return 0;
2153
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002154 // If we aren't appending the results to this list, then clear the list
2155 if (!append)
2156 types.Clear();
2157
Greg Clayton6dbd3982010-09-15 05:51:24 +00002158 // Index if we already haven't to make sure the compile units
2159 // get indexed and make their global DIE index list
2160 if (!m_indexed)
2161 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002162
Greg Claytonc685f8e2010-09-15 04:15:46 +00002163 const uint32_t initial_types_size = types.GetSize();
Greg Clayton96d7d742010-11-10 23:42:09 +00002164 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002165 DWARFCompileUnit* prev_cu = NULL;
2166 const DWARFDebugInfoEntry* die = NULL;
2167 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002168 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002169 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002170 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002171 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002172
Greg Clayton96d7d742010-11-10 23:42:09 +00002173 if (curr_cu != prev_cu)
2174 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002175
Greg Clayton96d7d742010-11-10 23:42:09 +00002176 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002177
Greg Clayton96d7d742010-11-10 23:42:09 +00002178 Type *matching_type = ResolveType (curr_cu, die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002179 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002180 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002181 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002182 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonc685f8e2010-09-15 04:15:46 +00002183 assert (type_sp.get() != NULL);
2184 types.InsertUnique (type_sp);
2185 if (types.GetSize() >= max_matches)
2186 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002187 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002188 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002189 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002190}
2191
2192
Greg Clayton526e5af2010-11-13 03:52:47 +00002193ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002194SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2195 const ConstString &name)
2196{
Greg Clayton526e5af2010-11-13 03:52:47 +00002197 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002198 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002199 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002200 {
Greg Clayton526e5af2010-11-13 03:52:47 +00002201 // Index if we already haven't to make sure the compile units
2202 // get indexed and make their global DIE index list
2203 if (!m_indexed)
2204 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002205
Greg Clayton526e5af2010-11-13 03:52:47 +00002206 DWARFCompileUnit* curr_cu = NULL;
2207 DWARFCompileUnit* prev_cu = NULL;
2208 const DWARFDebugInfoEntry* die = NULL;
2209 std::vector<NameToDIE::Info> die_info_array;
2210 const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2211 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2212 {
2213 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2214
2215 if (curr_cu != prev_cu)
2216 curr_cu->ExtractDIEsIfNeeded (false);
Greg Clayton96d7d742010-11-10 23:42:09 +00002217
Greg Clayton526e5af2010-11-13 03:52:47 +00002218 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2219
2220 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2221 if (clang_namespace_decl)
2222 {
2223 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2224 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2225 }
2226 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002227 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002228 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002229}
2230
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002231uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002232SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002233{
2234 // Remember how many sc_list are in the list before we search in case
2235 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002236 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002237
2238 const uint32_t num_die_offsets = die_offsets.size();
2239 // Parse all of the types we found from the pubtypes matches
2240 uint32_t i;
2241 uint32_t num_matches = 0;
2242 for (i = 0; i < num_die_offsets; ++i)
2243 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002244 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2245 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002246 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002247 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002248 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002249 assert (type_sp.get() != NULL);
2250 types.InsertUnique (type_sp);
2251 ++num_matches;
2252 if (num_matches >= max_matches)
2253 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002254 }
2255 }
2256
2257 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002258 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002259}
2260
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002261
2262size_t
2263SymbolFileDWARF::ParseChildParameters
2264(
2265 const SymbolContext& sc,
2266 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002267 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002268 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002269 bool skip_artificial,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002270 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002271 std::vector<clang_type_t>& function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00002272 std::vector<clang::ParmVarDecl*>& function_param_decls,
2273 unsigned &type_quals
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002274)
2275{
2276 if (parent_die == NULL)
2277 return 0;
2278
Greg Claytond88d7592010-09-15 08:33:30 +00002279 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2280
Greg Clayton7fedea22010-11-16 02:10:54 +00002281 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002282 const DWARFDebugInfoEntry *die;
2283 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2284 {
2285 dw_tag_t tag = die->Tag();
2286 switch (tag)
2287 {
2288 case DW_TAG_formal_parameter:
2289 {
2290 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002291 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002292 if (num_attributes > 0)
2293 {
2294 const char *name = NULL;
2295 Declaration decl;
2296 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002297 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002298 // one of None, Auto, Register, Extern, Static, PrivateExtern
2299
Sean Callanane2ef6e32010-09-23 03:01:22 +00002300 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002301 uint32_t i;
2302 for (i=0; i<num_attributes; ++i)
2303 {
2304 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2305 DWARFFormValue form_value;
2306 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2307 {
2308 switch (attr)
2309 {
2310 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2311 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2312 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2313 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2314 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002315 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002316 case DW_AT_location:
2317 // if (form_value.BlockData())
2318 // {
2319 // const DataExtractor& debug_info_data = debug_info();
2320 // uint32_t block_length = form_value.Unsigned();
2321 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2322 // }
2323 // else
2324 // {
2325 // }
2326 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002327 case DW_AT_const_value:
2328 case DW_AT_default_value:
2329 case DW_AT_description:
2330 case DW_AT_endianity:
2331 case DW_AT_is_optional:
2332 case DW_AT_segment:
2333 case DW_AT_variable_parameter:
2334 default:
2335 case DW_AT_abstract_origin:
2336 case DW_AT_sibling:
2337 break;
2338 }
2339 }
2340 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002341
Greg Clayton0fffff52010-09-24 05:15:53 +00002342 bool skip = false;
2343 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002344 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002345 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00002346 {
2347 // In order to determine if a C++ member function is
2348 // "const" we have to look at the const-ness of "this"...
2349 // Ugly, but that
2350 if (arg_idx == 0)
2351 {
2352 const DWARFDebugInfoEntry *grandparent_die = parent_die->GetParent();
2353 if (grandparent_die && (grandparent_die->Tag() == DW_TAG_structure_type ||
2354 grandparent_die->Tag() == DW_TAG_class_type))
2355 {
2356 LanguageType language = sc.comp_unit->GetLanguage();
2357 if (language == eLanguageTypeObjC_plus_plus || language == eLanguageTypeC_plus_plus)
2358 {
2359 // Often times compilers omit the "this" name for the
2360 // specification DIEs, so we can't rely upon the name
2361 // being in the formal parameter DIE...
2362 if (name == NULL || ::strcmp(name, "this")==0)
2363 {
2364 Type *this_type = ResolveTypeUID (param_type_die_offset);
2365 if (this_type)
2366 {
2367 uint32_t encoding_mask = this_type->GetEncodingMask();
2368 if (encoding_mask & Type::eEncodingIsPointerUID)
2369 {
2370 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
Greg Clayton47fbf1a2010-11-16 22:09:25 +00002371 type_quals |= clang::Qualifiers::Const;
Greg Clayton7fedea22010-11-16 02:10:54 +00002372 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
Greg Clayton47fbf1a2010-11-16 22:09:25 +00002373 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00002374 }
2375 }
2376 }
2377 }
2378 }
2379 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002380 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00002381 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002382 else
2383 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002384
Greg Clayton0fffff52010-09-24 05:15:53 +00002385 // HACK: Objective C formal parameters "self" and "_cmd"
2386 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002387 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2388 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002389 {
2390 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2391 skip = true;
2392 }
2393 }
2394 }
2395
2396 if (!skip)
2397 {
2398 Type *type = ResolveTypeUID(param_type_die_offset);
2399 if (type)
2400 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002401 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002402
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002403 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002404 assert(param_var_decl);
2405 function_param_decls.push_back(param_var_decl);
2406 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002407 }
2408 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002409 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002410 }
2411 break;
2412
2413 default:
2414 break;
2415 }
2416 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002417 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002418}
2419
2420size_t
2421SymbolFileDWARF::ParseChildEnumerators
2422(
2423 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002424 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002425 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002426 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002427 const DWARFDebugInfoEntry *parent_die
2428)
2429{
2430 if (parent_die == NULL)
2431 return 0;
2432
2433 size_t enumerators_added = 0;
2434 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002435 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2436
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002437 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2438 {
2439 const dw_tag_t tag = die->Tag();
2440 if (tag == DW_TAG_enumerator)
2441 {
2442 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002443 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002444 if (num_child_attributes > 0)
2445 {
2446 const char *name = NULL;
2447 bool got_value = false;
2448 int64_t enum_value = 0;
2449 Declaration decl;
2450
2451 uint32_t i;
2452 for (i=0; i<num_child_attributes; ++i)
2453 {
2454 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2455 DWARFFormValue form_value;
2456 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2457 {
2458 switch (attr)
2459 {
2460 case DW_AT_const_value:
2461 got_value = true;
2462 enum_value = form_value.Unsigned();
2463 break;
2464
2465 case DW_AT_name:
2466 name = form_value.AsCString(&get_debug_str_data());
2467 break;
2468
2469 case DW_AT_description:
2470 default:
2471 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2472 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2473 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2474 case DW_AT_sibling:
2475 break;
2476 }
2477 }
2478 }
2479
2480 if (name && name[0] && got_value)
2481 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002482 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2483 enumerator_clang_type,
2484 decl,
2485 name,
2486 enum_value,
2487 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002488 ++enumerators_added;
2489 }
2490 }
2491 }
2492 }
2493 return enumerators_added;
2494}
2495
2496void
2497SymbolFileDWARF::ParseChildArrayInfo
2498(
2499 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002500 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002501 const DWARFDebugInfoEntry *parent_die,
2502 int64_t& first_index,
2503 std::vector<uint64_t>& element_orders,
2504 uint32_t& byte_stride,
2505 uint32_t& bit_stride
2506)
2507{
2508 if (parent_die == NULL)
2509 return;
2510
2511 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002512 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002513 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2514 {
2515 const dw_tag_t tag = die->Tag();
2516 switch (tag)
2517 {
2518 case DW_TAG_enumerator:
2519 {
2520 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002521 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002522 if (num_child_attributes > 0)
2523 {
2524 const char *name = NULL;
2525 bool got_value = false;
2526 int64_t enum_value = 0;
2527
2528 uint32_t i;
2529 for (i=0; i<num_child_attributes; ++i)
2530 {
2531 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2532 DWARFFormValue form_value;
2533 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2534 {
2535 switch (attr)
2536 {
2537 case DW_AT_const_value:
2538 got_value = true;
2539 enum_value = form_value.Unsigned();
2540 break;
2541
2542 case DW_AT_name:
2543 name = form_value.AsCString(&get_debug_str_data());
2544 break;
2545
2546 case DW_AT_description:
2547 default:
2548 case DW_AT_decl_file:
2549 case DW_AT_decl_line:
2550 case DW_AT_decl_column:
2551 case DW_AT_sibling:
2552 break;
2553 }
2554 }
2555 }
2556 }
2557 }
2558 break;
2559
2560 case DW_TAG_subrange_type:
2561 {
2562 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002563 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002564 if (num_child_attributes > 0)
2565 {
2566 const char *name = NULL;
2567 bool got_value = false;
2568 uint64_t byte_size = 0;
2569 int64_t enum_value = 0;
2570 uint64_t num_elements = 0;
2571 uint64_t lower_bound = 0;
2572 uint64_t upper_bound = 0;
2573 uint32_t i;
2574 for (i=0; i<num_child_attributes; ++i)
2575 {
2576 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2577 DWARFFormValue form_value;
2578 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2579 {
2580 switch (attr)
2581 {
2582 case DW_AT_const_value:
2583 got_value = true;
2584 enum_value = form_value.Unsigned();
2585 break;
2586
2587 case DW_AT_name:
2588 name = form_value.AsCString(&get_debug_str_data());
2589 break;
2590
2591 case DW_AT_count:
2592 num_elements = form_value.Unsigned();
2593 break;
2594
2595 case DW_AT_bit_stride:
2596 bit_stride = form_value.Unsigned();
2597 break;
2598
2599 case DW_AT_byte_stride:
2600 byte_stride = form_value.Unsigned();
2601 break;
2602
2603 case DW_AT_byte_size:
2604 byte_size = form_value.Unsigned();
2605 break;
2606
2607 case DW_AT_lower_bound:
2608 lower_bound = form_value.Unsigned();
2609 break;
2610
2611 case DW_AT_upper_bound:
2612 upper_bound = form_value.Unsigned();
2613 break;
2614
2615 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002616 case DW_AT_abstract_origin:
2617 case DW_AT_accessibility:
2618 case DW_AT_allocated:
2619 case DW_AT_associated:
2620 case DW_AT_data_location:
2621 case DW_AT_declaration:
2622 case DW_AT_description:
2623 case DW_AT_sibling:
2624 case DW_AT_threads_scaled:
2625 case DW_AT_type:
2626 case DW_AT_visibility:
2627 break;
2628 }
2629 }
2630 }
2631
2632 if (upper_bound > lower_bound)
2633 num_elements = upper_bound - lower_bound + 1;
2634
2635 if (num_elements > 0)
2636 element_orders.push_back (num_elements);
2637 }
2638 }
2639 break;
2640 }
2641 }
2642}
2643
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002644TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002645SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002646{
2647 TypeSP type_sp;
2648 if (die != NULL)
2649 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002650 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002651 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002652 if (type_ptr == NULL)
2653 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002654 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
2655 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002656 }
2657 else if (type_ptr != DIE_IS_BEING_PARSED)
2658 {
2659 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002660 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002661 }
2662
2663 }
2664 return type_sp;
2665}
2666
2667clang::DeclContext *
2668SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2669{
2670 if (die_offset != DW_INVALID_OFFSET)
2671 {
2672 DWARFCompileUnitSP cu_sp;
2673 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2674 return GetClangDeclContextForDIE (cu_sp.get(), die);
2675 }
2676 return NULL;
2677}
2678
2679
Greg Clayton96d7d742010-11-10 23:42:09 +00002680clang::NamespaceDecl *
2681SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2682{
2683 if (die->Tag() == DW_TAG_namespace)
2684 {
2685 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2686 if (namespace_name)
2687 {
2688 Declaration decl; // TODO: fill in the decl object
2689 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2690 if (namespace_decl)
2691 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2692 return namespace_decl;
2693 }
2694 }
2695 return NULL;
2696}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002697
2698clang::DeclContext *
Greg Clayton96d7d742010-11-10 23:42:09 +00002699SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002700{
2701 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2702 if (pos != m_die_to_decl_ctx.end())
2703 return pos->second;
2704
2705 while (die != NULL)
2706 {
2707 switch (die->Tag())
2708 {
2709 case DW_TAG_namespace:
2710 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002711 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002712 if (namespace_name)
2713 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002714 Declaration decl; // TODO: fill in the decl object
Greg Clayton96d7d742010-11-10 23:42:09 +00002715 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002716 if (namespace_decl)
2717 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2718 return namespace_decl;
2719 }
2720 }
2721 break;
2722
2723 default:
2724 break;
2725 }
2726 clang::DeclContext *decl_ctx;
Greg Clayton96d7d742010-11-10 23:42:09 +00002727 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002728 if (decl_ctx)
2729 return decl_ctx;
2730
Greg Clayton96d7d742010-11-10 23:42:09 +00002731 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002732 if (decl_ctx)
2733 return decl_ctx;
2734
2735 die = die->GetParent();
2736 }
Greg Clayton7a345282010-11-09 23:46:37 +00002737 // Right now we have only one translation unit per module...
2738 if (m_clang_tu_decl == NULL)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002739 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Greg Clayton7a345282010-11-09 23:46:37 +00002740 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002741}
2742
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002743// This function can be used when a DIE is found that is a forward declaration
2744// DIE and we want to try and find a type that has the complete definition.
2745TypeSP
2746SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Clayton96d7d742010-11-10 23:42:09 +00002747 DWARFCompileUnit* curr_cu,
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002748 const DWARFDebugInfoEntry *die,
2749 const ConstString &type_name
2750)
2751{
2752 TypeSP type_sp;
2753
Greg Clayton96d7d742010-11-10 23:42:09 +00002754 if (curr_cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002755 return type_sp;
2756
Greg Clayton69974892010-12-03 21:42:06 +00002757 if (!m_indexed)
2758 Index ();
2759
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002760 const dw_tag_t type_tag = die->Tag();
2761 std::vector<NameToDIE::Info> die_info_array;
2762 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2763 if (num_matches > 0)
2764 {
2765 DWARFCompileUnit* type_cu = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00002766 DWARFCompileUnit* curr_cu = curr_cu;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002767 DWARFDebugInfo *info = DebugInfo();
2768 for (size_t i=0; i<num_matches; ++i)
2769 {
2770 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2771
2772 if (type_cu != curr_cu)
2773 {
2774 type_cu->ExtractDIEsIfNeeded (false);
2775 curr_cu = type_cu;
2776 }
2777
2778 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2779
2780 if (type_die != die && type_die->Tag() == type_tag)
2781 {
2782 // Hold off on comparing parent DIE tags until
2783 // we know what happens with stuff in namespaces
2784 // for gcc and clang...
2785 //DWARFDebugInfoEntry *parent_die = die->GetParent();
2786 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2787 //if (parent_die->Tag() == parent_type_die->Tag())
2788 {
2789 Type *resolved_type = ResolveType (type_cu, type_die, false);
2790 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2791 {
2792 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2793 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00002794 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002795 m_obj_file->GetFileSpec().GetFilename().AsCString(),
2796 type_die->GetOffset(),
2797 type_cu->GetOffset());
2798
2799 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002800 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00002801 if (!type_sp)
2802 {
2803 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2804 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002805 break;
2806 }
2807 }
2808 }
2809 }
2810 }
2811 return type_sp;
2812}
2813
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002814TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002815SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002816{
2817 TypeSP type_sp;
2818
Greg Clayton1be10fc2010-09-29 01:12:09 +00002819 if (type_is_new_ptr)
2820 *type_is_new_ptr = false;
2821
Sean Callananc7fbf732010-08-06 00:32:49 +00002822 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002823 if (die != NULL)
2824 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002825 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002826 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00002827 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002828 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002829 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002830 if (type_is_new_ptr)
2831 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002832
Greg Clayton594e5ed2010-09-27 21:07:38 +00002833 const dw_tag_t tag = die->Tag();
2834
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002835 bool is_forward_declaration = false;
2836 DWARFDebugInfoEntry::Attributes attributes;
2837 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00002838 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00002839 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
2840 size_t byte_size = 0;
2841 Declaration decl;
2842
Greg Clayton4957bf62010-09-30 21:49:03 +00002843 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002844 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002845
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002846 dw_attr_t attr;
2847
2848 switch (tag)
2849 {
2850 case DW_TAG_base_type:
2851 case DW_TAG_pointer_type:
2852 case DW_TAG_reference_type:
2853 case DW_TAG_typedef:
2854 case DW_TAG_const_type:
2855 case DW_TAG_restrict_type:
2856 case DW_TAG_volatile_type:
2857 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002858 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002859 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002860
Greg Claytond88d7592010-09-15 08:33:30 +00002861 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002862 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002863 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2864
2865 if (num_attributes > 0)
2866 {
2867 uint32_t i;
2868 for (i=0; i<num_attributes; ++i)
2869 {
2870 attr = attributes.AttributeAtIndex(i);
2871 DWARFFormValue form_value;
2872 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2873 {
2874 switch (attr)
2875 {
2876 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2877 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2878 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2879 case DW_AT_name:
2880 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00002881 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002882 break;
2883 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2884 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2885 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2886 default:
2887 case DW_AT_sibling:
2888 break;
2889 }
2890 }
2891 }
2892 }
2893
Greg Claytonc93237c2010-10-01 20:48:32 +00002894 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") type => 0x%8.8x\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
2895
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002896 switch (tag)
2897 {
2898 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00002899 break;
2900
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002901 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00002902 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002903 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
2904 encoding,
2905 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002906 break;
2907
Greg Clayton526e5af2010-11-13 03:52:47 +00002908 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
2909 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
2910 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
2911 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
2912 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
2913 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002914 }
2915
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002916 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
2917 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
2918 {
2919 static ConstString g_objc_type_name_id("id");
2920 static ConstString g_objc_type_name_Class("Class");
2921 static ConstString g_objc_type_name_selector("SEL");
2922
Greg Clayton24739922010-10-13 03:15:28 +00002923 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002924 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002925 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00002926 resolve_state = Type::eResolveStateFull;
2927
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002928 }
Greg Clayton24739922010-10-13 03:15:28 +00002929 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002930 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002931 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00002932 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002933 }
Greg Clayton24739922010-10-13 03:15:28 +00002934 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002935 {
Sean Callanan88339f02010-12-06 22:16:55 +00002936 clang_type = ast.CreatePointerType(ast.GetBuiltInType_objc_selector());
Greg Clayton526e5af2010-11-13 03:52:47 +00002937 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002938 }
2939 }
2940
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002941 type_sp.reset( new Type (die->GetOffset(),
2942 this,
2943 type_name_const_str,
2944 byte_size,
2945 NULL,
2946 encoding_uid,
2947 encoding_data_type,
2948 &decl,
2949 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00002950 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002951
Greg Clayton594e5ed2010-09-27 21:07:38 +00002952 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002953
2954// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2955// if (encoding_type != NULL)
2956// {
2957// if (encoding_type != DIE_IS_BEING_PARSED)
2958// type_sp->SetEncodingType(encoding_type);
2959// else
2960// m_indirect_fixups.push_back(type_sp.get());
2961// }
2962 }
2963 break;
2964
2965 case DW_TAG_structure_type:
2966 case DW_TAG_union_type:
2967 case DW_TAG_class_type:
2968 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002969 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002970 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002971
Greg Clayton9e409562010-07-28 02:04:09 +00002972 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002973 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00002974 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002975 if (num_attributes > 0)
2976 {
2977 uint32_t i;
2978 for (i=0; i<num_attributes; ++i)
2979 {
2980 attr = attributes.AttributeAtIndex(i);
2981 DWARFFormValue form_value;
2982 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2983 {
2984 switch (attr)
2985 {
Greg Clayton9e409562010-07-28 02:04:09 +00002986 case DW_AT_decl_file:
2987 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
2988 break;
2989
2990 case DW_AT_decl_line:
2991 decl.SetLine(form_value.Unsigned());
2992 break;
2993
2994 case DW_AT_decl_column:
2995 decl.SetColumn(form_value.Unsigned());
2996 break;
2997
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002998 case DW_AT_name:
2999 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003000 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003001 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003002
3003 case DW_AT_byte_size:
3004 byte_size = form_value.Unsigned();
3005 break;
3006
3007 case DW_AT_accessibility:
3008 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3009 break;
3010
3011 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003012 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003013 break;
3014
3015 case DW_AT_APPLE_runtime_class:
3016 class_language = (LanguageType)form_value.Signed();
3017 break;
3018
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003019 case DW_AT_allocated:
3020 case DW_AT_associated:
3021 case DW_AT_data_location:
3022 case DW_AT_description:
3023 case DW_AT_start_scope:
3024 case DW_AT_visibility:
3025 default:
3026 case DW_AT_sibling:
3027 break;
3028 }
3029 }
3030 }
3031 }
3032
Greg Claytonc93237c2010-10-01 20:48:32 +00003033 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3034
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003035 int tag_decl_kind = -1;
Sean Callananc7fbf732010-08-06 00:32:49 +00003036 AccessType default_accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003037 if (tag == DW_TAG_structure_type)
3038 {
3039 tag_decl_kind = clang::TTK_Struct;
Sean Callananc7fbf732010-08-06 00:32:49 +00003040 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003041 }
3042 else if (tag == DW_TAG_union_type)
3043 {
3044 tag_decl_kind = clang::TTK_Union;
Sean Callananc7fbf732010-08-06 00:32:49 +00003045 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003046 }
3047 else if (tag == DW_TAG_class_type)
3048 {
3049 tag_decl_kind = clang::TTK_Class;
Sean Callananc7fbf732010-08-06 00:32:49 +00003050 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003051 }
3052
Greg Clayton24739922010-10-13 03:15:28 +00003053
Greg Claytonc615ce42010-11-09 04:42:43 +00003054 if (is_forward_declaration)
3055 {
3056 // We have a forward declaration to a type and we need
3057 // to try and find a full declaration. We look in the
3058 // current type index just in case we have a forward
3059 // declaration followed by an actual declarations in the
3060 // DWARF. If this fails, we need to look elsewhere...
3061
3062 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3063
3064 if (!type_sp)
3065 {
3066 // We weren't able to find a full declaration in
3067 // this DWARF, see if we have a declaration anywhere
3068 // else...
3069 if (m_debug_map_symfile)
3070 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3071 }
3072 if (type_sp)
Greg Claytonfacfd062010-11-20 19:16:50 +00003073 {
3074 // We found a real definition for this type elsewhere
3075 // so lets use it and cache the fact that we found
3076 // a complete type for this die
3077 m_die_to_type[die] = type_sp.get();
Greg Claytonc615ce42010-11-09 04:42:43 +00003078 return type_sp;
Greg Claytonfacfd062010-11-20 19:16:50 +00003079 }
Greg Claytonc615ce42010-11-09 04:42:43 +00003080 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003081 assert (tag_decl_kind != -1);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003082 bool clang_type_was_created = false;
3083 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3084 if (clang_type == NULL)
3085 {
3086 clang_type_was_created = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003087 clang_type = ast.CreateRecordType (type_name_cstr,
3088 tag_decl_kind,
3089 GetClangDeclContextForDIE (dwarf_cu, die),
3090 class_language);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003091 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003092
Greg Clayton6adffa22010-09-28 01:04:25 +00003093 // Store a forward declaration to this class type in case any
3094 // parameters in any class methods need it for the clang
3095 // types for function prototypes.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003096 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003097 type_sp.reset (new Type (die->GetOffset(),
3098 this,
3099 type_name_const_str,
3100 byte_size,
3101 NULL,
3102 LLDB_INVALID_UID,
3103 Type::eEncodingIsUID,
3104 &decl,
3105 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003106 Type::eResolveStateForward));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003107
Greg Clayton594e5ed2010-09-27 21:07:38 +00003108 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003109
Greg Clayton40328bf2010-11-08 02:05:08 +00003110 if (die->HasChildren() == false && is_forward_declaration == false)
Greg Clayton1be10fc2010-09-29 01:12:09 +00003111 {
Greg Clayton4957bf62010-09-30 21:49:03 +00003112 // No children for this struct/union/class, lets finish it
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003113 ast.StartTagDeclarationDefinition (clang_type);
3114 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton4957bf62010-09-30 21:49:03 +00003115 }
3116 else if (clang_type_was_created)
3117 {
3118 // Leave this as a forward declaration until we need
3119 // to know the details of the type. lldb_private::Type
3120 // will automatically call the SymbolFile virtual function
3121 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3122 // When the definition needs to be defined.
Greg Clayton1be10fc2010-09-29 01:12:09 +00003123 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003124 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003125 }
Greg Clayton4957bf62010-09-30 21:49:03 +00003126
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003127 }
3128 break;
3129
3130 case DW_TAG_enumeration_type:
3131 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003132 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003133 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003134
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003135 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003136
Greg Claytond88d7592010-09-15 08:33:30 +00003137 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003138 if (num_attributes > 0)
3139 {
3140 uint32_t i;
3141
3142 for (i=0; i<num_attributes; ++i)
3143 {
3144 attr = attributes.AttributeAtIndex(i);
3145 DWARFFormValue form_value;
3146 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3147 {
3148 switch (attr)
3149 {
Greg Clayton7a345282010-11-09 23:46:37 +00003150 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3151 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3152 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003153 case DW_AT_name:
3154 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003155 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003156 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003157 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3158 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3159 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3160 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003161 case DW_AT_allocated:
3162 case DW_AT_associated:
3163 case DW_AT_bit_stride:
3164 case DW_AT_byte_stride:
3165 case DW_AT_data_location:
3166 case DW_AT_description:
3167 case DW_AT_start_scope:
3168 case DW_AT_visibility:
3169 case DW_AT_specification:
3170 case DW_AT_abstract_origin:
3171 case DW_AT_sibling:
3172 break;
3173 }
3174 }
3175 }
3176
Greg Claytonc93237c2010-10-01 20:48:32 +00003177 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3178
Greg Clayton1be10fc2010-09-29 01:12:09 +00003179 clang_type_t enumerator_clang_type = NULL;
3180 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3181 if (clang_type == NULL)
3182 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003183 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3184 DW_ATE_signed,
3185 byte_size * 8);
3186 clang_type = ast.CreateEnumerationType (decl,
3187 type_name_cstr,
3188 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003189 }
3190 else
3191 {
3192 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3193 assert (enumerator_clang_type != NULL);
3194 }
3195
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003196 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003197 type_sp.reset( new Type (die->GetOffset(),
3198 this,
3199 type_name_const_str,
3200 byte_size,
3201 NULL,
3202 encoding_uid,
3203 Type::eEncodingIsUID,
3204 &decl,
3205 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003206 Type::eResolveStateForward));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003207
Greg Clayton594e5ed2010-09-27 21:07:38 +00003208 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003209
Greg Clayton1be10fc2010-09-29 01:12:09 +00003210 // Leave this as a forward declaration until we need
3211 // to know the details of the type. lldb_private::Type
3212 // will automatically call the SymbolFile virtual function
3213 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3214 // When the definition needs to be defined.
3215 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003216 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003217
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003218 }
3219 }
3220 break;
3221
Jim Inghamb0be4422010-08-12 01:20:14 +00003222 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003223 case DW_TAG_subprogram:
3224 case DW_TAG_subroutine_type:
3225 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003226 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003227 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003228
3229 const char *mangled = NULL;
3230 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003231 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003232 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003233 bool is_static = false;
3234 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003235 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003236
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003237 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003238 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003239
3240
Greg Claytond88d7592010-09-15 08:33:30 +00003241 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003242 if (num_attributes > 0)
3243 {
3244 uint32_t i;
3245 for (i=0; i<num_attributes; ++i)
3246 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003247 const dw_attr_t attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003248 DWARFFormValue form_value;
3249 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3250 {
3251 switch (attr)
3252 {
3253 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3254 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3255 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3256 case DW_AT_name:
3257 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003258 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003259 break;
3260
3261 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3262 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003263 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003264 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003265 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3266 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003267 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3268
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003269 case DW_AT_external:
3270 if (form_value.Unsigned())
3271 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003272 if (storage == clang::SC_None)
3273 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003274 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003275 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003276 }
3277 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003278
3279 case DW_AT_allocated:
3280 case DW_AT_associated:
3281 case DW_AT_address_class:
3282 case DW_AT_artificial:
3283 case DW_AT_calling_convention:
3284 case DW_AT_data_location:
3285 case DW_AT_elemental:
3286 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003287 case DW_AT_frame_base:
3288 case DW_AT_high_pc:
3289 case DW_AT_low_pc:
3290 case DW_AT_object_pointer:
3291 case DW_AT_prototyped:
3292 case DW_AT_pure:
3293 case DW_AT_ranges:
3294 case DW_AT_recursive:
3295 case DW_AT_return_addr:
3296 case DW_AT_segment:
3297 case DW_AT_specification:
3298 case DW_AT_start_scope:
3299 case DW_AT_static_link:
3300 case DW_AT_trampoline:
3301 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003302 case DW_AT_vtable_elem_location:
3303 case DW_AT_abstract_origin:
3304 case DW_AT_description:
3305 case DW_AT_sibling:
3306 break;
3307 }
3308 }
3309 }
Greg Clayton24739922010-10-13 03:15:28 +00003310 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003311
Greg Clayton24739922010-10-13 03:15:28 +00003312 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00003313
Greg Clayton24739922010-10-13 03:15:28 +00003314 clang_type_t return_clang_type = NULL;
3315 Type *func_type = NULL;
3316
3317 if (type_die_offset != DW_INVALID_OFFSET)
3318 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003319
Greg Clayton24739922010-10-13 03:15:28 +00003320 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003321 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003322 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003323 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003324
Greg Claytonf51de672010-10-01 02:31:07 +00003325
Greg Clayton24739922010-10-13 03:15:28 +00003326 std::vector<clang_type_t> function_param_types;
3327 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003328
Greg Clayton24739922010-10-13 03:15:28 +00003329 // Parse the function children for the parameters
3330 if (die->HasChildren())
3331 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003332 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003333 ParseChildParameters (sc,
3334 type_sp,
3335 dwarf_cu,
3336 die,
3337 skip_artificial,
3338 type_list,
3339 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00003340 function_param_decls,
3341 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00003342 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003343
Greg Clayton24739922010-10-13 03:15:28 +00003344 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003345 clang_type = ast.CreateFunctionType (return_clang_type,
3346 &function_param_types[0],
3347 function_param_types.size(),
3348 is_variadic,
3349 type_quals);
3350
Greg Clayton24739922010-10-13 03:15:28 +00003351 if (type_name_cstr)
3352 {
3353 bool type_handled = false;
3354 const DWARFDebugInfoEntry *parent_die = die->GetParent();
3355 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003356 {
Greg Clayton24739922010-10-13 03:15:28 +00003357 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003358 {
Greg Clayton24739922010-10-13 03:15:28 +00003359 // We need to find the DW_TAG_class_type or
3360 // DW_TAG_struct_type by name so we can add this
3361 // as a member function of the class.
3362 const char *class_name_start = type_name_cstr + 2;
3363 const char *class_name_end = ::strchr (class_name_start, ' ');
3364 SymbolContext empty_sc;
3365 clang_type_t class_opaque_type = NULL;
3366 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003367 {
Greg Clayton24739922010-10-13 03:15:28 +00003368 ConstString class_name (class_name_start, class_name_end - class_name_start);
3369 TypeList types;
3370 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3371 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003372 {
Greg Clayton24739922010-10-13 03:15:28 +00003373 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003374 {
Greg Clayton24739922010-10-13 03:15:28 +00003375 Type *type = types.GetTypeAtIndex (i).get();
3376 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3377 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003378 {
Greg Clayton24739922010-10-13 03:15:28 +00003379 class_opaque_type = type_clang_forward_type;
3380 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003381 }
3382 }
3383 }
Greg Clayton24739922010-10-13 03:15:28 +00003384 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003385
Greg Clayton24739922010-10-13 03:15:28 +00003386 if (class_opaque_type)
3387 {
3388 // If accessibility isn't set to anything valid, assume public for
3389 // now...
3390 if (accessibility == eAccessNone)
3391 accessibility = eAccessPublic;
3392
3393 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003394 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3395 type_name_cstr,
3396 clang_type,
3397 accessibility);
Greg Clayton24739922010-10-13 03:15:28 +00003398 type_handled = objc_method_decl != NULL;
3399 }
3400 }
3401 else if (parent_die->Tag() == DW_TAG_class_type ||
3402 parent_die->Tag() == DW_TAG_structure_type)
3403 {
3404 // Look at the parent of this DIE and see if is is
3405 // a class or struct and see if this is actually a
3406 // C++ method
3407 Type *class_type = ResolveType (dwarf_cu, parent_die);
3408 if (class_type)
3409 {
3410 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3411 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003412 {
Greg Clayton24739922010-10-13 03:15:28 +00003413 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3414 // in the DWARF for C++ methods... Default to public for now...
Greg Clayton6d01ad92010-09-29 01:57:37 +00003415 if (accessibility == eAccessNone)
3416 accessibility = eAccessPublic;
3417
Greg Clayton24739922010-10-13 03:15:28 +00003418 clang::CXXMethodDecl *cxx_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003419 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3420 type_name_cstr,
3421 clang_type,
3422 accessibility,
3423 is_virtual,
3424 is_static,
3425 is_inline,
3426 is_explicit);
Greg Clayton24739922010-10-13 03:15:28 +00003427 type_handled = cxx_method_decl != NULL;
Greg Clayton0fffff52010-09-24 05:15:53 +00003428 }
3429 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003430 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003431 }
Greg Clayton24739922010-10-13 03:15:28 +00003432
3433 if (!type_handled)
3434 {
3435 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003436 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3437 clang_type,
3438 storage,
3439 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003440
3441 // Add the decl to our DIE to decl context map
3442 assert (function_decl);
3443 m_die_to_decl_ctx[die] = function_decl;
3444 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003445 ast.SetFunctionParameters (function_decl,
3446 &function_param_decls.front(),
3447 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003448 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003449 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003450 type_sp.reset( new Type (die->GetOffset(),
3451 this,
3452 type_name_const_str,
3453 0,
3454 NULL,
3455 LLDB_INVALID_UID,
3456 Type::eEncodingIsUID,
3457 &decl,
3458 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003459 Type::eResolveStateFull));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003460
Greg Clayton24739922010-10-13 03:15:28 +00003461 m_die_to_type[die] = type_sp.get();
3462 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003463 }
3464 break;
3465
3466 case DW_TAG_array_type:
3467 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003468 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003469 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003470
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003471 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003472 int64_t first_index = 0;
3473 uint32_t byte_stride = 0;
3474 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003475 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003476
3477 if (num_attributes > 0)
3478 {
3479 uint32_t i;
3480 for (i=0; i<num_attributes; ++i)
3481 {
3482 attr = attributes.AttributeAtIndex(i);
3483 DWARFFormValue form_value;
3484 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3485 {
3486 switch (attr)
3487 {
3488 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3489 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3490 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3491 case DW_AT_name:
3492 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003493 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003494 break;
3495
3496 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3497 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3498 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3499 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003500 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003501 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003502 case DW_AT_allocated:
3503 case DW_AT_associated:
3504 case DW_AT_data_location:
3505 case DW_AT_description:
3506 case DW_AT_ordering:
3507 case DW_AT_start_scope:
3508 case DW_AT_visibility:
3509 case DW_AT_specification:
3510 case DW_AT_abstract_origin:
3511 case DW_AT_sibling:
3512 break;
3513 }
3514 }
3515 }
3516
Greg Claytonc93237c2010-10-01 20:48:32 +00003517 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3518
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003519 Type *element_type = ResolveTypeUID(type_die_offset);
3520
3521 if (element_type)
3522 {
3523 std::vector<uint64_t> element_orders;
3524 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003525 // We have an array that claims to have no members, lets give it at least one member...
3526 if (element_orders.empty())
3527 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003528 if (byte_stride == 0 && bit_stride == 0)
3529 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003530 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003531 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3532 uint64_t num_elements = 0;
3533 std::vector<uint64_t>::const_reverse_iterator pos;
3534 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3535 for (pos = element_orders.rbegin(); pos != end; ++pos)
3536 {
3537 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003538 clang_type = ast.CreateArrayType (array_element_type,
3539 num_elements,
3540 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003541 array_element_type = clang_type;
3542 array_element_bit_stride = array_element_bit_stride * num_elements;
3543 }
3544 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003545 type_sp.reset( new Type (die->GetOffset(),
3546 this,
3547 empty_name,
3548 array_element_bit_stride / 8,
3549 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00003550 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003551 Type::eEncodingIsUID,
3552 &decl,
3553 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003554 Type::eResolveStateFull));
3555 type_sp->SetEncodingType (element_type);
Greg Clayton594e5ed2010-09-27 21:07:38 +00003556 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003557 }
3558 }
3559 }
3560 break;
3561
Greg Clayton9b81a312010-06-12 01:20:30 +00003562 case DW_TAG_ptr_to_member_type:
3563 {
3564 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3565 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3566
Greg Claytond88d7592010-09-15 08:33:30 +00003567 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003568
3569 if (num_attributes > 0) {
3570 uint32_t i;
3571 for (i=0; i<num_attributes; ++i)
3572 {
3573 attr = attributes.AttributeAtIndex(i);
3574 DWARFFormValue form_value;
3575 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3576 {
3577 switch (attr)
3578 {
3579 case DW_AT_type:
3580 type_die_offset = form_value.Reference(dwarf_cu); break;
3581 case DW_AT_containing_type:
3582 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3583 }
3584 }
3585 }
3586
3587 Type *pointee_type = ResolveTypeUID(type_die_offset);
3588 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3589
Greg Clayton526e5af2010-11-13 03:52:47 +00003590 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
3591 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003592
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003593 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3594 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003595
Greg Clayton526e5af2010-11-13 03:52:47 +00003596 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3597 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003598
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003599 type_sp.reset( new Type (die->GetOffset(),
3600 this,
3601 type_name_const_str,
3602 byte_size,
3603 NULL,
3604 LLDB_INVALID_UID,
3605 Type::eEncodingIsUID,
3606 NULL,
3607 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003608 Type::eResolveStateForward));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003609 m_die_to_type[die] = type_sp.get();
Greg Clayton9b81a312010-06-12 01:20:30 +00003610 }
3611
3612 break;
3613 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003614 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003615 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003616 break;
3617 }
3618
3619 if (type_sp.get())
3620 {
3621 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3622 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3623
3624 SymbolContextScope * symbol_context_scope = NULL;
3625 if (sc_parent_tag == DW_TAG_compile_unit)
3626 {
3627 symbol_context_scope = sc.comp_unit;
3628 }
3629 else if (sc.function != NULL)
3630 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003631 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003632 if (symbol_context_scope == NULL)
3633 symbol_context_scope = sc.function;
3634 }
3635
3636 if (symbol_context_scope != NULL)
3637 {
3638 type_sp->SetSymbolContextScope(symbol_context_scope);
3639 }
3640
3641// if (udt_sp.get())
3642// {
3643// if (is_forward_declaration)
3644// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3645// type_sp->SetUserDefinedType(udt_sp);
3646// }
3647
3648 if (type_sp.unique())
3649 {
3650 // We are ready to put this type into the uniqued list up at the module level
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003651 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00003652
Greg Clayton594e5ed2010-09-27 21:07:38 +00003653 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003654 }
3655 }
3656 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003657 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003658 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003659 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003660 }
3661 }
3662 return type_sp;
3663}
3664
3665size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003666SymbolFileDWARF::ParseTypes
3667(
3668 const SymbolContext& sc,
3669 DWARFCompileUnit* dwarf_cu,
3670 const DWARFDebugInfoEntry *die,
3671 bool parse_siblings,
3672 bool parse_children
3673)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003674{
3675 size_t types_added = 0;
3676 while (die != NULL)
3677 {
3678 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003679 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003680 {
3681 if (type_is_new)
3682 ++types_added;
3683 }
3684
3685 if (parse_children && die->HasChildren())
3686 {
3687 if (die->Tag() == DW_TAG_subprogram)
3688 {
3689 SymbolContext child_sc(sc);
3690 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3691 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3692 }
3693 else
3694 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3695 }
3696
3697 if (parse_siblings)
3698 die = die->GetSibling();
3699 else
3700 die = NULL;
3701 }
3702 return types_added;
3703}
3704
3705
3706size_t
3707SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3708{
3709 assert(sc.comp_unit && sc.function);
3710 size_t functions_added = 0;
3711 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3712 if (dwarf_cu)
3713 {
3714 dw_offset_t function_die_offset = sc.function->GetID();
3715 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3716 if (function_die)
3717 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003718 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003719 }
3720 }
3721
3722 return functions_added;
3723}
3724
3725
3726size_t
3727SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3728{
3729 // At least a compile unit must be valid
3730 assert(sc.comp_unit);
3731 size_t types_added = 0;
3732 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3733 if (dwarf_cu)
3734 {
3735 if (sc.function)
3736 {
3737 dw_offset_t function_die_offset = sc.function->GetID();
3738 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3739 if (func_die && func_die->HasChildren())
3740 {
3741 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3742 }
3743 }
3744 else
3745 {
3746 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3747 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3748 {
3749 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3750 }
3751 }
3752 }
3753
3754 return types_added;
3755}
3756
3757size_t
3758SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3759{
3760 if (sc.comp_unit != NULL)
3761 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003762 DWARFDebugInfo* info = DebugInfo();
3763 if (info == NULL)
3764 return 0;
3765
3766 uint32_t cu_idx = UINT32_MAX;
3767 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003768
3769 if (dwarf_cu == NULL)
3770 return 0;
3771
3772 if (sc.function)
3773 {
3774 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003775
3776 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3777 assert (func_lo_pc != DW_INVALID_ADDRESS);
3778
3779 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003780 }
3781 else if (sc.comp_unit)
3782 {
3783 uint32_t vars_added = 0;
3784 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3785
3786 if (variables.get() == NULL)
3787 {
3788 variables.reset(new VariableList());
3789 sc.comp_unit->SetVariableList(variables);
3790
3791 // Index if we already haven't to make sure the compile units
3792 // get indexed and make their global DIE index list
3793 if (!m_indexed)
3794 Index ();
3795
Greg Claytonc685f8e2010-09-15 04:15:46 +00003796 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00003797 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003798 for (size_t idx=0; idx<num_globals; ++idx)
3799 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003800 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003801 if (var_sp)
3802 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00003803 variables->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003804 ++vars_added;
3805 }
3806 }
3807 }
3808 return vars_added;
3809 }
3810 }
3811 return 0;
3812}
3813
3814
3815VariableSP
3816SymbolFileDWARF::ParseVariableDIE
3817(
3818 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003819 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003820 const DWARFDebugInfoEntry *die,
3821 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003822)
3823{
3824
Greg Clayton83c5cd92010-11-14 22:13:40 +00003825 VariableSP var_sp (m_die_to_variable_sp[die]);
3826 if (var_sp)
3827 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003828
3829 const dw_tag_t tag = die->Tag();
3830 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003831 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003832 if (num_attributes > 0)
3833 {
3834 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00003835 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003836 Declaration decl;
3837 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003838 Type *var_type = NULL;
3839 DWARFExpression location;
3840 bool is_external = false;
3841 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00003842 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003843
3844 for (i=0; i<num_attributes; ++i)
3845 {
3846 dw_attr_t attr = attributes.AttributeAtIndex(i);
3847 DWARFFormValue form_value;
3848 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3849 {
3850 switch (attr)
3851 {
3852 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3853 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3854 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3855 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00003856 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003857 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003858 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3859 case DW_AT_location:
3860 {
3861 if (form_value.BlockData())
3862 {
3863 const DataExtractor& debug_info_data = get_debug_info_data();
3864
3865 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3866 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00003867 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003868 }
3869 else
3870 {
3871 const DataExtractor& debug_loc_data = get_debug_loc_data();
3872 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3873
3874 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3875 if (loc_list_length > 0)
3876 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003877 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
3878 assert (func_low_pc != LLDB_INVALID_ADDRESS);
3879 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003880 }
3881 }
3882 }
3883 break;
3884
3885 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003886 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003887 case DW_AT_const_value:
3888 case DW_AT_declaration:
3889 case DW_AT_description:
3890 case DW_AT_endianity:
3891 case DW_AT_segment:
3892 case DW_AT_start_scope:
3893 case DW_AT_visibility:
3894 default:
3895 case DW_AT_abstract_origin:
3896 case DW_AT_sibling:
3897 case DW_AT_specification:
3898 break;
3899 }
3900 }
3901 }
3902
3903 if (location.IsValid())
3904 {
3905 assert(var_type != DIE_IS_BEING_PARSED);
3906
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003907 ValueType scope = eValueTypeInvalid;
3908
3909 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3910 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3911
3912 if (tag == DW_TAG_formal_parameter)
3913 scope = eValueTypeVariableArgument;
3914 else if (is_external || parent_tag == DW_TAG_compile_unit)
3915 scope = eValueTypeVariableGlobal;
3916 else
3917 scope = eValueTypeVariableLocal;
3918
3919 SymbolContextScope * symbol_context_scope = NULL;
3920 if (parent_tag == DW_TAG_compile_unit)
3921 {
3922 symbol_context_scope = sc.comp_unit;
3923 }
3924 else if (sc.function != NULL)
3925 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003926 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003927 if (symbol_context_scope == NULL)
3928 symbol_context_scope = sc.function;
3929 }
3930
3931 assert(symbol_context_scope != NULL);
3932 var_sp.reset (new Variable(die->GetOffset(),
Greg Clayton83c5cd92010-11-14 22:13:40 +00003933 name,
3934 mangled,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003935 var_type,
3936 scope,
3937 symbol_context_scope,
3938 &decl,
3939 location,
3940 is_external,
3941 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003942
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003943 }
3944 }
Greg Clayton83c5cd92010-11-14 22:13:40 +00003945 // Cache var_sp even if NULL (the variable was just a specification or
3946 // was missing vital information to be able to be displayed in the debugger
3947 // (missing location due to optimization, etc)) so we don't re-parse
3948 // this DIE over and over later...
3949 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003950 return var_sp;
3951}
3952
3953size_t
3954SymbolFileDWARF::ParseVariables
3955(
3956 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003957 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003958 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003959 const DWARFDebugInfoEntry *orig_die,
3960 bool parse_siblings,
3961 bool parse_children,
3962 VariableList* cc_variable_list
3963)
3964{
3965 if (orig_die == NULL)
3966 return 0;
3967
3968 size_t vars_added = 0;
3969 const DWARFDebugInfoEntry *die = orig_die;
3970 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3971 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3972 VariableListSP variables;
3973 switch (parent_tag)
3974 {
3975 case DW_TAG_compile_unit:
3976 if (sc.comp_unit != NULL)
3977 {
3978 variables = sc.comp_unit->GetVariableList(false);
3979 if (variables.get() == NULL)
3980 {
3981 variables.reset(new VariableList());
3982 sc.comp_unit->SetVariableList(variables);
3983 }
3984 }
3985 else
3986 {
3987 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3988 vars_added = 0;
3989 }
3990 break;
3991
3992 case DW_TAG_subprogram:
3993 case DW_TAG_inlined_subroutine:
3994 case DW_TAG_lexical_block:
3995 if (sc.function != NULL)
3996 {
3997 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003998
3999 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4000 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00004001 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004002 if (variables.get() == NULL)
4003 {
4004 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004005 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004006 }
4007 }
4008 else
4009 {
4010 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
4011 vars_added = 0;
4012 }
4013 break;
4014
4015 default:
4016 assert(!"Didn't find appropriate parent DIE for variable list...");
4017 break;
4018 }
4019
4020 // We need to have a variable list at this point that we can add variables to
4021 assert(variables.get());
4022
4023 while (die != NULL)
4024 {
4025 dw_tag_t tag = die->Tag();
4026
4027 // Check to see if we have already parsed this variable or constant?
Greg Claytonbcf12172010-10-28 00:56:11 +00004028 if (m_die_to_variable_sp[die])
4029 {
4030 if (cc_variable_list)
Greg Clayton83c5cd92010-11-14 22:13:40 +00004031 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Greg Claytonbcf12172010-10-28 00:56:11 +00004032 }
4033 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004034 {
4035 // We haven't already parsed it, lets do that now.
4036 if ((tag == DW_TAG_variable) ||
4037 (tag == DW_TAG_constant) ||
4038 (tag == DW_TAG_formal_parameter && sc.function))
4039 {
Greg Clayton016a95e2010-09-14 02:20:48 +00004040 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004041 if (var_sp)
4042 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00004043 variables->AddVariableIfUnique (var_sp);
Greg Claytonbcf12172010-10-28 00:56:11 +00004044 if (cc_variable_list)
Greg Clayton83c5cd92010-11-14 22:13:40 +00004045 cc_variable_list->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004046 ++vars_added;
4047 }
4048 }
4049 }
4050
4051 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4052
4053 if (!skip_children && parse_children && die->HasChildren())
4054 {
Greg Claytonbcf12172010-10-28 00:56:11 +00004055 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004056 }
4057
4058 if (parse_siblings)
4059 die = die->GetSibling();
4060 else
4061 die = NULL;
4062 }
4063
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004064 return vars_added;
4065}
4066
4067//------------------------------------------------------------------
4068// PluginInterface protocol
4069//------------------------------------------------------------------
4070const char *
4071SymbolFileDWARF::GetPluginName()
4072{
4073 return "SymbolFileDWARF";
4074}
4075
4076const char *
4077SymbolFileDWARF::GetShortPluginName()
4078{
4079 return GetPluginNameStatic();
4080}
4081
4082uint32_t
4083SymbolFileDWARF::GetPluginVersion()
4084{
4085 return 1;
4086}
4087
4088void
4089SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
4090{
4091}
4092
4093Error
4094SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
4095{
4096 Error error;
4097 error.SetErrorString("No plug-in command are currently supported.");
4098 return error;
4099}
4100
4101Log *
4102SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
4103{
4104 return NULL;
4105}
4106