blob: 866617bcf4497b20a54a97ad966616ec8cc13e65 [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"
23
24#include "lldb/Core/Module.h"
25#include "lldb/Core/PluginManager.h"
26#include "lldb/Core/RegularExpression.h"
27#include "lldb/Core/Scalar.h"
28#include "lldb/Core/Section.h"
29#include "lldb/Core/Timer.h"
30#include "lldb/Core/Value.h"
31
32#include "lldb/Symbol/Block.h"
33#include "lldb/Symbol/CompileUnit.h"
34#include "lldb/Symbol/LineTable.h"
35#include "lldb/Symbol/ObjectFile.h"
36#include "lldb/Symbol/SymbolVendor.h"
37#include "lldb/Symbol/VariableList.h"
38
39#include "DWARFCompileUnit.h"
40#include "DWARFDebugAbbrev.h"
41#include "DWARFDebugAranges.h"
42#include "DWARFDebugInfo.h"
43#include "DWARFDebugInfoEntry.h"
44#include "DWARFDebugLine.h"
45#include "DWARFDebugPubnames.h"
46#include "DWARFDebugRanges.h"
47#include "DWARFDIECollection.h"
48#include "DWARFFormValue.h"
49#include "DWARFLocationList.h"
50#include "LogChannelDWARF.h"
51
52#include <map>
53
54#define DIE_IS_BEING_PARSED ((void*)1)
55
56using namespace lldb;
57using namespace lldb_private;
58
59
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060static uint32_t
61DwarfToClangAccessibility (uint32_t dwarf_accessibility)
62{
63 switch (dwarf_accessibility)
64 {
65 case DW_ACCESS_public:
66 return clang::AS_public;
67 case DW_ACCESS_private:
68 return clang::AS_private;
69 case DW_ACCESS_protected:
70 return clang::AS_protected;
71 default:
72 return clang::AS_none;
73 }
74}
75
76void
77SymbolFileDWARF::Initialize()
78{
79 LogChannelDWARF::Initialize();
80 PluginManager::RegisterPlugin (GetPluginNameStatic(),
81 GetPluginDescriptionStatic(),
82 CreateInstance);
83}
84
85void
86SymbolFileDWARF::Terminate()
87{
88 PluginManager::UnregisterPlugin (CreateInstance);
89 LogChannelDWARF::Initialize();
90}
91
92
93const char *
94SymbolFileDWARF::GetPluginNameStatic()
95{
96 return "symbol-file.dwarf2";
97}
98
99const char *
100SymbolFileDWARF::GetPluginDescriptionStatic()
101{
102 return "DWARF and DWARF3 debug symbol file reader.";
103}
104
105
106SymbolFile*
107SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
108{
109 return new SymbolFileDWARF(obj_file);
110}
111
112//----------------------------------------------------------------------
113// Gets the first parent that is a lexical block, function or inlined
114// subroutine, or compile unit.
115//----------------------------------------------------------------------
116static const DWARFDebugInfoEntry *
117GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
118{
119 const DWARFDebugInfoEntry *die;
120 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
121 {
122 dw_tag_t tag = die->Tag();
123
124 switch (tag)
125 {
126 case DW_TAG_compile_unit:
127 case DW_TAG_subprogram:
128 case DW_TAG_inlined_subroutine:
129 case DW_TAG_lexical_block:
130 return die;
131 }
132 }
133 return NULL;
134}
135
136
137SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) :
138 SymbolFile(ofile),
139 m_flags(),
140 m_data_debug_abbrev(),
141 m_data_debug_aranges(),
142 m_data_debug_frame(),
143 m_data_debug_info(),
144 m_data_debug_line(),
145 m_data_debug_loc(),
146 m_data_debug_macinfo(),
147 m_data_debug_pubnames(),
148 m_data_debug_pubtypes(),
149 m_data_debug_ranges(),
150 m_data_debug_str(),
151 m_abbr(),
152 m_aranges(),
153 m_info(),
154 m_line(),
Greg Clayton0c5cd902010-06-28 21:30:43 +0000155 m_base_name_to_function_die(),
156 m_full_name_to_function_die(),
157 m_method_name_to_function_die(),
158 m_selector_name_to_function_die(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 m_name_to_global_die(),
160 m_name_to_type_die(),
161 m_indexed(false),
162// m_pubnames(),
163// m_pubtypes(),
164// m_pubbasetypes(),
165 m_ranges()//,
166// m_type_fixups(),
167// m_indirect_fixups()
168{
169}
170
171SymbolFileDWARF::~SymbolFileDWARF()
172{
173}
174
175bool
176SymbolFileDWARF::SupportedVersion(uint16_t version)
177{
178 return version == 2 || version == 3;
179}
180
181uint32_t
182SymbolFileDWARF::GetAbilities ()
183{
184 uint32_t abilities = 0;
185 if (m_obj_file != NULL)
186 {
187 const Section* section = NULL;
188 const SectionList *section_list = m_obj_file->GetSectionList();
189 if (section_list == NULL)
190 return 0;
191
192 uint64_t debug_abbrev_file_size = 0;
193 uint64_t debug_aranges_file_size = 0;
194 uint64_t debug_frame_file_size = 0;
195 uint64_t debug_info_file_size = 0;
196 uint64_t debug_line_file_size = 0;
197 uint64_t debug_loc_file_size = 0;
198 uint64_t debug_macinfo_file_size = 0;
199 uint64_t debug_pubnames_file_size = 0;
200 uint64_t debug_pubtypes_file_size = 0;
201 uint64_t debug_ranges_file_size = 0;
202 uint64_t debug_str_file_size = 0;
203
204 static ConstString g_dwarf_section_name ("__DWARF");
205
206 section = section_list->FindSectionByName(g_dwarf_section_name).get();
207
208 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000209 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
Greg Clayton4ceb9982010-07-21 22:54:26 +0000211 section_list = &section->GetChildren ();
212 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213
Greg Clayton4ceb9982010-07-21 22:54:26 +0000214 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215 if (section != NULL)
216 {
217 debug_info_file_size = section->GetByteSize();
218
Greg Clayton4ceb9982010-07-21 22:54:26 +0000219 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220 if (section)
221 debug_abbrev_file_size = section->GetByteSize();
222 else
223 m_flags.Set (flagsGotDebugAbbrevData);
224
Greg Clayton4ceb9982010-07-21 22:54:26 +0000225 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 if (section)
227 debug_aranges_file_size = section->GetByteSize();
228 else
229 m_flags.Set (flagsGotDebugArangesData);
230
Greg Clayton4ceb9982010-07-21 22:54:26 +0000231 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 if (section)
233 debug_frame_file_size = section->GetByteSize();
234 else
235 m_flags.Set (flagsGotDebugFrameData);
236
Greg Clayton4ceb9982010-07-21 22:54:26 +0000237 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238 if (section)
239 debug_line_file_size = section->GetByteSize();
240 else
241 m_flags.Set (flagsGotDebugLineData);
242
Greg Clayton4ceb9982010-07-21 22:54:26 +0000243 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244 if (section)
245 debug_loc_file_size = section->GetByteSize();
246 else
247 m_flags.Set (flagsGotDebugLocData);
248
Greg Clayton4ceb9982010-07-21 22:54:26 +0000249 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250 if (section)
251 debug_macinfo_file_size = section->GetByteSize();
252 else
253 m_flags.Set (flagsGotDebugMacInfoData);
254
Greg Clayton4ceb9982010-07-21 22:54:26 +0000255 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256 if (section)
257 debug_pubnames_file_size = section->GetByteSize();
258 else
259 m_flags.Set (flagsGotDebugPubNamesData);
260
Greg Clayton4ceb9982010-07-21 22:54:26 +0000261 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 if (section)
263 debug_pubtypes_file_size = section->GetByteSize();
264 else
265 m_flags.Set (flagsGotDebugPubTypesData);
266
Greg Clayton4ceb9982010-07-21 22:54:26 +0000267 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268 if (section)
269 debug_ranges_file_size = section->GetByteSize();
270 else
271 m_flags.Set (flagsGotDebugRangesData);
272
Greg Clayton4ceb9982010-07-21 22:54:26 +0000273 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274 if (section)
275 debug_str_file_size = section->GetByteSize();
276 else
277 m_flags.Set (flagsGotDebugStrData);
278 }
279
280 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
281 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
282
283 if (debug_line_file_size > 0)
284 abilities |= LineTables;
285
286 if (debug_aranges_file_size > 0)
287 abilities |= AddressAcceleratorTable;
288
289 if (debug_pubnames_file_size > 0)
290 abilities |= FunctionAcceleratorTable;
291
292 if (debug_pubtypes_file_size > 0)
293 abilities |= TypeAcceleratorTable;
294
295 if (debug_macinfo_file_size > 0)
296 abilities |= MacroInformation;
297
298 if (debug_frame_file_size > 0)
299 abilities |= CallFrameInformation;
300 }
301 return abilities;
302}
303
304const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000305SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306{
307 if (m_flags.IsClear (got_flag))
308 {
309 m_flags.Set (got_flag);
310 const SectionList *section_list = m_obj_file->GetSectionList();
311 if (section_list)
312 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000313 Section *section = section_list->FindSectionByType(sect_type, true).get();
314 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315 {
316 // See if we memory mapped the DWARF segment?
317 if (m_dwarf_data.GetByteSize())
318 {
319 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
320 }
321 else
322 {
323 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
324 data.Clear();
325 }
326 }
327 }
328 }
329 return data;
330}
331
332const DataExtractor&
333SymbolFileDWARF::get_debug_abbrev_data()
334{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000335 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336}
337
338const DataExtractor&
339SymbolFileDWARF::get_debug_aranges_data()
340{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000341 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342}
343
344const DataExtractor&
345SymbolFileDWARF::get_debug_frame_data()
346{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000347 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348}
349
350const DataExtractor&
351SymbolFileDWARF::get_debug_info_data()
352{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000353 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354}
355
356const DataExtractor&
357SymbolFileDWARF::get_debug_line_data()
358{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000359 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360}
361
362const DataExtractor&
363SymbolFileDWARF::get_debug_loc_data()
364{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000365 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366}
367
368const DataExtractor&
369SymbolFileDWARF::get_debug_macinfo_data()
370{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000371 return GetCachedSectionData (flagsGotDebugMacInfoData, eSectionTypeDWARFDebugMacInfo, m_data_debug_macinfo);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372}
373
374const DataExtractor&
375SymbolFileDWARF::get_debug_pubnames_data()
376{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000377 return GetCachedSectionData (flagsGotDebugPubNamesData, eSectionTypeDWARFDebugPubNames, m_data_debug_pubnames);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378}
379
380const DataExtractor&
381SymbolFileDWARF::get_debug_pubtypes_data()
382{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000383 return GetCachedSectionData (flagsGotDebugPubTypesData, eSectionTypeDWARFDebugPubTypes, m_data_debug_pubtypes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384}
385
386const DataExtractor&
387SymbolFileDWARF::get_debug_ranges_data()
388{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000389 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390}
391
392const DataExtractor&
393SymbolFileDWARF::get_debug_str_data()
394{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000395 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396}
397
398
399DWARFDebugAbbrev*
400SymbolFileDWARF::DebugAbbrev()
401{
402 if (m_abbr.get() == NULL)
403 {
404 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
405 if (debug_abbrev_data.GetByteSize() > 0)
406 {
407 m_abbr.reset(new DWARFDebugAbbrev());
408 if (m_abbr.get())
409 m_abbr->Parse(debug_abbrev_data);
410 }
411 }
412 return m_abbr.get();
413}
414
415const DWARFDebugAbbrev*
416SymbolFileDWARF::DebugAbbrev() const
417{
418 return m_abbr.get();
419}
420
421DWARFDebugAranges*
422SymbolFileDWARF::DebugAranges()
423{
424 if (m_aranges.get() == NULL)
425 {
426 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
427 m_aranges.reset(new DWARFDebugAranges());
428 if (m_aranges.get())
429 {
430 const DataExtractor &debug_aranges_data = get_debug_aranges_data();
431 if (debug_aranges_data.GetByteSize() > 0)
432 m_aranges->Extract(debug_aranges_data);
433 else
434 m_aranges->Generate(this);
435 }
436 }
437 return m_aranges.get();
438}
439
440const DWARFDebugAranges*
441SymbolFileDWARF::DebugAranges() const
442{
443 return m_aranges.get();
444}
445
446
447DWARFDebugInfo*
448SymbolFileDWARF::DebugInfo()
449{
450 if (m_info.get() == NULL)
451 {
452 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
453 if (get_debug_info_data().GetByteSize() > 0)
454 {
455 m_info.reset(new DWARFDebugInfo());
456 if (m_info.get())
457 {
458 m_info->SetDwarfData(this);
459 }
460 }
461 }
462 return m_info.get();
463}
464
465const DWARFDebugInfo*
466SymbolFileDWARF::DebugInfo() const
467{
468 return m_info.get();
469}
470
471//DWARFDebugLine*
472//SymbolFileDWARF::DebugLine()
473//{
474// if (m_line.get() == NULL)
475// {
476// Timer scoped_timer(__PRETTY_FUNCTION__);
477// const DataExtractor &debug_line_data = debug_line();
478// if (debug_line_data.GetByteSize() > 0)
479// {
480// m_line.reset(new DWARFDebugLine());
481// if (m_line.get())
482// m_line->Parse(debug_line_data);
483// }
484// }
485// return m_line.get();
486//}
487//
488//const DWARFDebugLine*
489//SymbolFileDWARF::DebugLine() const
490//{
491// return m_line.get();
492//}
493
494
495DWARFCompileUnit*
496SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
497{
498 DWARFDebugInfo* info = DebugInfo();
499 if (info)
500 return info->GetCompileUnit(cu_uid).get();
501 return NULL;
502}
503
504//DWARFCompileUnit*
505//SymbolFileDWARF::GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu)
506//{
507// DWARFCompileUnit* cu = NULL;
508// DWARFDebugInfo* info = DebugInfo();
509// if (info)
510// {
511// uint32_t cu_idx = 0;
512// if (prev_cu != NULL)
513// {
514// // Find the index of the previus DWARF compile unit if one was provided
515// while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL)
516// {
517// ++cu_idx;
518// if (cu == prev_cu)
519// break;
520// }
521// }
522//
523// // Now find the next unparsed DWARF compile unit. We do this by checking the
524// // user data in the DWARFCompileUnit class that starts as NULL, and eventually
525// // holds a pointer to the CompileUnit that was created for it after it has
526// // been parsed.
527// while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL)
528// {
529// if (cu->GetUserData() == NULL)
530// break;
531// }
532// }
533// return cu;
534//}
535
536DWARFDebugRanges*
537SymbolFileDWARF::DebugRanges()
538{
539 if (m_ranges.get() == NULL)
540 {
541 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
542 if (get_debug_ranges_data().GetByteSize() > 0)
543 {
544 m_ranges.reset(new DWARFDebugRanges());
545 if (m_ranges.get())
546 m_ranges->Extract(this);
547 }
548 }
549 return m_ranges.get();
550}
551
552const DWARFDebugRanges*
553SymbolFileDWARF::DebugRanges() const
554{
555 return m_ranges.get();
556}
557//
558//DWARFDebugPubnames*
559//SymbolFileDWARF::DebugPubnames()
560//{
561// if (m_pubnames.get() == NULL)
562// {
563// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
564// const DataExtractor &debug_pubnames_data = get_debug_pubnames_data();
565// if (debug_pubnames_data.GetByteSize() > 0)
566// {
567// // Pass false to indicate this is a pubnames section
568// m_pubnames.reset(new DWARFDebugPubnames());
569// if (m_pubnames.get())
570// {
571// // "m_pubnames->GeneratePubnames" is costly, but needed for global variables
572// m_pubnames->GeneratePubnames(this);
573//
574//#if 0
575// StreamFile s(stdout);
576// s.Printf (".debug_pubnames for %s/%s:\n",
577// m_obj_file->GetModule()->GetFileSpec().GetDirectory().AsCString(),
578// m_obj_file->GetModule()->GetFileSpec().GetFilename().AsCString());
579// m_pubnames->Dump (&s);
580//#endif
581// // "m_pubnames->Extract" is quicker, but the pubnames don't always contain what we need.
582// //m_pubnames->Extract(debug_pubnames_data);
583// }
584// }
585// }
586// return m_pubnames.get();
587//}
588//
589//const DWARFDebugPubnames*
590//SymbolFileDWARF::DebugPubnames() const
591//{
592// return m_pubnames.get();
593//}
594
595//DWARFDebugPubnames*
596//SymbolFileDWARF::DebugPubBaseTypes()
597//{
598// if (m_pubbasetypes.get() == NULL)
599// {
600// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
601// // Pass false to indicate this is a pubnames section
602// m_pubbasetypes.reset(new DWARFDebugPubnames());
603// if (m_pubbasetypes.get())
604// m_pubbasetypes->GeneratePubBaseTypes(this);
605// }
606// return m_pubbasetypes.get();
607//}
608//
609//const DWARFDebugPubnames*
610//SymbolFileDWARF::DebugPubBaseTypes() const
611//{
612// return m_pubbasetypes.get();
613//}
614//
615//const DWARFDebugPubnames*
616//SymbolFileDWARF::DebugPubtypes() const
617//{
618// return m_pubtypes.get();
619//}
620//
621//DWARFDebugPubnames*
622//SymbolFileDWARF::DebugPubtypes()
623//{
624// if (m_pubtypes.get() == NULL)
625// {
626// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
627// const DataExtractor &debug_pubtypes_data = get_debug_pubtypes_data();
628// if (debug_pubtypes_data.GetByteSize() > 0)
629// {
630// // Pass false to indicate this is a pubnames section
631// m_pubtypes.reset(new DWARFDebugPubnames());
632// if (m_pubtypes.get())
633// m_pubtypes->Extract(debug_pubtypes_data);
634// }
635// }
636// return m_pubtypes.get();
637//}
638//
639
640bool
641SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
642{
643 if (cu != NULL)
644 {
645 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly ();
646 if (cu_die)
647 {
648 const char * cu_die_name = cu_die->GetName(this, cu);
649 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
650 Language::Type language = (Language::Type)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
651 if (cu_die_name)
652 {
653 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
654 {
655 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), language));
656 }
657 else
658 {
659 std::string fullpath(cu_comp_dir);
660 if (*fullpath.rbegin() != '/')
661 fullpath += '/';
662 fullpath += cu_die_name;
663
664 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), language));
665 }
666
667 if (compile_unit_sp.get())
668 {
669 cu->SetUserData(compile_unit_sp.get());
670 return true;
671 }
672 }
673 }
674 }
675 return false;
676}
677
678#if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST
679
680void
681SymbolFileDWARF::ShrinkDSYM(CompileUnit *dc_cu, DWARFCompileUnit *dw_cu, const FileSpec& cu_fspec, const FileSpec& base_types_fspec, FSToDIES& fs_to_dies, const DWARFDebugInfoEntry *die)
682{
683 while (die != NULL)
684 {
685 dw_tag_t tag = die->Tag();
686
687 switch (tag)
688 {
689 case DW_TAG_base_type:
690 // Put all base types into the base type compile unit
691 fs_to_dies[base_types_fspec].Insert(die);
692 break;
693
694 default:
695 {
696 uint32_t decl_file = die->GetAttributeValueAsUnsigned(this, dw_cu, DW_AT_decl_file, 0);
697 if (decl_file)
698 {
699 fs_to_dies[dc_cu->GetSupportFiles().GetFileSpecAtIndex(decl_file)].Insert(die);
700 }
701 else
702 {
703 // add this to the current compile unit
704 fs_to_dies[cu_fspec].Insert(die);
705 }
706 }
707 break;
708 }
709
710 die = die->GetSibling();
711 }
712}
713
714
715
716#endif
717
718uint32_t
719SymbolFileDWARF::GetNumCompileUnits()
720{
721 DWARFDebugInfo* info = DebugInfo();
722 if (info)
723 {
724#if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST
725 uint32_t cu_idx;
726 FSToDIES fs_to_dies;
727
728 FileSpec base_type_fspec("DW_TAG_base_type");
729 const uint32_t num_comp_units = info->GetNumCompileUnits();
730
731 for (cu_idx=0; cu_idx < num_comp_units; ++cu_idx)
732 {
733 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
734 if (cu != NULL)
735 {
736 const DWARFDebugInfoEntry *cu_die = cu->DIE();
737 if (cu_die)
738 {
739 CompUnitSP dc_cu_sp;
740 ParseCompileUnit(cu, dc_cu_sp);
741 if (dc_cu_sp.get())
742 {
743 FileSpec cu_fspec(*dc_cu_sp.get());
744
745 ShrinkDSYM(dc_cu_sp.get(), cu, cu_fspec, base_type_fspec, fs_to_dies, cu->DIE()->GetFirstChild());
746 }
747 }
748 }
749 }
750
751 Stream strm(stdout);
752 FSToDIES::const_iterator pos, end = fs_to_dies.end();
753 for (pos = fs_to_dies.begin(); pos != end; ++pos)
754 {
755 strm << "\n\nMinimal Compile Unit: " << pos->first << ":\n";
756 const DWARFDIECollection& dies = pos->second;
757 dies.Dump(strm, NULL);
758 }
759 return num_comp_units;
760#else
761 return info->GetNumCompileUnits();
762#endif
763 }
764 return 0;
765}
766
767CompUnitSP
768SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
769{
770 CompUnitSP comp_unit;
771 DWARFDebugInfo* info = DebugInfo();
772 if (info)
773 {
774 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
775 if (cu != NULL)
776 {
777 // Our symbol vendor shouldn't be asking us to add a compile unit that
778 // has already been added to it, which this DWARF plug-in knows as it
779 // stores the lldb compile unit (CompileUnit) pointer in each
780 // DWARFCompileUnit object when it gets added.
781 assert(cu->GetUserData() == NULL);
782 ParseCompileUnit(cu, comp_unit);
783 }
784 }
785 return comp_unit;
786}
787
788static void
789AddRangesToBlock
790(
791 BlockList& blocks,
792 lldb::user_id_t blockID,
793 DWARFDebugRanges::RangeList& ranges,
794 addr_t block_base_addr
795)
796{
797 ranges.SubtractOffset (block_base_addr);
798 size_t range_idx = 0;
799 const DWARFDebugRanges::Range *debug_range;
800 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
801 {
802 blocks.AddRange(blockID, debug_range->begin_offset, debug_range->end_offset);
803 }
804}
805
806
807Function *
808SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
809{
810 DWARFDebugRanges::RangeList func_ranges;
811 const char *name = NULL;
812 const char *mangled = NULL;
813 int decl_file = 0;
814 int decl_line = 0;
815 int decl_column = 0;
816 int call_file = 0;
817 int call_line = 0;
818 int call_column = 0;
819 DWARFExpression frame_base;
820
821 // Parse the function prototype as a type that can then be added to concrete function instance
822 ParseTypes (sc, dwarf_cu, die, false, false);
823 //FixupTypes();
824
825 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
826 {
827 // Union of all ranges in the function DIE (if the function is discontiguous)
828 AddressRange func_range;
829 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
830 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
831 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
832 {
833 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
834 if (func_range.GetBaseAddress().IsValid())
835 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
836 }
837
838 if (func_range.GetBaseAddress().IsValid())
839 {
840 Mangled func_name;
841 if (mangled)
842 func_name.SetValue(mangled, true);
843 else if (name)
844 func_name.SetValue(name, false);
845
846 FunctionSP func_sp;
847 std::auto_ptr<Declaration> decl_ap;
848 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
849 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
850
851 Type *func_type = NULL;
852
853 if (die->GetUserData() != DIE_IS_BEING_PARSED)
854 func_type = (Type*)die->GetUserData();
855
856 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
857
858 func_range.GetBaseAddress().ResolveLinkedAddress();
859
860 func_sp.reset(new Function (sc.comp_unit,
861 die->GetOffset(), // UserID is the DIE offset
862 die->GetOffset(),
863 func_name,
864 func_type,
865 func_range)); // first address range
866
867 if (func_sp.get() != NULL)
868 {
869 func_sp->GetFrameBaseExpression() = frame_base;
870 sc.comp_unit->AddFunction(func_sp);
871 return func_sp.get();
872 }
873 }
874 }
875 return NULL;
876}
877
878size_t
879SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
880{
881 assert (sc.comp_unit);
882 size_t functions_added = 0;
883 const DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
884 if (dwarf_cu)
885 {
886 DWARFDIECollection function_dies;
887 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
888 size_t func_idx;
889 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
890 {
891 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
892 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
893 {
894 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
895 ++functions_added;
896 }
897 }
898 //FixupTypes();
899 }
900 return functions_added;
901}
902
903bool
904SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
905{
906 assert (sc.comp_unit);
907 DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
908 assert (cu);
909 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly();
910
911 if (cu_die)
912 {
913 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
914 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
915
916 // All file indexes in DWARF are one based and a file of index zero is
917 // supposed to be the compile unit itself.
918 support_files.Append (*sc.comp_unit);
919
920 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
921 }
922 return false;
923}
924
925struct ParseDWARFLineTableCallbackInfo
926{
927 LineTable* line_table;
928 const SectionList *section_list;
929 lldb::addr_t prev_sect_file_base_addr;
930 lldb::addr_t curr_sect_file_base_addr;
931 bool is_oso_for_debug_map;
932 bool prev_in_final_executable;
933 DWARFDebugLine::Row prev_row;
934 SectionSP prev_section_sp;
935 SectionSP curr_section_sp;
936};
937
938//----------------------------------------------------------------------
939// ParseStatementTableCallback
940//----------------------------------------------------------------------
941static void
942ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
943{
944 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
945 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
946 {
947 // Just started parsing the line table
948 }
949 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
950 {
951 // Done parsing line table, nothing to do for the cleanup
952 }
953 else
954 {
955 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
956 // We have a new row, lets append it
957
958 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
959 {
960 info->prev_section_sp = info->curr_section_sp;
961 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
962 // If this is an end sequence entry, then we subtract one from the
963 // address to make sure we get an address that is not the end of
964 // a section.
965 if (state.end_sequence && state.address != 0)
966 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
967 else
968 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
969
970 if (info->curr_section_sp.get())
971 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
972 else
973 info->curr_sect_file_base_addr = 0;
974 }
975 if (info->curr_section_sp.get())
976 {
977 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
978 // Check for the fancy section magic to determine if we
979
980 if (info->is_oso_for_debug_map)
981 {
982 // When this is a debug map object file that contains DWARF
983 // (referenced from an N_OSO debug map nlist entry) we will have
984 // a file address in the file range for our section from the
985 // original .o file, and a load address in the executable that
986 // contains the debug map.
987 //
988 // If the sections for the file range and load range are
989 // different, we have a remapped section for the function and
990 // this address is resolved. If they are the same, then the
991 // function for this address didn't make it into the final
992 // executable.
993 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
994
995 // If we are doing DWARF with debug map, then we need to carefully
996 // add each line table entry as there may be gaps as functions
997 // get moved around or removed.
998 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
999 {
1000 if (info->prev_in_final_executable)
1001 {
1002 bool terminate_previous_entry = false;
1003 if (!curr_in_final_executable)
1004 {
1005 // Check for the case where the previous line entry
1006 // in a function made it into the final executable,
1007 // yet the current line entry falls in a function
1008 // that didn't. The line table used to be contiguous
1009 // through this address range but now it isn't. We
1010 // need to terminate the previous line entry so
1011 // that we can reconstruct the line range correctly
1012 // for it and to keep the line table correct.
1013 terminate_previous_entry = true;
1014 }
1015 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
1016 {
1017 // Check for cases where the line entries used to be
1018 // contiguous address ranges, but now they aren't.
1019 // This can happen when order files specify the
1020 // ordering of the functions.
1021 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
1022 Section *curr_sect = info->curr_section_sp.get();
1023 Section *prev_sect = info->prev_section_sp.get();
1024 assert (curr_sect->GetLinkedSection());
1025 assert (prev_sect->GetLinkedSection());
1026 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
1027 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
1028 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
1029 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
1030 if (object_file_addr_delta != linked_file_addr_delta)
1031 terminate_previous_entry = true;
1032 }
1033
1034 if (terminate_previous_entry)
1035 {
1036 line_table->InsertLineEntry (info->prev_section_sp,
1037 state.address - info->prev_sect_file_base_addr,
1038 info->prev_row.line,
1039 info->prev_row.column,
1040 info->prev_row.file,
1041 false, // is_stmt
1042 false, // basic_block
1043 false, // state.prologue_end
1044 false, // state.epilogue_begin
1045 true); // end_sequence);
1046 }
1047 }
1048 }
1049
1050 if (curr_in_final_executable)
1051 {
1052 line_table->InsertLineEntry (info->curr_section_sp,
1053 curr_line_section_offset,
1054 state.line,
1055 state.column,
1056 state.file,
1057 state.is_stmt,
1058 state.basic_block,
1059 state.prologue_end,
1060 state.epilogue_begin,
1061 state.end_sequence);
1062 info->prev_section_sp = info->curr_section_sp;
1063 }
1064 else
1065 {
1066 // If the current address didn't make it into the final
1067 // executable, the current section will be the __text
1068 // segment in the .o file, so we need to clear this so
1069 // we can catch the next function that did make it into
1070 // the final executable.
1071 info->prev_section_sp.reset();
1072 info->curr_section_sp.reset();
1073 }
1074
1075 info->prev_in_final_executable = curr_in_final_executable;
1076 }
1077 else
1078 {
1079 // We are not in an object file that contains DWARF for an
1080 // N_OSO, this is just a normal DWARF file. The DWARF spec
1081 // guarantees that the addresses will be in increasing order
1082 // so, since we store line tables in file address order, we
1083 // can always just append the line entry without needing to
1084 // search for the correct insertion point (we don't need to
1085 // use LineEntry::InsertLineEntry()).
1086 line_table->AppendLineEntry (info->curr_section_sp,
1087 curr_line_section_offset,
1088 state.line,
1089 state.column,
1090 state.file,
1091 state.is_stmt,
1092 state.basic_block,
1093 state.prologue_end,
1094 state.epilogue_begin,
1095 state.end_sequence);
1096 }
1097 }
1098
1099 info->prev_row = state;
1100 }
1101}
1102
1103bool
1104SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1105{
1106 assert (sc.comp_unit);
1107 if (sc.comp_unit->GetLineTable() != NULL)
1108 return true;
1109
1110 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
1111 if (dwarf_cu)
1112 {
1113 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1114 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
1115 if (cu_line_offset != DW_INVALID_OFFSET)
1116 {
1117 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
1118 if (line_table_ap.get())
1119 {
1120 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_flags.IsSet (flagsDWARFIsOSOForDebugMap), false};
1121 uint32_t offset = cu_line_offset;
1122 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1123 sc.comp_unit->SetLineTable(line_table_ap.release());
1124 return true;
1125 }
1126 }
1127 }
1128 return false;
1129}
1130
1131size_t
1132SymbolFileDWARF::ParseFunctionBlocks
1133(
1134 const SymbolContext& sc,
1135 lldb::user_id_t parentBlockID,
1136 const DWARFCompileUnit* dwarf_cu,
1137 const DWARFDebugInfoEntry *die,
1138 addr_t subprogram_low_pc,
1139 bool parse_siblings,
1140 bool parse_children
1141)
1142{
1143 size_t blocks_added = 0;
1144 while (die != NULL)
1145 {
1146 dw_tag_t tag = die->Tag();
1147
1148 switch (tag)
1149 {
1150 case DW_TAG_subprogram:
1151 case DW_TAG_inlined_subroutine:
1152 case DW_TAG_lexical_block:
1153 {
1154 DWARFDebugRanges::RangeList ranges;
1155 const char *name = NULL;
1156 const char *mangled_name = NULL;
1157 BlockList& blocks = sc.function->GetBlocks(false);
1158
1159 lldb::user_id_t blockID = blocks.AddChild(parentBlockID, die->GetOffset());
1160 int decl_file = 0;
1161 int decl_line = 0;
1162 int decl_column = 0;
1163 int call_file = 0;
1164 int call_line = 0;
1165 int call_column = 0;
1166 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column))
1167 {
1168 if (tag == DW_TAG_subprogram)
1169 {
1170 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1171 subprogram_low_pc = ranges.LowestAddress(0);
1172 }
1173
1174 AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc);
1175
1176 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1177 {
1178 std::auto_ptr<Declaration> decl_ap;
1179 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
1180 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
1181
1182 std::auto_ptr<Declaration> call_ap;
1183 if (call_file != 0 || call_line != 0 || call_column != 0)
1184 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column));
1185
1186 blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get());
1187 }
1188
1189 ++blocks_added;
1190
1191 if (parse_children && die->HasChildren())
1192 {
1193 blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true);
1194 }
1195 }
1196 }
1197 break;
1198 default:
1199 break;
1200 }
1201
1202 if (parse_siblings)
1203 die = die->GetSibling();
1204 else
1205 die = NULL;
1206 }
1207 return blocks_added;
1208}
1209
1210size_t
1211SymbolFileDWARF::ParseChildMembers
1212(
1213 const SymbolContext& sc,
1214 TypeSP& type_sp,
1215 const DWARFCompileUnit* dwarf_cu,
1216 const DWARFDebugInfoEntry *parent_die,
1217 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1218 std::vector<int>& member_accessibilities,
1219 int& default_accessibility,
1220 bool &is_a_class
1221)
1222{
1223 if (parent_die == NULL)
1224 return 0;
1225
1226 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1227
1228 size_t count = 0;
1229 const DWARFDebugInfoEntry *die;
1230 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1231 {
1232 dw_tag_t tag = die->Tag();
1233
1234 switch (tag)
1235 {
1236 case DW_TAG_member:
1237 {
1238 DWARFDebugInfoEntry::Attributes attributes;
1239 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1240 if (num_attributes > 0)
1241 {
1242 Declaration decl;
1243 DWARFExpression location;
1244 const char *name = NULL;
1245 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1246 uint32_t accessibility = clang::AS_none;
1247 off_t member_offset = 0;
1248 size_t byte_size = 0;
1249 size_t bit_offset = 0;
1250 size_t bit_size = 0;
1251 uint32_t i;
1252 for (i=0; i<num_attributes; ++i)
1253 {
1254 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1255 DWARFFormValue form_value;
1256 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1257 {
1258 switch (attr)
1259 {
1260 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1261 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1262 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1263 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1264 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1265 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1266 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1267 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1268 case DW_AT_data_member_location:
1269 if (form_value.BlockData())
1270 {
1271 Value initialValue(0);
1272 Value memberOffset(0);
1273 const DataExtractor& debug_info_data = get_debug_info_data();
1274 uint32_t block_length = form_value.Unsigned();
1275 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1276 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1277 {
1278 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1279 }
1280 }
1281 break;
1282
1283 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility (form_value.Unsigned()); break;
1284 case DW_AT_declaration:
1285 case DW_AT_description:
1286 case DW_AT_mutable:
1287 case DW_AT_visibility:
1288 default:
1289 case DW_AT_sibling:
1290 break;
1291 }
1292 }
1293 }
1294
1295 Type *member_type = ResolveTypeUID(encoding_uid);
1296 assert(member_type);
1297 if (accessibility == clang::AS_none)
1298 accessibility = default_accessibility;
1299 member_accessibilities.push_back(accessibility);
1300
1301 type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size);
1302 }
1303 }
1304 break;
1305
1306 case DW_TAG_subprogram:
1307 {
1308 is_a_class = true;
1309 if (default_accessibility == clang::AS_none)
1310 default_accessibility = clang::AS_private;
1311 // TODO: implement DW_TAG_subprogram type parsing
1312// UserDefTypeChildInfo method_info(die->GetOffset());
1313//
1314// FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset()));
1315// if (func_sp.get() == NULL)
1316// ParseCompileUnitFunction(sc, dwarf_cu, die);
1317//
1318// method_info.SetEncodingTypeUID(die->GetOffset());
1319// struct_udt->AddMethod(method_info);
1320 }
1321 break;
1322
1323 case DW_TAG_inheritance:
1324 {
1325 is_a_class = true;
1326 if (default_accessibility == clang::AS_none)
1327 default_accessibility = clang::AS_private;
1328 // TODO: implement DW_TAG_inheritance type parsing
1329 DWARFDebugInfoEntry::Attributes attributes;
1330 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1331 if (num_attributes > 0)
1332 {
1333 Declaration decl;
1334 DWARFExpression location;
1335 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1336 uint32_t accessibility = default_accessibility;
1337 bool is_virtual = false;
1338 bool is_base_of_class = true;
1339 off_t member_offset = 0;
1340 uint32_t i;
1341 for (i=0; i<num_attributes; ++i)
1342 {
1343 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1344 DWARFFormValue form_value;
1345 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1346 {
1347 switch (attr)
1348 {
1349 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1350 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1351 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1352 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1353 case DW_AT_data_member_location:
1354 if (form_value.BlockData())
1355 {
1356 Value initialValue(0);
1357 Value memberOffset(0);
1358 const DataExtractor& debug_info_data = get_debug_info_data();
1359 uint32_t block_length = form_value.Unsigned();
1360 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1361 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1362 {
1363 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1364 }
1365 }
1366 break;
1367
1368 case DW_AT_accessibility:
1369 accessibility = DwarfToClangAccessibility(form_value.Unsigned());
1370 break;
1371
1372 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1373 default:
1374 case DW_AT_sibling:
1375 break;
1376 }
1377 }
1378 }
1379
1380 Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1381 assert(base_class_dctype);
1382 base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class));
1383 assert(base_classes.back());
1384 }
1385 }
1386 break;
1387
1388 default:
1389 break;
1390 }
1391 }
1392 return count;
1393}
1394
1395
1396clang::DeclContext*
1397SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1398{
1399 DWARFDebugInfo* debug_info = DebugInfo();
1400 if (debug_info)
1401 {
1402 DWARFCompileUnitSP cu_sp;
1403 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1404 if (die)
1405 return GetClangDeclContextForDIE (cu_sp.get(), die);
1406 }
1407 return NULL;
1408}
1409
1410Type*
1411SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid)
1412{
1413 DWARFDebugInfo* debug_info = DebugInfo();
1414 if (debug_info)
1415 {
1416 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL);
1417 if (type_die != NULL)
1418 {
1419 void *type = type_die->GetUserData();
1420 if (type == NULL)
1421 {
1422 DWARFCompileUnitSP cu_sp;
1423 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1424 if (die != NULL)
1425 {
1426 TypeSP owning_type_sp;
1427 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0));
1428 }
1429 type = type_die->GetUserData();
1430 }
1431 if (type != DIE_IS_BEING_PARSED)
1432 return (Type *)type;
1433 }
1434 }
1435 return NULL;
1436}
1437
1438CompileUnit*
1439SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx)
1440{
1441 // Check if the symbol vendor already knows about this compile unit?
1442 if (cu->GetUserData() == NULL)
1443 {
1444 // The symbol vendor doesn't know about this compile unit, we
1445 // need to parse and add it to the symbol vendor object.
1446 CompUnitSP dc_cu;
1447 ParseCompileUnit(cu, dc_cu);
1448 if (dc_cu.get())
1449 {
1450 // Figure out the compile unit index if we weren't given one
1451 if (cu_idx == UINT_MAX)
1452 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
1453
1454 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
1455 }
1456 }
1457 return (CompileUnit*)cu->GetUserData();
1458}
1459
1460bool
1461SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1462{
1463 sc.Clear();
1464 // Check if the symbol vendor already knows about this compile unit?
1465 sc.module_sp = m_obj_file->GetModule()->GetSP();
1466 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1467
1468 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1469 if (sc.function == NULL)
1470 sc.function = ParseCompileUnitFunction(sc, cu, func_die);
1471
1472 return sc.function != NULL;
1473}
1474
1475uint32_t
1476SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1477{
1478 Timer scoped_timer(__PRETTY_FUNCTION__,
1479 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1480 so_addr.GetSection(),
1481 so_addr.GetOffset(),
1482 resolve_scope);
1483 uint32_t resolved = 0;
1484 if (resolve_scope & ( eSymbolContextCompUnit |
1485 eSymbolContextFunction |
1486 eSymbolContextBlock |
1487 eSymbolContextLineEntry))
1488 {
1489 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1490
1491 DWARFDebugAranges* debug_aranges = DebugAranges();
1492 DWARFDebugInfo* debug_info = DebugInfo();
1493 if (debug_aranges)
1494 {
1495 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1496 if (cu_offset != DW_INVALID_OFFSET)
1497 {
1498 uint32_t cu_idx;
1499 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1500 if (cu)
1501 {
1502 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1503 assert(sc.comp_unit != NULL);
1504 resolved |= eSymbolContextCompUnit;
1505
1506 if (resolve_scope & eSymbolContextLineEntry)
1507 {
1508 LineTable *line_table = sc.comp_unit->GetLineTable();
1509 if (line_table == NULL)
1510 {
1511 if (ParseCompileUnitLineTable(sc))
1512 line_table = sc.comp_unit->GetLineTable();
1513 }
1514 if (line_table != NULL)
1515 {
1516 if (so_addr.IsLinkedAddress())
1517 {
1518 Address linked_addr (so_addr);
1519 linked_addr.ResolveLinkedAddress();
1520 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1521 {
1522 resolved |= eSymbolContextLineEntry;
1523 }
1524 }
1525 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1526 {
1527 resolved |= eSymbolContextLineEntry;
1528 }
1529 }
1530 }
1531
1532 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1533 {
1534 DWARFDebugInfoEntry *function_die = NULL;
1535 DWARFDebugInfoEntry *block_die = NULL;
1536 if (resolve_scope & eSymbolContextBlock)
1537 {
1538 cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1539 }
1540 else
1541 {
1542 cu->LookupAddress(file_vm_addr, &function_die, NULL);
1543 }
1544
1545 if (function_die != NULL)
1546 {
1547 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1548 if (sc.function == NULL)
1549 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1550 }
1551
1552 if (sc.function != NULL)
1553 {
1554 resolved |= eSymbolContextFunction;
1555
1556 if (resolve_scope & eSymbolContextBlock)
1557 {
1558 BlockList& blocks = sc.function->GetBlocks(true);
1559
1560 if (block_die != NULL)
1561 sc.block = blocks.GetBlockByID(block_die->GetOffset());
1562 else
1563 sc.block = blocks.GetBlockByID(function_die->GetOffset());
1564 if (sc.block)
1565 resolved |= eSymbolContextBlock;
1566 }
1567 }
1568 }
1569 }
1570 }
1571 }
1572 }
1573 return resolved;
1574}
1575
1576
1577
1578uint32_t
1579SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1580{
1581 const uint32_t prev_size = sc_list.GetSize();
1582 if (resolve_scope & eSymbolContextCompUnit)
1583 {
1584 DWARFDebugInfo* debug_info = DebugInfo();
1585 if (debug_info)
1586 {
1587 uint32_t cu_idx;
1588 DWARFCompileUnit* cu = NULL;
1589
1590 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1591 {
1592 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1593 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1594 if (check_inlines || file_spec_matches_cu_file_spec)
1595 {
1596 SymbolContext sc (m_obj_file->GetModule());
1597 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1598 assert(sc.comp_unit != NULL);
1599
1600 uint32_t file_idx = UINT32_MAX;
1601
1602 // If we are looking for inline functions only and we don't
1603 // find it in the support files, we are done.
1604 if (check_inlines)
1605 {
1606 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1607 if (file_idx == UINT32_MAX)
1608 continue;
1609 }
1610
1611 if (line != 0)
1612 {
1613 LineTable *line_table = sc.comp_unit->GetLineTable();
1614
1615 if (line_table != NULL && line != 0)
1616 {
1617 // We will have already looked up the file index if
1618 // we are searching for inline entries.
1619 if (!check_inlines)
1620 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1621
1622 if (file_idx != UINT32_MAX)
1623 {
1624 uint32_t found_line;
1625 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1626 found_line = sc.line_entry.line;
1627
1628 while (line_idx != UINT_MAX)
1629 {
1630 sc.function = NULL;
1631 sc.block = NULL;
1632 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1633 {
1634 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1635 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1636 {
1637 DWARFDebugInfoEntry *function_die = NULL;
1638 DWARFDebugInfoEntry *block_die = NULL;
1639 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1640
1641 if (function_die != NULL)
1642 {
1643 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1644 if (sc.function == NULL)
1645 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1646 }
1647
1648 if (sc.function != NULL)
1649 {
1650 BlockList& blocks = sc.function->GetBlocks(true);
1651
1652 if (block_die != NULL)
1653 sc.block = blocks.GetBlockByID(block_die->GetOffset());
1654 else
1655 sc.block = blocks.GetBlockByID(function_die->GetOffset());
1656 }
1657 }
1658 }
1659
1660 sc_list.Append(sc);
1661 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1662 }
1663 }
1664 }
1665 else if (file_spec_matches_cu_file_spec && !check_inlines)
1666 {
1667 // only append the context if we aren't looking for inline call sites
1668 // by file and line and if the file spec matches that of the compile unit
1669 sc_list.Append(sc);
1670 }
1671 }
1672 else if (file_spec_matches_cu_file_spec && !check_inlines)
1673 {
1674 // only append the context if we aren't looking for inline call sites
1675 // by file and line and if the file spec matches that of the compile unit
1676 sc_list.Append(sc);
1677 }
1678
1679 if (!check_inlines)
1680 break;
1681 }
1682 }
1683 }
1684 }
1685 return sc_list.GetSize() - prev_size;
1686}
1687
1688void
1689SymbolFileDWARF::Index ()
1690{
1691 if (m_indexed)
1692 return;
1693 m_indexed = true;
1694 Timer scoped_timer (__PRETTY_FUNCTION__,
1695 "SymbolFileDWARF::Index (%s)",
1696 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1697
1698 DWARFDebugInfo* debug_info = DebugInfo();
1699 if (debug_info)
1700 {
1701 uint32_t cu_idx = 0;
1702 const uint32_t num_compile_units = GetNumCompileUnits();
1703 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1704 {
1705 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1706
1707 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
1708
Greg Clayton0c5cd902010-06-28 21:30:43 +00001709 cu->Index (m_base_name_to_function_die,
1710 m_full_name_to_function_die,
1711 m_method_name_to_function_die,
1712 m_selector_name_to_function_die,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001713 m_name_to_global_die,
1714 m_name_to_type_die);
1715
1716 // Keep memory down by clearing DIEs if this generate function
1717 // caused them to be parsed
1718 if (clear_dies)
1719 cu->ClearDIEs (true);
1720 }
1721
Greg Clayton0c5cd902010-06-28 21:30:43 +00001722 m_base_name_to_function_die.Sort();
1723 m_full_name_to_function_die.Sort();
1724 m_method_name_to_function_die.Sort();
1725 m_selector_name_to_function_die.Sort();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001726 m_name_to_global_die.Sort();
1727 m_name_to_type_die.Sort();
1728 }
1729}
1730
1731uint32_t
1732SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1733{
1734 std::vector<dw_offset_t> die_offsets;
1735
1736 // If we aren't appending the results to this list, then clear the list
1737 if (!append)
1738 variables.Clear();
1739
1740 // Remember how many variables are in the list before we search in case
1741 // we are appending the results to a variable list.
1742 const uint32_t original_size = variables.GetSize();
1743
1744 // Index the DWARF if we haven't already
1745 if (!m_indexed)
1746 Index ();
1747
1748 const UniqueCStringMap<dw_offset_t>::Entry *entry;
1749
1750 for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString());
1751 entry != NULL;
1752 entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry))
1753 {
1754 DWARFCompileUnitSP cu_sp;
1755 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1756 DWARFCompileUnit* cu = cu_sp.get();
1757 if (die)
1758 {
1759 SymbolContext sc;
1760 sc.module_sp = m_obj_file->GetModule()->GetSP();
1761 assert (sc.module_sp);
1762
1763 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1764 assert(sc.comp_unit != NULL);
1765
1766 ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1767
1768 if (variables.GetSize() - original_size >= max_matches)
1769 break;
1770 }
1771 }
1772
1773 // Return the number of variable that were appended to the list
1774 return variables.GetSize() - original_size;
1775}
1776
1777uint32_t
1778SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1779{
1780 std::vector<dw_offset_t> die_offsets;
1781
1782 // If we aren't appending the results to this list, then clear the list
1783 if (!append)
1784 variables.Clear();
1785
1786 // Remember how many variables are in the list before we search in case
1787 // we are appending the results to a variable list.
1788 const uint32_t original_size = variables.GetSize();
1789
1790 // Index the DWARF if we haven't already
1791 if (!m_indexed)
1792 Index ();
1793
1794 // Create the pubnames information so we can quickly lookup external symbols by name
1795 const size_t num_entries = m_name_to_global_die.GetSize();
1796 for (size_t i=0; i<num_entries; i++)
1797 {
1798 if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i)))
1799 continue;
1800
1801 const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i);
1802
1803 DWARFCompileUnitSP cu_sp;
1804 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1805 DWARFCompileUnit* cu = cu_sp.get();
1806 if (die)
1807 {
1808 SymbolContext sc;
1809 sc.module_sp = m_obj_file->GetModule()->GetSP();
1810 assert (sc.module_sp);
1811
1812
1813 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1814 assert(sc.comp_unit != NULL);
1815
1816 ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1817
1818 if (variables.GetSize() - original_size >= max_matches)
1819 break;
1820 }
1821 }
1822
1823 // Return the number of variable that were appended to the list
1824 return variables.GetSize() - original_size;
1825}
1826
1827
Greg Clayton0c5cd902010-06-28 21:30:43 +00001828void
1829SymbolFileDWARF::FindFunctions
1830(
1831 const ConstString &name,
1832 UniqueCStringMap<dw_offset_t> &name_to_die,
1833 SymbolContextList& sc_list
1834)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001835{
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001836 const UniqueCStringMap<dw_offset_t>::Entry *entry;
1837
1838 SymbolContext sc;
Greg Clayton0c5cd902010-06-28 21:30:43 +00001839 for (entry = name_to_die.FindFirstValueForName (name.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001840 entry != NULL;
Greg Clayton0c5cd902010-06-28 21:30:43 +00001841 entry = name_to_die.FindNextValueForName (name.AsCString(), entry))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001842 {
1843 DWARFCompileUnitSP cu_sp;
1844 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1845 if (die)
1846 {
1847 if (GetFunction (cu_sp.get(), die, sc))
1848 {
1849 // We found the function, so we should find the line table
1850 // and line table entry as well
1851 LineTable *line_table = sc.comp_unit->GetLineTable();
1852 if (line_table == NULL)
1853 {
1854 if (ParseCompileUnitLineTable(sc))
1855 line_table = sc.comp_unit->GetLineTable();
1856 }
1857 if (line_table != NULL)
1858 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1859
1860 sc_list.Append(sc);
1861 }
1862 }
1863 }
1864
Greg Clayton0c5cd902010-06-28 21:30:43 +00001865}
1866
1867uint32_t
1868SymbolFileDWARF::FindFunctions
1869(
1870 const ConstString &name,
1871 uint32_t name_type_mask,
1872 bool append,
1873 SymbolContextList& sc_list
1874)
1875{
1876 Timer scoped_timer (__PRETTY_FUNCTION__,
1877 "SymbolFileDWARF::FindFunctions (name = '%s')",
1878 name.AsCString());
1879
1880 std::vector<dw_offset_t> die_offsets;
1881
1882 // If we aren't appending the results to this list, then clear the list
1883 if (!append)
1884 sc_list.Clear();
1885
1886 // Remember how many sc_list are in the list before we search in case
1887 // we are appending the results to a variable list.
1888 uint32_t original_size = sc_list.GetSize();
1889
1890 // Index the DWARF if we haven't already
1891 if (!m_indexed)
1892 Index ();
1893
1894 if (name_type_mask & eFunctionNameTypeBase)
1895 FindFunctions (name, m_base_name_to_function_die, sc_list);
1896
1897 if (name_type_mask & eFunctionNameTypeFull)
1898 FindFunctions (name, m_full_name_to_function_die, sc_list);
1899
1900 if (name_type_mask & eFunctionNameTypeMethod)
1901 FindFunctions (name, m_method_name_to_function_die, sc_list);
1902
1903 if (name_type_mask & eFunctionNameTypeSelector)
1904 FindFunctions (name, m_selector_name_to_function_die, sc_list);
1905
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001906 // Return the number of variable that were appended to the list
1907 return sc_list.GetSize() - original_size;
1908}
1909
1910
1911uint32_t
1912SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
1913{
1914 Timer scoped_timer (__PRETTY_FUNCTION__,
1915 "SymbolFileDWARF::FindFunctions (regex = '%s')",
1916 regex.GetText());
1917
1918 std::vector<dw_offset_t> die_offsets;
1919
1920 // If we aren't appending the results to this list, then clear the list
1921 if (!append)
1922 sc_list.Clear();
1923
1924 // Remember how many sc_list are in the list before we search in case
1925 // we are appending the results to a variable list.
1926 uint32_t original_size = sc_list.GetSize();
1927
1928 // Index the DWARF if we haven't already
1929 if (!m_indexed)
1930 Index ();
1931
1932 // Create the pubnames information so we can quickly lookup external symbols by name
1933 // Create the pubnames information so we can quickly lookup external symbols by name
Greg Clayton0c5cd902010-06-28 21:30:43 +00001934 const size_t num_entries = m_full_name_to_function_die.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001935 SymbolContext sc;
1936 for (size_t i=0; i<num_entries; i++)
1937 {
Greg Clayton0c5cd902010-06-28 21:30:43 +00001938 if (!regex.Execute(m_full_name_to_function_die.GetCStringAtIndex (i)))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001939 continue;
1940
Greg Clayton0c5cd902010-06-28 21:30:43 +00001941 const dw_offset_t die_offset = *m_full_name_to_function_die.GetValueAtIndex (i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001942
1943 DWARFCompileUnitSP cu_sp;
1944 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1945 if (die)
1946 {
1947 if (GetFunction (cu_sp.get(), die, sc))
1948 {
1949 // We found the function, so we should find the line table
1950 // and line table entry as well
1951 LineTable *line_table = sc.comp_unit->GetLineTable();
1952 if (line_table == NULL)
1953 {
1954 if (ParseCompileUnitLineTable(sc))
1955 line_table = sc.comp_unit->GetLineTable();
1956 }
1957 if (line_table != NULL)
1958 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1959
1960
1961 sc_list.Append(sc);
1962 }
1963 }
1964 }
1965
1966 // Return the number of variable that were appended to the list
1967 return sc_list.GetSize() - original_size;
1968}
1969
1970#if 0
1971uint32_t
1972SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
1973{
1974 // If we aren't appending the results to this list, then clear the list
1975 if (!append)
1976 types.Clear();
1977
1978 // Create the pubnames information so we can quickly lookup external symbols by name
1979 DWARFDebugPubnames* pubtypes = DebugPubtypes();
1980 if (pubtypes)
1981 {
1982 std::vector<dw_offset_t> die_offsets;
1983 if (!pubtypes->Find(name.AsCString(), false, die_offsets))
1984 {
1985 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
1986 if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets))
1987 return 0;
1988 }
1989 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
1990 }
1991 return 0;
1992}
1993
1994
1995uint32_t
1996SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
1997{
1998 // If we aren't appending the results to this list, then clear the list
1999 if (!append)
2000 types.Clear();
2001
2002 // Create the pubnames information so we can quickly lookup external symbols by name
2003 DWARFDebugPubnames* pubtypes = DebugPubtypes();
2004 if (pubtypes)
2005 {
2006 std::vector<dw_offset_t> die_offsets;
2007 if (!pubtypes->Find(regex, die_offsets))
2008 {
2009 DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
2010 if (pub_base_types && !pub_base_types->Find(regex, die_offsets))
2011 return 0;
2012 }
2013
2014 return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
2015 }
2016
2017 return 0;
2018}
2019
2020
2021
2022uint32_t
2023SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
2024{
2025 // Remember how many sc_list are in the list before we search in case
2026 // we are appending the results to a variable list.
2027 uint32_t original_size = types.Size();
2028
2029 const uint32_t num_die_offsets = die_offsets.size();
2030 // Parse all of the types we found from the pubtypes matches
2031 uint32_t i;
2032 uint32_t num_matches = 0;
2033 for (i = 0; i < num_die_offsets; ++i)
2034 {
2035 dw_offset_t die_offset = die_offsets[i];
2036 DWARFCompileUnitSP cu_sp;
2037 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2038
2039 assert(die != NULL);
2040
2041 bool get_type_for_die = true;
2042 if (encoding)
2043 {
2044 // Check if this type has already been uniqued and registers with the module?
2045 Type* type = (Type*)die->GetUserData();
2046 if (type != NULL && type != DIE_IS_BEING_PARSED)
2047 {
2048 get_type_for_die = type->GetEncoding() == encoding;
2049 }
2050 else
2051 {
2052 dw_tag_t tag = die->Tag();
2053 switch (encoding)
2054 {
2055 case Type::address:
2056 case Type::boolean:
2057 case Type::complex_float:
2058 case Type::float_type:
2059 case Type::signed_int:
2060 case Type::signed_char:
2061 case Type::unsigned_int:
2062 case Type::unsigned_char:
2063 case Type::imaginary_float:
2064 case Type::packed_decimal:
2065 case Type::numeric_string:
2066 case Type::edited_string:
2067 case Type::signed_fixed:
2068 case Type::unsigned_fixed:
2069 case Type::decimal_float:
2070 if (tag != DW_TAG_base_type)
2071 get_type_for_die = false;
2072 else
2073 {
2074 if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding)
2075 get_type_for_die = false;
2076 }
2077 break;
2078
2079 case Type::indirect_const: get_type_for_die = tag == DW_TAG_const_type; break;
2080 case Type::indirect_restrict: get_type_for_die = tag == DW_TAG_restrict_type; break;
2081 case Type::indirect_volatile: get_type_for_die = tag == DW_TAG_volatile_type; break;
2082 case Type::indirect_typedef: get_type_for_die = tag == DW_TAG_typedef; break;
2083 case Type::indirect_pointer: get_type_for_die = tag == DW_TAG_pointer_type; break;
2084 case Type::indirect_reference: get_type_for_die = tag == DW_TAG_reference_type; break;
2085
2086 case Type::user_defined_type:
2087 switch (tag)
2088 {
2089 case DW_TAG_array_type:
2090 get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid);
2091 break;
2092
2093 case DW_TAG_structure_type:
2094 case DW_TAG_union_type:
2095 case DW_TAG_class_type:
2096 get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid);
2097 break;
2098
2099 case DW_TAG_enumeration_type:
2100 get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid);
2101 break;
2102
2103 case DW_TAG_subprogram:
2104 case DW_TAG_subroutine_type:
2105 get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid);
2106 break;
2107 }
2108 }
2109 }
2110 }
2111
2112 if (get_type_for_die)
2113 {
2114 TypeSP owning_type_sp;
2115 TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0));
2116
2117 if (type_sp.get())
2118 {
2119 // See if we are filtering results based on encoding?
2120 bool add_type = (encoding == Type::invalid);
2121 if (!add_type)
2122 {
2123 // We are filtering base on encoding, so lets check the resulting type encoding
2124 add_type = (encoding == type_sp->GetEncoding());
2125 if (add_type)
2126 {
2127 // The type encoding matches, if this is a user defined type, lets
2128 // make sure the exact user define type uid matches if one was provided
2129 if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID)
2130 {
2131 UserDefType* udt = type_sp->GetUserDefinedType().get();
2132 if (udt)
2133 add_type = udt->UserDefinedTypeUID() == udt_uid;
2134 }
2135 }
2136 }
2137 // Add the type to our list as long as everything matched
2138 if (add_type)
2139 {
2140 types.InsertUnique(type_sp);
2141 if (++num_matches >= max_matches)
2142 break;
2143 }
2144 }
2145 }
2146 }
2147
2148 // Return the number of variable that were appended to the list
2149 return types.Size() - original_size;
2150}
2151
2152#endif
2153
2154
2155size_t
2156SymbolFileDWARF::ParseChildParameters
2157(
2158 const SymbolContext& sc,
2159 TypeSP& type_sp,
2160 const DWARFCompileUnit* dwarf_cu,
2161 const DWARFDebugInfoEntry *parent_die,
2162 TypeList* type_list,
2163 std::vector<void *>& function_param_types,
2164 std::vector<clang::ParmVarDecl*>& function_param_decls
2165)
2166{
2167 if (parent_die == NULL)
2168 return 0;
2169
2170 size_t count = 0;
2171 const DWARFDebugInfoEntry *die;
2172 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2173 {
2174 dw_tag_t tag = die->Tag();
2175 switch (tag)
2176 {
2177 case DW_TAG_formal_parameter:
2178 {
2179 DWARFDebugInfoEntry::Attributes attributes;
2180 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2181 if (num_attributes > 0)
2182 {
2183 const char *name = NULL;
2184 Declaration decl;
2185 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
2186 // one of None, Auto, Register, Extern, Static, PrivateExtern
2187
2188 clang::VarDecl::StorageClass storage = clang::VarDecl::None;
2189 uint32_t i;
2190 for (i=0; i<num_attributes; ++i)
2191 {
2192 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2193 DWARFFormValue form_value;
2194 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2195 {
2196 switch (attr)
2197 {
2198 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2199 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2200 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2201 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2202 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
2203 case DW_AT_location:
2204 // if (form_value.BlockData())
2205 // {
2206 // const DataExtractor& debug_info_data = debug_info();
2207 // uint32_t block_length = form_value.Unsigned();
2208 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2209 // }
2210 // else
2211 // {
2212 // }
2213 // break;
2214 case DW_AT_artificial:
2215 case DW_AT_const_value:
2216 case DW_AT_default_value:
2217 case DW_AT_description:
2218 case DW_AT_endianity:
2219 case DW_AT_is_optional:
2220 case DW_AT_segment:
2221 case DW_AT_variable_parameter:
2222 default:
2223 case DW_AT_abstract_origin:
2224 case DW_AT_sibling:
2225 break;
2226 }
2227 }
2228 }
2229 Type *dc_type = ResolveTypeUID(param_type_die_offset);
2230 if (dc_type)
2231 {
2232 function_param_types.push_back (dc_type->GetOpaqueClangQualType());
2233
2234 clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage);
2235 assert(param_var_decl);
2236 function_param_decls.push_back(param_var_decl);
2237 }
2238 }
2239 }
2240 break;
2241
2242 default:
2243 break;
2244 }
2245 }
2246 return count;
2247}
2248
2249size_t
2250SymbolFileDWARF::ParseChildEnumerators
2251(
2252 const SymbolContext& sc,
2253 TypeSP& type_sp,
2254 void * enumerator_qual_type,
2255 uint32_t enumerator_byte_size,
2256 const DWARFCompileUnit* dwarf_cu,
2257 const DWARFDebugInfoEntry *parent_die
2258)
2259{
2260 if (parent_die == NULL)
2261 return 0;
2262
2263 size_t enumerators_added = 0;
2264 const DWARFDebugInfoEntry *die;
2265 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2266 {
2267 const dw_tag_t tag = die->Tag();
2268 if (tag == DW_TAG_enumerator)
2269 {
2270 DWARFDebugInfoEntry::Attributes attributes;
2271 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2272 if (num_child_attributes > 0)
2273 {
2274 const char *name = NULL;
2275 bool got_value = false;
2276 int64_t enum_value = 0;
2277 Declaration decl;
2278
2279 uint32_t i;
2280 for (i=0; i<num_child_attributes; ++i)
2281 {
2282 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2283 DWARFFormValue form_value;
2284 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2285 {
2286 switch (attr)
2287 {
2288 case DW_AT_const_value:
2289 got_value = true;
2290 enum_value = form_value.Unsigned();
2291 break;
2292
2293 case DW_AT_name:
2294 name = form_value.AsCString(&get_debug_str_data());
2295 break;
2296
2297 case DW_AT_description:
2298 default:
2299 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2300 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2301 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2302 case DW_AT_sibling:
2303 break;
2304 }
2305 }
2306 }
2307
2308 if (name && name[0] && got_value)
2309 {
2310 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2311 type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8);
2312 ++enumerators_added;
2313 }
2314 }
2315 }
2316 }
2317 return enumerators_added;
2318}
2319
2320void
2321SymbolFileDWARF::ParseChildArrayInfo
2322(
2323 const SymbolContext& sc,
2324 const DWARFCompileUnit* dwarf_cu,
2325 const DWARFDebugInfoEntry *parent_die,
2326 int64_t& first_index,
2327 std::vector<uint64_t>& element_orders,
2328 uint32_t& byte_stride,
2329 uint32_t& bit_stride
2330)
2331{
2332 if (parent_die == NULL)
2333 return;
2334
2335 const DWARFDebugInfoEntry *die;
2336 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2337 {
2338 const dw_tag_t tag = die->Tag();
2339 switch (tag)
2340 {
2341 case DW_TAG_enumerator:
2342 {
2343 DWARFDebugInfoEntry::Attributes attributes;
2344 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2345 if (num_child_attributes > 0)
2346 {
2347 const char *name = NULL;
2348 bool got_value = false;
2349 int64_t enum_value = 0;
2350
2351 uint32_t i;
2352 for (i=0; i<num_child_attributes; ++i)
2353 {
2354 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2355 DWARFFormValue form_value;
2356 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2357 {
2358 switch (attr)
2359 {
2360 case DW_AT_const_value:
2361 got_value = true;
2362 enum_value = form_value.Unsigned();
2363 break;
2364
2365 case DW_AT_name:
2366 name = form_value.AsCString(&get_debug_str_data());
2367 break;
2368
2369 case DW_AT_description:
2370 default:
2371 case DW_AT_decl_file:
2372 case DW_AT_decl_line:
2373 case DW_AT_decl_column:
2374 case DW_AT_sibling:
2375 break;
2376 }
2377 }
2378 }
2379 }
2380 }
2381 break;
2382
2383 case DW_TAG_subrange_type:
2384 {
2385 DWARFDebugInfoEntry::Attributes attributes;
2386 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2387 if (num_child_attributes > 0)
2388 {
2389 const char *name = NULL;
2390 bool got_value = false;
2391 uint64_t byte_size = 0;
2392 int64_t enum_value = 0;
2393 uint64_t num_elements = 0;
2394 uint64_t lower_bound = 0;
2395 uint64_t upper_bound = 0;
2396 uint32_t i;
2397 for (i=0; i<num_child_attributes; ++i)
2398 {
2399 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2400 DWARFFormValue form_value;
2401 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2402 {
2403 switch (attr)
2404 {
2405 case DW_AT_const_value:
2406 got_value = true;
2407 enum_value = form_value.Unsigned();
2408 break;
2409
2410 case DW_AT_name:
2411 name = form_value.AsCString(&get_debug_str_data());
2412 break;
2413
2414 case DW_AT_count:
2415 num_elements = form_value.Unsigned();
2416 break;
2417
2418 case DW_AT_bit_stride:
2419 bit_stride = form_value.Unsigned();
2420 break;
2421
2422 case DW_AT_byte_stride:
2423 byte_stride = form_value.Unsigned();
2424 break;
2425
2426 case DW_AT_byte_size:
2427 byte_size = form_value.Unsigned();
2428 break;
2429
2430 case DW_AT_lower_bound:
2431 lower_bound = form_value.Unsigned();
2432 break;
2433
2434 case DW_AT_upper_bound:
2435 upper_bound = form_value.Unsigned();
2436 break;
2437
2438 default:
2439 //printf("0x%8.8x: %-30s skipping attribute at 0x%8.8x: %s\n", die->GetOffset(), DW_TAG_value_to_name(tag), attributes.die_offsets[i], DW_AT_value_to_name(attr)); // remove this, debug only
2440
2441 case DW_AT_abstract_origin:
2442 case DW_AT_accessibility:
2443 case DW_AT_allocated:
2444 case DW_AT_associated:
2445 case DW_AT_data_location:
2446 case DW_AT_declaration:
2447 case DW_AT_description:
2448 case DW_AT_sibling:
2449 case DW_AT_threads_scaled:
2450 case DW_AT_type:
2451 case DW_AT_visibility:
2452 break;
2453 }
2454 }
2455 }
2456
2457 if (upper_bound > lower_bound)
2458 num_elements = upper_bound - lower_bound + 1;
2459
2460 if (num_elements > 0)
2461 element_orders.push_back (num_elements);
2462 }
2463 }
2464 break;
2465 }
2466 }
2467}
2468
2469Type*
2470SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe)
2471{
2472 if (type_die_offset != DW_INVALID_OFFSET)
2473 {
2474 DWARFCompileUnitSP cu_sp;
2475 const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp);
2476 assert(type_die != NULL);
2477 GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx);
2478 // Return the uniqued type if there is one
2479 Type* type = (Type*)type_die->GetUserData();
2480 if (type == DIE_IS_BEING_PARSED && safe)
2481 return NULL;
2482 return type;
2483 }
2484 return NULL;
2485}
2486
2487TypeSP
2488SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx)
2489{
2490 TypeSP type_sp;
2491 if (die != NULL)
2492 {
2493 assert(cu != NULL);
2494 Type *type_ptr = (Type *)die->GetUserData();
2495 if (type_ptr == NULL)
2496 {
2497 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
2498 bool type_is_new = false;
2499 type_sp = ParseType(sc, cu, die, type_is_new);
2500 type_ptr = (Type *)die->GetUserData();
2501 if (owning_type_sp.get() == NULL)
2502 owning_type_sp = type_sp;
2503 }
2504 else if (type_ptr != DIE_IS_BEING_PARSED)
2505 {
2506 // Grab the existing type from the master types lists
2507 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
2508 }
2509
2510 }
2511 return type_sp;
2512}
2513
2514clang::DeclContext *
2515SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2516{
2517 if (die_offset != DW_INVALID_OFFSET)
2518 {
2519 DWARFCompileUnitSP cu_sp;
2520 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2521 return GetClangDeclContextForDIE (cu_sp.get(), die);
2522 }
2523 return NULL;
2524}
2525
2526
2527
2528clang::DeclContext *
2529SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
2530{
2531 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2532 if (pos != m_die_to_decl_ctx.end())
2533 return pos->second;
2534
2535 while (die != NULL)
2536 {
2537 switch (die->Tag())
2538 {
2539 case DW_TAG_namespace:
2540 {
2541 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
2542 if (namespace_name)
2543 {
2544 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2545 assert(type_list);
2546 Declaration decl; // TODO: fill in the decl object
2547 clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
2548 if (namespace_decl)
2549 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2550 return namespace_decl;
2551 }
2552 }
2553 break;
2554
2555 default:
2556 break;
2557 }
2558 clang::DeclContext *decl_ctx;
2559 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
2560 if (decl_ctx)
2561 return decl_ctx;
2562
2563 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2564 if (decl_ctx)
2565 return decl_ctx;
2566
2567 die = die->GetParent();
2568 }
2569 return NULL;
2570}
2571
2572TypeSP
2573SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new)
2574{
2575 TypeSP type_sp;
2576
2577 uint32_t accessibility = clang::AS_none;
2578 if (die != NULL)
2579 {
2580 dw_tag_t tag = die->Tag();
2581 if (die->GetUserData() == NULL)
2582 {
2583 type_is_new = true;
2584
2585 bool is_forward_declaration = false;
2586 DWARFDebugInfoEntry::Attributes attributes;
2587 const char *type_name_cstr = NULL;
2588 ConstString type_name_dbstr;
2589 Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID;
2590 void *clang_type = NULL;
2591
2592 TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2593 dw_attr_t attr;
2594
2595 switch (tag)
2596 {
2597 case DW_TAG_base_type:
2598 case DW_TAG_pointer_type:
2599 case DW_TAG_reference_type:
2600 case DW_TAG_typedef:
2601 case DW_TAG_const_type:
2602 case DW_TAG_restrict_type:
2603 case DW_TAG_volatile_type:
2604 {
2605 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2606 // Set a bit that lets us know that we are currently parsing this
2607 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2608
2609 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2610 Declaration decl;
2611 uint32_t encoding = 0;
2612 size_t byte_size = 0;
2613 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2614
2615 if (num_attributes > 0)
2616 {
2617 uint32_t i;
2618 for (i=0; i<num_attributes; ++i)
2619 {
2620 attr = attributes.AttributeAtIndex(i);
2621 DWARFFormValue form_value;
2622 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2623 {
2624 switch (attr)
2625 {
2626 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2627 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2628 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2629 case DW_AT_name:
2630 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2631 type_name_dbstr.SetCString(type_name_cstr);
2632 break;
2633 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2634 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2635 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2636 default:
2637 case DW_AT_sibling:
2638 break;
2639 }
2640 }
2641 }
2642 }
2643
2644 switch (tag)
2645 {
2646 default:
2647 case DW_TAG_base_type:
2648 clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8);
2649 break;
2650
2651 case DW_TAG_pointer_type:
2652 // The encoding_uid will be embedded into the
2653 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2654 encoding_uid_type = Type::ePointerToTypeWithUID;
2655 break;
2656
2657 case DW_TAG_reference_type:
2658 // The encoding_uid will be embedded into the
2659 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2660 encoding_uid_type = Type::eLValueReferenceToTypeWithUID;
2661 break;
2662
2663 case DW_TAG_typedef:
2664 // The encoding_uid will be embedded into the
2665 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2666 encoding_uid_type = Type::eTypedefToTypeWithUID;
2667 break;
2668
2669 case DW_TAG_const_type:
2670 // The encoding_uid will be embedded into the
2671 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2672 encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type);
2673 break;
2674
2675 case DW_TAG_restrict_type:
2676 // The encoding_uid will be embedded into the
2677 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2678 encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type);
2679 break;
2680
2681 case DW_TAG_volatile_type:
2682 // The encoding_uid will be embedded into the
2683 // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2684 encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type);
2685 break;
2686 }
2687
2688 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type));
2689
2690 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2691
2692
2693// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2694// if (encoding_type != NULL)
2695// {
2696// if (encoding_type != DIE_IS_BEING_PARSED)
2697// type_sp->SetEncodingType(encoding_type);
2698// else
2699// m_indirect_fixups.push_back(type_sp.get());
2700// }
2701 }
2702 break;
2703
2704 case DW_TAG_structure_type:
2705 case DW_TAG_union_type:
2706 case DW_TAG_class_type:
2707 {
2708 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2709 // Set a bit that lets us know that we are currently parsing this
2710 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2711
2712 size_t byte_size = 0;
2713 //bool struct_is_class = false;
2714 Declaration decl;
2715 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2716 if (num_attributes > 0)
2717 {
2718 uint32_t i;
2719 for (i=0; i<num_attributes; ++i)
2720 {
2721 attr = attributes.AttributeAtIndex(i);
2722 DWARFFormValue form_value;
2723 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2724 {
2725 switch (attr)
2726 {
2727 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2728 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2729 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2730 case DW_AT_name:
2731 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2732 type_name_dbstr.SetCString(type_name_cstr);
2733 break;
2734 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2735 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; break;
2736 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2737 case DW_AT_allocated:
2738 case DW_AT_associated:
2739 case DW_AT_data_location:
2740 case DW_AT_description:
2741 case DW_AT_start_scope:
2742 case DW_AT_visibility:
2743 default:
2744 case DW_AT_sibling:
2745 break;
2746 }
2747 }
2748 }
2749 }
2750
2751 int tag_decl_kind = -1;
2752 int default_accessibility = clang::AS_none;
2753 if (tag == DW_TAG_structure_type)
2754 {
2755 tag_decl_kind = clang::TTK_Struct;
2756 default_accessibility = clang::AS_public;
2757 }
2758 else if (tag == DW_TAG_union_type)
2759 {
2760 tag_decl_kind = clang::TTK_Union;
2761 default_accessibility = clang::AS_public;
2762 }
2763 else if (tag == DW_TAG_class_type)
2764 {
2765 tag_decl_kind = clang::TTK_Class;
2766 default_accessibility = clang::AS_private;
2767 }
2768
2769 assert (tag_decl_kind != -1);
2770 clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die));
2771
2772 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2773 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
2774
2775 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2776
2777// assert(type_sp.get());
2778// if (accessibility)
2779// type_sp->SetAccess(accessibility);
2780//
2781 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2782 if (die->HasChildren())
2783 {
2784 std::vector<clang::CXXBaseSpecifier *> base_classes;
2785 std::vector<int> member_accessibilities;
2786 bool is_a_class = false;
2787 ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class);
2788 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2789 // need to tell the clang type it is actually a class.
2790 if (is_a_class && tag_decl_kind != clang::TTK_Class)
2791 type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
2792
2793 // Since DW_TAG_structure_type gets used for both classes
2794 // and structures, we may need to set any DW_TAG_member
2795 // fields to have a "private" access if none was specified.
2796 // When we parsed the child members we tracked that actual
2797 // accessibility value for each DW_TAG_member in the
2798 // "member_accessibilities" array. If the value for the
2799 // member is zero, then it was set to the "default_accessibility"
2800 // which for structs was "public". Below we correct this
2801 // by setting any fields to "private" that weren't correctly
2802 // set.
2803 if (is_a_class && !member_accessibilities.empty())
2804 {
2805 // This is a class and all members that didn't have
2806 // their access specified are private.
Greg Clayton471b31c2010-07-20 22:52:08 +00002807 type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, clang::AS_private, &member_accessibilities.front(), member_accessibilities.size());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002808 }
2809
2810 if (!base_classes.empty())
2811 {
Greg Clayton471b31c2010-07-20 22:52:08 +00002812 type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, &base_classes.front(), base_classes.size());
2813
2814 // Clang will copy each CXXBaseSpecifier in "base_classes"
2815 // so we have to free them all.
2816 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), base_classes.size());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002817 }
Greg Clayton0b42ac32010-07-02 01:29:13 +00002818
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002819 }
2820 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2821 }
2822 break;
2823
2824 case DW_TAG_enumeration_type:
2825 {
2826 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2827 // Set a bit that lets us know that we are currently parsing this
2828 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2829
2830 size_t byte_size = 0;
2831 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2832 Declaration decl;
2833
2834 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2835 if (num_attributes > 0)
2836 {
2837 uint32_t i;
2838
2839 for (i=0; i<num_attributes; ++i)
2840 {
2841 attr = attributes.AttributeAtIndex(i);
2842 DWARFFormValue form_value;
2843 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2844 {
2845 switch (attr)
2846 {
2847 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2848 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2849 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2850 case DW_AT_name:
2851 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2852 type_name_dbstr.SetCString(type_name_cstr);
2853 break;
2854 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2855 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2856 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
2857 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2858 case DW_AT_allocated:
2859 case DW_AT_associated:
2860 case DW_AT_bit_stride:
2861 case DW_AT_byte_stride:
2862 case DW_AT_data_location:
2863 case DW_AT_description:
2864 case DW_AT_start_scope:
2865 case DW_AT_visibility:
2866 case DW_AT_specification:
2867 case DW_AT_abstract_origin:
2868 case DW_AT_sibling:
2869 break;
2870 }
2871 }
2872 }
2873
2874 clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr);
2875 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2876 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type));
2877
2878 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2879
2880 if (die->HasChildren())
2881 {
2882 type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2883 void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
2884 ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die);
2885 type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2886 }
2887 }
2888 }
2889 break;
2890
2891 case DW_TAG_subprogram:
2892 case DW_TAG_subroutine_type:
2893 {
2894 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2895 // Set a bit that lets us know that we are currently parsing this
2896 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2897
2898 const char *mangled = NULL;
2899 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
2900 Declaration decl;
2901 bool isVariadic = false;
2902 bool is_inline = false;
2903 unsigned type_quals = 0;
2904 clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern
2905
2906
2907 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2908 if (num_attributes > 0)
2909 {
2910 uint32_t i;
2911 for (i=0; i<num_attributes; ++i)
2912 {
2913 attr = attributes.AttributeAtIndex(i);
2914 DWARFFormValue form_value;
2915 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2916 {
2917 switch (attr)
2918 {
2919 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2920 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2921 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2922 case DW_AT_name:
2923 type_name_cstr = form_value.AsCString(&get_debug_str_data());
2924 type_name_dbstr.SetCString(type_name_cstr);
2925 break;
2926
2927 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
2928 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
2929 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
2930 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2931 case DW_AT_external:
2932 if (form_value.Unsigned())
2933 {
2934 if (storage == clang::FunctionDecl::None)
2935 storage = clang::FunctionDecl::Extern;
2936 else
2937 storage = clang::FunctionDecl::PrivateExtern;
2938 }
2939 break;
2940 case DW_AT_inline:
2941 is_inline = form_value.Unsigned() != 0;
2942 break;
2943
2944 case DW_AT_allocated:
2945 case DW_AT_associated:
2946 case DW_AT_address_class:
2947 case DW_AT_artificial:
2948 case DW_AT_calling_convention:
2949 case DW_AT_data_location:
2950 case DW_AT_elemental:
2951 case DW_AT_entry_pc:
2952 case DW_AT_explicit:
2953 case DW_AT_frame_base:
2954 case DW_AT_high_pc:
2955 case DW_AT_low_pc:
2956 case DW_AT_object_pointer:
2957 case DW_AT_prototyped:
2958 case DW_AT_pure:
2959 case DW_AT_ranges:
2960 case DW_AT_recursive:
2961 case DW_AT_return_addr:
2962 case DW_AT_segment:
2963 case DW_AT_specification:
2964 case DW_AT_start_scope:
2965 case DW_AT_static_link:
2966 case DW_AT_trampoline:
2967 case DW_AT_visibility:
2968 case DW_AT_virtuality:
2969 case DW_AT_vtable_elem_location:
2970 case DW_AT_abstract_origin:
2971 case DW_AT_description:
2972 case DW_AT_sibling:
2973 break;
2974 }
2975 }
2976 }
2977
2978 void *return_clang_type = NULL;
2979 Type *func_type = ResolveTypeUID(type_die_offset);
2980 if (func_type)
2981 return_clang_type = func_type->GetOpaqueClangQualType();
2982 else
2983 return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType();
2984
2985 std::vector<void *> function_param_types;
2986 std::vector<clang::ParmVarDecl*> function_param_decls;
2987
2988 // Parse the function children for the parameters
2989 ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls);
2990
2991 clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals);
2992 if (type_name_cstr)
2993 {
2994 clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
2995 // Add the decl to our DIE to decl context map
2996 assert (function_decl);
2997 m_die_to_decl_ctx[die] = function_decl;
2998 if (!function_param_decls.empty())
Greg Clayton471b31c2010-07-20 22:52:08 +00002999 type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003000 }
3001 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3002
3003 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3004 assert(type_sp.get());
3005 }
3006 }
3007 break;
3008
3009 case DW_TAG_array_type:
3010 {
3011 //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
3012 // Set a bit that lets us know that we are currently parsing this
3013 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
3014
3015 size_t byte_size = 0;
3016 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3017 Declaration decl;
3018 int64_t first_index = 0;
3019 uint32_t byte_stride = 0;
3020 uint32_t bit_stride = 0;
3021 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3022
3023 if (num_attributes > 0)
3024 {
3025 uint32_t i;
3026 for (i=0; i<num_attributes; ++i)
3027 {
3028 attr = attributes.AttributeAtIndex(i);
3029 DWARFFormValue form_value;
3030 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3031 {
3032 switch (attr)
3033 {
3034 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3035 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3036 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3037 case DW_AT_name:
3038 type_name_cstr = form_value.AsCString(&get_debug_str_data());
3039 type_name_dbstr.SetCString(type_name_cstr);
3040 break;
3041
3042 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3043 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3044 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3045 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
3046 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
3047 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
3048 case DW_AT_allocated:
3049 case DW_AT_associated:
3050 case DW_AT_data_location:
3051 case DW_AT_description:
3052 case DW_AT_ordering:
3053 case DW_AT_start_scope:
3054 case DW_AT_visibility:
3055 case DW_AT_specification:
3056 case DW_AT_abstract_origin:
3057 case DW_AT_sibling:
3058 break;
3059 }
3060 }
3061 }
3062
3063 Type *element_type = ResolveTypeUID(type_die_offset);
3064
3065 if (element_type)
3066 {
3067 std::vector<uint64_t> element_orders;
3068 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
3069 if (byte_stride == 0 && bit_stride == 0)
3070 byte_stride = element_type->GetByteSize();
3071 void *array_element_type = element_type->GetOpaqueClangQualType();
3072 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3073 uint64_t num_elements = 0;
3074 std::vector<uint64_t>::const_reverse_iterator pos;
3075 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3076 for (pos = element_orders.rbegin(); pos != end; ++pos)
3077 {
3078 num_elements = *pos;
3079 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
3080 array_element_type = clang_type;
3081 array_element_bit_stride = array_element_bit_stride * num_elements;
3082 }
3083 ConstString empty_name;
3084 type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3085 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3086 }
3087 }
3088 }
3089 break;
3090
Greg Clayton9b81a312010-06-12 01:20:30 +00003091 case DW_TAG_ptr_to_member_type:
3092 {
3093 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3094 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3095
3096 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3097
3098 if (num_attributes > 0) {
3099 uint32_t i;
3100 for (i=0; i<num_attributes; ++i)
3101 {
3102 attr = attributes.AttributeAtIndex(i);
3103 DWARFFormValue form_value;
3104 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3105 {
3106 switch (attr)
3107 {
3108 case DW_AT_type:
3109 type_die_offset = form_value.Reference(dwarf_cu); break;
3110 case DW_AT_containing_type:
3111 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3112 }
3113 }
3114 }
3115
3116 Type *pointee_type = ResolveTypeUID(type_die_offset);
3117 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3118
3119 void *pointee_clang_type = pointee_type->GetOpaqueClangQualType();
Greg Clayton1ba811d2010-06-12 15:33:14 +00003120 void *class_clang_type = class_type->GetOpaqueClangQualType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003121
Greg Claytonb1320972010-07-14 00:18:15 +00003122 clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003123
3124 size_t byte_size = ClangASTContext::GetTypeBitSize(type_list->GetClangASTContext().getASTContext(), clang_type) / 8;
3125
3126 type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type));
3127 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3128 }
3129
3130 break;
3131 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003132 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003133 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003134 break;
3135 }
3136
3137 if (type_sp.get())
3138 {
3139 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3140 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3141
3142 SymbolContextScope * symbol_context_scope = NULL;
3143 if (sc_parent_tag == DW_TAG_compile_unit)
3144 {
3145 symbol_context_scope = sc.comp_unit;
3146 }
3147 else if (sc.function != NULL)
3148 {
3149 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3150 if (symbol_context_scope == NULL)
3151 symbol_context_scope = sc.function;
3152 }
3153
3154 if (symbol_context_scope != NULL)
3155 {
3156 type_sp->SetSymbolContextScope(symbol_context_scope);
3157 }
3158
3159// if (udt_sp.get())
3160// {
3161// if (is_forward_declaration)
3162// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3163// type_sp->SetUserDefinedType(udt_sp);
3164// }
3165
3166 if (type_sp.unique())
3167 {
3168 // We are ready to put this type into the uniqued list up at the module level
3169 TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
3170
3171 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get());
3172
3173 type_sp = uniqued_type_sp;
3174 }
3175 }
3176 }
3177 else
3178 {
3179 switch (tag)
3180 {
3181 case DW_TAG_base_type:
3182 case DW_TAG_pointer_type:
3183 case DW_TAG_reference_type:
3184 case DW_TAG_typedef:
3185 case DW_TAG_const_type:
3186 case DW_TAG_restrict_type:
3187 case DW_TAG_volatile_type:
3188 case DW_TAG_structure_type:
3189 case DW_TAG_union_type:
3190 case DW_TAG_class_type:
3191 case DW_TAG_enumeration_type:
3192 case DW_TAG_subprogram:
3193 case DW_TAG_subroutine_type:
3194 case DW_TAG_array_type:
3195 {
3196 Type *existing_type = (Type*)die->GetUserData();
3197 if (existing_type != DIE_IS_BEING_PARSED)
3198 {
3199 type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID());
3200 }
3201 }
3202 break;
3203 default:
3204 //assert(!"invalid type tag...");
3205 break;
3206 }
3207 }
3208 }
3209 return type_sp;
3210}
3211
3212size_t
3213SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children)
3214{
3215 size_t types_added = 0;
3216 while (die != NULL)
3217 {
3218 bool type_is_new = false;
3219 if (ParseType(sc, dwarf_cu, die, type_is_new).get())
3220 {
3221 if (type_is_new)
3222 ++types_added;
3223 }
3224
3225 if (parse_children && die->HasChildren())
3226 {
3227 if (die->Tag() == DW_TAG_subprogram)
3228 {
3229 SymbolContext child_sc(sc);
3230 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3231 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3232 }
3233 else
3234 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3235 }
3236
3237 if (parse_siblings)
3238 die = die->GetSibling();
3239 else
3240 die = NULL;
3241 }
3242 return types_added;
3243}
3244
3245
3246size_t
3247SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3248{
3249 assert(sc.comp_unit && sc.function);
3250 size_t functions_added = 0;
3251 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3252 if (dwarf_cu)
3253 {
3254 dw_offset_t function_die_offset = sc.function->GetID();
3255 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3256 if (function_die)
3257 {
3258 ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
3259 }
3260 }
3261
3262 return functions_added;
3263}
3264
3265
3266size_t
3267SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3268{
3269 // At least a compile unit must be valid
3270 assert(sc.comp_unit);
3271 size_t types_added = 0;
3272 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3273 if (dwarf_cu)
3274 {
3275 if (sc.function)
3276 {
3277 dw_offset_t function_die_offset = sc.function->GetID();
3278 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3279 if (func_die && func_die->HasChildren())
3280 {
3281 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3282 }
3283 }
3284 else
3285 {
3286 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3287 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3288 {
3289 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3290 }
3291 }
3292 }
3293
3294 return types_added;
3295}
3296
3297size_t
3298SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3299{
3300 if (sc.comp_unit != NULL)
3301 {
3302 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3303
3304 if (dwarf_cu == NULL)
3305 return 0;
3306
3307 if (sc.function)
3308 {
3309 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
3310 return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true);
3311 }
3312 else if (sc.comp_unit)
3313 {
3314 uint32_t vars_added = 0;
3315 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3316
3317 if (variables.get() == NULL)
3318 {
3319 variables.reset(new VariableList());
3320 sc.comp_unit->SetVariableList(variables);
3321
3322 // Index if we already haven't to make sure the compile units
3323 // get indexed and make their global DIE index list
3324 if (!m_indexed)
3325 Index ();
3326
3327 const size_t num_globals = dwarf_cu->GetNumGlobals();
3328 for (size_t idx=0; idx<num_globals; ++idx)
3329 {
3330 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx)));
3331 if (var_sp)
3332 {
3333 variables->AddVariable(var_sp);
3334 ++vars_added;
3335 }
3336 }
3337 }
3338 return vars_added;
3339 }
3340 }
3341 return 0;
3342}
3343
3344
3345VariableSP
3346SymbolFileDWARF::ParseVariableDIE
3347(
3348 const SymbolContext& sc,
3349 const DWARFCompileUnit* dwarf_cu,
3350 const DWARFDebugInfoEntry *die
3351)
3352{
3353
3354 VariableSP var_sp;
3355
3356 const dw_tag_t tag = die->Tag();
3357 DWARFDebugInfoEntry::Attributes attributes;
3358 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3359 if (num_attributes > 0)
3360 {
3361 const char *name = NULL;
3362 Declaration decl;
3363 uint32_t i;
3364 TypeSP type_sp;
3365 Type *var_type = NULL;
3366 DWARFExpression location;
3367 bool is_external = false;
3368 bool is_artificial = false;
3369 uint32_t accessibility = clang::AS_none;
3370
3371 for (i=0; i<num_attributes; ++i)
3372 {
3373 dw_attr_t attr = attributes.AttributeAtIndex(i);
3374 DWARFFormValue form_value;
3375 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3376 {
3377 switch (attr)
3378 {
3379 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3380 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3381 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3382 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
3383 case DW_AT_type: var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break;
3384 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3385 case DW_AT_location:
3386 {
3387 if (form_value.BlockData())
3388 {
3389 const DataExtractor& debug_info_data = get_debug_info_data();
3390
3391 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3392 uint32_t block_length = form_value.Unsigned();
3393 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL);
3394 }
3395 else
3396 {
3397 const DataExtractor& debug_loc_data = get_debug_loc_data();
3398 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3399
3400 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3401 if (loc_list_length > 0)
3402 {
3403 Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList());
3404 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address);
3405 }
3406 }
3407 }
3408 break;
3409
3410 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
3411 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
3412 case DW_AT_const_value:
3413 case DW_AT_declaration:
3414 case DW_AT_description:
3415 case DW_AT_endianity:
3416 case DW_AT_segment:
3417 case DW_AT_start_scope:
3418 case DW_AT_visibility:
3419 default:
3420 case DW_AT_abstract_origin:
3421 case DW_AT_sibling:
3422 case DW_AT_specification:
3423 break;
3424 }
3425 }
3426 }
3427
3428 if (location.IsValid())
3429 {
3430 assert(var_type != DIE_IS_BEING_PARSED);
3431
3432 ConstString var_name(name);
3433
3434 ValueType scope = eValueTypeInvalid;
3435
3436 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3437 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3438
3439 if (tag == DW_TAG_formal_parameter)
3440 scope = eValueTypeVariableArgument;
3441 else if (is_external || parent_tag == DW_TAG_compile_unit)
3442 scope = eValueTypeVariableGlobal;
3443 else
3444 scope = eValueTypeVariableLocal;
3445
3446 SymbolContextScope * symbol_context_scope = NULL;
3447 if (parent_tag == DW_TAG_compile_unit)
3448 {
3449 symbol_context_scope = sc.comp_unit;
3450 }
3451 else if (sc.function != NULL)
3452 {
3453 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3454 if (symbol_context_scope == NULL)
3455 symbol_context_scope = sc.function;
3456 }
3457
3458 assert(symbol_context_scope != NULL);
3459 var_sp.reset (new Variable(die->GetOffset(),
3460 var_name,
3461 var_type,
3462 scope,
3463 symbol_context_scope,
3464 &decl,
3465 location,
3466 is_external,
3467 is_artificial));
3468 const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get());
3469 }
3470 }
3471 return var_sp;
3472}
3473
3474size_t
3475SymbolFileDWARF::ParseVariables
3476(
3477 const SymbolContext& sc,
3478 const DWARFCompileUnit* dwarf_cu,
3479 const DWARFDebugInfoEntry *orig_die,
3480 bool parse_siblings,
3481 bool parse_children,
3482 VariableList* cc_variable_list
3483)
3484{
3485 if (orig_die == NULL)
3486 return 0;
3487
3488 size_t vars_added = 0;
3489 const DWARFDebugInfoEntry *die = orig_die;
3490 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3491 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3492 VariableListSP variables;
3493 switch (parent_tag)
3494 {
3495 case DW_TAG_compile_unit:
3496 if (sc.comp_unit != NULL)
3497 {
3498 variables = sc.comp_unit->GetVariableList(false);
3499 if (variables.get() == NULL)
3500 {
3501 variables.reset(new VariableList());
3502 sc.comp_unit->SetVariableList(variables);
3503 }
3504 }
3505 else
3506 {
3507 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3508 vars_added = 0;
3509 }
3510 break;
3511
3512 case DW_TAG_subprogram:
3513 case DW_TAG_inlined_subroutine:
3514 case DW_TAG_lexical_block:
3515 if (sc.function != NULL)
3516 {
3517 // Check to see if we already have parsed the variables for the given scope
3518 variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false);
3519 if (variables.get() == NULL)
3520 {
3521 variables.reset(new VariableList());
3522 sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables);
3523 }
3524 }
3525 else
3526 {
3527 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3528 vars_added = 0;
3529 }
3530 break;
3531
3532 default:
3533 assert(!"Didn't find appropriate parent DIE for variable list...");
3534 break;
3535 }
3536
3537 // We need to have a variable list at this point that we can add variables to
3538 assert(variables.get());
3539
3540 while (die != NULL)
3541 {
3542 dw_tag_t tag = die->Tag();
3543
3544 // Check to see if we have already parsed this variable or constant?
3545 if (die->GetUserData() == NULL)
3546 {
3547 // We haven't already parsed it, lets do that now.
3548 if ((tag == DW_TAG_variable) ||
3549 (tag == DW_TAG_constant) ||
3550 (tag == DW_TAG_formal_parameter && sc.function))
3551 {
3552 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die));
3553 if (var_sp)
3554 {
3555 variables->AddVariable(var_sp);
3556 ++vars_added;
3557 }
3558 }
3559 }
3560
3561 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3562
3563 if (!skip_children && parse_children && die->HasChildren())
3564 {
3565 vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true);
3566 //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
3567 }
3568
3569 if (parse_siblings)
3570 die = die->GetSibling();
3571 else
3572 die = NULL;
3573 }
3574
3575 if (cc_variable_list)
3576 {
3577 cc_variable_list->AddVariables(variables.get());
3578 }
3579
3580 return vars_added;
3581}
3582
3583//------------------------------------------------------------------
3584// PluginInterface protocol
3585//------------------------------------------------------------------
3586const char *
3587SymbolFileDWARF::GetPluginName()
3588{
3589 return "SymbolFileDWARF";
3590}
3591
3592const char *
3593SymbolFileDWARF::GetShortPluginName()
3594{
3595 return GetPluginNameStatic();
3596}
3597
3598uint32_t
3599SymbolFileDWARF::GetPluginVersion()
3600{
3601 return 1;
3602}
3603
3604void
3605SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3606{
3607}
3608
3609Error
3610SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3611{
3612 Error error;
3613 error.SetErrorString("No plug-in command are currently supported.");
3614 return error;
3615}
3616
3617Log *
3618SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3619{
3620 return NULL;
3621}
3622