blob: 7219b533d4437b69d9822b41b3af1cc42c9b4469 [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"
Greg Claytonc685f8e2010-09-15 04:15:46 +000029#include "lldb/Core/StreamFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Core/Timer.h"
31#include "lldb/Core/Value.h"
32
33#include "lldb/Symbol/Block.h"
34#include "lldb/Symbol/CompileUnit.h"
35#include "lldb/Symbol/LineTable.h"
36#include "lldb/Symbol/ObjectFile.h"
37#include "lldb/Symbol/SymbolVendor.h"
38#include "lldb/Symbol/VariableList.h"
39
40#include "DWARFCompileUnit.h"
41#include "DWARFDebugAbbrev.h"
42#include "DWARFDebugAranges.h"
43#include "DWARFDebugInfo.h"
44#include "DWARFDebugInfoEntry.h"
45#include "DWARFDebugLine.h"
46#include "DWARFDebugPubnames.h"
47#include "DWARFDebugRanges.h"
48#include "DWARFDIECollection.h"
49#include "DWARFFormValue.h"
50#include "DWARFLocationList.h"
51#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000052#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053
54#include <map>
55
Greg Claytonc93237c2010-10-01 20:48:32 +000056//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
57
58#ifdef ENABLE_DEBUG_PRINTF
59#include <stdio.h>
60#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
61#else
62#define DEBUG_PRINTF(fmt, ...)
63#endif
64
Greg Clayton594e5ed2010-09-27 21:07:38 +000065#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
67using namespace lldb;
68using namespace lldb_private;
69
70
Sean Callananc7fbf732010-08-06 00:32:49 +000071static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000072DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073{
74 switch (dwarf_accessibility)
75 {
Sean Callananc7fbf732010-08-06 00:32:49 +000076 case DW_ACCESS_public: return eAccessPublic;
77 case DW_ACCESS_private: return eAccessPrivate;
78 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000079 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080 }
Sean Callananc7fbf732010-08-06 00:32:49 +000081 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082}
83
84void
85SymbolFileDWARF::Initialize()
86{
87 LogChannelDWARF::Initialize();
88 PluginManager::RegisterPlugin (GetPluginNameStatic(),
89 GetPluginDescriptionStatic(),
90 CreateInstance);
91}
92
93void
94SymbolFileDWARF::Terminate()
95{
96 PluginManager::UnregisterPlugin (CreateInstance);
97 LogChannelDWARF::Initialize();
98}
99
100
101const char *
102SymbolFileDWARF::GetPluginNameStatic()
103{
104 return "symbol-file.dwarf2";
105}
106
107const char *
108SymbolFileDWARF::GetPluginDescriptionStatic()
109{
110 return "DWARF and DWARF3 debug symbol file reader.";
111}
112
113
114SymbolFile*
115SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
116{
117 return new SymbolFileDWARF(obj_file);
118}
119
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000120
121ClangASTContext &
122SymbolFileDWARF::GetClangASTContext()
123{
124 return GetTypeList()->GetClangASTContext();
125}
126
127TypeList *
128SymbolFileDWARF::GetTypeList ()
129{
130 if (m_debug_map_symfile)
131 return m_debug_map_symfile->GetTypeList();
132 return m_obj_file->GetModule()->GetTypeList();
133
134}
135
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136//----------------------------------------------------------------------
137// Gets the first parent that is a lexical block, function or inlined
138// subroutine, or compile unit.
139//----------------------------------------------------------------------
140static const DWARFDebugInfoEntry *
141GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
142{
143 const DWARFDebugInfoEntry *die;
144 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
145 {
146 dw_tag_t tag = die->Tag();
147
148 switch (tag)
149 {
150 case DW_TAG_compile_unit:
151 case DW_TAG_subprogram:
152 case DW_TAG_inlined_subroutine:
153 case DW_TAG_lexical_block:
154 return die;
155 }
156 }
157 return NULL;
158}
159
160
Greg Clayton450e3f32010-10-12 02:24:53 +0000161SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
162 SymbolFile (objfile),
163 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000164 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165 m_flags(),
166 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 m_data_debug_frame(),
168 m_data_debug_info(),
169 m_data_debug_line(),
170 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171 m_data_debug_ranges(),
172 m_data_debug_str(),
173 m_abbr(),
174 m_aranges(),
175 m_info(),
176 m_line(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000177 m_function_basename_index(),
178 m_function_fullname_index(),
179 m_function_method_index(),
180 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000181 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000182 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000183 m_type_index(),
184 m_namespace_index(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185 m_indexed(false),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000186 m_ranges()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187{
188}
189
190SymbolFileDWARF::~SymbolFileDWARF()
191{
192}
193
194bool
195SymbolFileDWARF::SupportedVersion(uint16_t version)
196{
197 return version == 2 || version == 3;
198}
199
200uint32_t
201SymbolFileDWARF::GetAbilities ()
202{
203 uint32_t abilities = 0;
204 if (m_obj_file != NULL)
205 {
206 const Section* section = NULL;
207 const SectionList *section_list = m_obj_file->GetSectionList();
208 if (section_list == NULL)
209 return 0;
210
211 uint64_t debug_abbrev_file_size = 0;
212 uint64_t debug_aranges_file_size = 0;
213 uint64_t debug_frame_file_size = 0;
214 uint64_t debug_info_file_size = 0;
215 uint64_t debug_line_file_size = 0;
216 uint64_t debug_loc_file_size = 0;
217 uint64_t debug_macinfo_file_size = 0;
218 uint64_t debug_pubnames_file_size = 0;
219 uint64_t debug_pubtypes_file_size = 0;
220 uint64_t debug_ranges_file_size = 0;
221 uint64_t debug_str_file_size = 0;
222
223 static ConstString g_dwarf_section_name ("__DWARF");
224
225 section = section_list->FindSectionByName(g_dwarf_section_name).get();
226
227 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000228 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
Greg Clayton4ceb9982010-07-21 22:54:26 +0000230 section_list = &section->GetChildren ();
231 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232
Greg Clayton4ceb9982010-07-21 22:54:26 +0000233 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000234 if (section != NULL)
235 {
236 debug_info_file_size = section->GetByteSize();
237
Greg Clayton4ceb9982010-07-21 22:54:26 +0000238 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239 if (section)
240 debug_abbrev_file_size = section->GetByteSize();
241 else
242 m_flags.Set (flagsGotDebugAbbrevData);
243
Greg Clayton4ceb9982010-07-21 22:54:26 +0000244 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245 if (section)
246 debug_aranges_file_size = section->GetByteSize();
247 else
248 m_flags.Set (flagsGotDebugArangesData);
249
Greg Clayton4ceb9982010-07-21 22:54:26 +0000250 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251 if (section)
252 debug_frame_file_size = section->GetByteSize();
253 else
254 m_flags.Set (flagsGotDebugFrameData);
255
Greg Clayton4ceb9982010-07-21 22:54:26 +0000256 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257 if (section)
258 debug_line_file_size = section->GetByteSize();
259 else
260 m_flags.Set (flagsGotDebugLineData);
261
Greg Clayton4ceb9982010-07-21 22:54:26 +0000262 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263 if (section)
264 debug_loc_file_size = section->GetByteSize();
265 else
266 m_flags.Set (flagsGotDebugLocData);
267
Greg Clayton4ceb9982010-07-21 22:54:26 +0000268 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269 if (section)
270 debug_macinfo_file_size = section->GetByteSize();
271 else
272 m_flags.Set (flagsGotDebugMacInfoData);
273
Greg Clayton4ceb9982010-07-21 22:54:26 +0000274 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275 if (section)
276 debug_pubnames_file_size = section->GetByteSize();
277 else
278 m_flags.Set (flagsGotDebugPubNamesData);
279
Greg Clayton4ceb9982010-07-21 22:54:26 +0000280 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281 if (section)
282 debug_pubtypes_file_size = section->GetByteSize();
283 else
284 m_flags.Set (flagsGotDebugPubTypesData);
285
Greg Clayton4ceb9982010-07-21 22:54:26 +0000286 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000287 if (section)
288 debug_ranges_file_size = section->GetByteSize();
289 else
290 m_flags.Set (flagsGotDebugRangesData);
291
Greg Clayton4ceb9982010-07-21 22:54:26 +0000292 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 if (section)
294 debug_str_file_size = section->GetByteSize();
295 else
296 m_flags.Set (flagsGotDebugStrData);
297 }
298
299 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
300 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
301
302 if (debug_line_file_size > 0)
303 abilities |= LineTables;
304
305 if (debug_aranges_file_size > 0)
306 abilities |= AddressAcceleratorTable;
307
308 if (debug_pubnames_file_size > 0)
309 abilities |= FunctionAcceleratorTable;
310
311 if (debug_pubtypes_file_size > 0)
312 abilities |= TypeAcceleratorTable;
313
314 if (debug_macinfo_file_size > 0)
315 abilities |= MacroInformation;
316
317 if (debug_frame_file_size > 0)
318 abilities |= CallFrameInformation;
319 }
320 return abilities;
321}
322
323const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000324SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325{
326 if (m_flags.IsClear (got_flag))
327 {
328 m_flags.Set (got_flag);
329 const SectionList *section_list = m_obj_file->GetSectionList();
330 if (section_list)
331 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000332 Section *section = section_list->FindSectionByType(sect_type, true).get();
333 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334 {
335 // See if we memory mapped the DWARF segment?
336 if (m_dwarf_data.GetByteSize())
337 {
338 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
339 }
340 else
341 {
342 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
343 data.Clear();
344 }
345 }
346 }
347 }
348 return data;
349}
350
351const DataExtractor&
352SymbolFileDWARF::get_debug_abbrev_data()
353{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000354 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355}
356
357const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358SymbolFileDWARF::get_debug_frame_data()
359{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000360 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361}
362
363const DataExtractor&
364SymbolFileDWARF::get_debug_info_data()
365{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000366 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367}
368
369const DataExtractor&
370SymbolFileDWARF::get_debug_line_data()
371{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000372 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373}
374
375const DataExtractor&
376SymbolFileDWARF::get_debug_loc_data()
377{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000378 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379}
380
381const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382SymbolFileDWARF::get_debug_ranges_data()
383{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000384 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385}
386
387const DataExtractor&
388SymbolFileDWARF::get_debug_str_data()
389{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000390 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391}
392
393
394DWARFDebugAbbrev*
395SymbolFileDWARF::DebugAbbrev()
396{
397 if (m_abbr.get() == NULL)
398 {
399 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
400 if (debug_abbrev_data.GetByteSize() > 0)
401 {
402 m_abbr.reset(new DWARFDebugAbbrev());
403 if (m_abbr.get())
404 m_abbr->Parse(debug_abbrev_data);
405 }
406 }
407 return m_abbr.get();
408}
409
410const DWARFDebugAbbrev*
411SymbolFileDWARF::DebugAbbrev() const
412{
413 return m_abbr.get();
414}
415
416DWARFDebugAranges*
417SymbolFileDWARF::DebugAranges()
418{
Greg Clayton016a95e2010-09-14 02:20:48 +0000419 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
420 // and we are already parsing all of the DWARF because the .debug_pubnames
421 // is useless (it only mentions symbols that are externally visible), so
422 // don't use the .debug_aranges section, we should be using a debug aranges
423 // we got from SymbolFileDWARF::Index().
424
425 if (!m_indexed)
426 Index();
427
428
429// if (m_aranges.get() == NULL)
430// {
431// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
432// m_aranges.reset(new DWARFDebugAranges());
433// if (m_aranges.get())
434// {
435// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
436// if (debug_aranges_data.GetByteSize() > 0)
437// m_aranges->Extract(debug_aranges_data);
438// else
439// m_aranges->Generate(this);
440// }
441// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442 return m_aranges.get();
443}
444
445const DWARFDebugAranges*
446SymbolFileDWARF::DebugAranges() const
447{
448 return m_aranges.get();
449}
450
451
452DWARFDebugInfo*
453SymbolFileDWARF::DebugInfo()
454{
455 if (m_info.get() == NULL)
456 {
457 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
458 if (get_debug_info_data().GetByteSize() > 0)
459 {
460 m_info.reset(new DWARFDebugInfo());
461 if (m_info.get())
462 {
463 m_info->SetDwarfData(this);
464 }
465 }
466 }
467 return m_info.get();
468}
469
470const DWARFDebugInfo*
471SymbolFileDWARF::DebugInfo() const
472{
473 return m_info.get();
474}
475
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476DWARFCompileUnit*
477SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
478{
479 DWARFDebugInfo* info = DebugInfo();
480 if (info)
481 return info->GetCompileUnit(cu_uid).get();
482 return NULL;
483}
484
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485
486DWARFDebugRanges*
487SymbolFileDWARF::DebugRanges()
488{
489 if (m_ranges.get() == NULL)
490 {
491 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
492 if (get_debug_ranges_data().GetByteSize() > 0)
493 {
494 m_ranges.reset(new DWARFDebugRanges());
495 if (m_ranges.get())
496 m_ranges->Extract(this);
497 }
498 }
499 return m_ranges.get();
500}
501
502const DWARFDebugRanges*
503SymbolFileDWARF::DebugRanges() const
504{
505 return m_ranges.get();
506}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000507
508bool
Greg Clayton0fffff52010-09-24 05:15:53 +0000509SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510{
511 if (cu != NULL)
512 {
513 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly ();
514 if (cu_die)
515 {
516 const char * cu_die_name = cu_die->GetName(this, cu);
517 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
Greg Clayton9e409562010-07-28 02:04:09 +0000518 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519 if (cu_die_name)
520 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000521 FileSpec cu_file_spec;
522
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
524 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000525 // If we have a full path to the compile unit, we don't need to resolve
526 // the file. This can be expensive e.g. when the source files are NFS mounted.
527 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528 }
529 else
530 {
531 std::string fullpath(cu_comp_dir);
532 if (*fullpath.rbegin() != '/')
533 fullpath += '/';
534 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000535 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536 }
537
Jim Ingham0909e5f2010-09-16 00:57:33 +0000538 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_file_spec, cu->GetOffset(), class_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539 if (compile_unit_sp.get())
540 {
541 cu->SetUserData(compile_unit_sp.get());
542 return true;
543 }
544 }
545 }
546 }
547 return false;
548}
549
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550uint32_t
551SymbolFileDWARF::GetNumCompileUnits()
552{
553 DWARFDebugInfo* info = DebugInfo();
554 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556 return 0;
557}
558
559CompUnitSP
560SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
561{
562 CompUnitSP comp_unit;
563 DWARFDebugInfo* info = DebugInfo();
564 if (info)
565 {
566 DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
567 if (cu != NULL)
568 {
569 // Our symbol vendor shouldn't be asking us to add a compile unit that
570 // has already been added to it, which this DWARF plug-in knows as it
571 // stores the lldb compile unit (CompileUnit) pointer in each
572 // DWARFCompileUnit object when it gets added.
573 assert(cu->GetUserData() == NULL);
574 ParseCompileUnit(cu, comp_unit);
575 }
576 }
577 return comp_unit;
578}
579
580static void
581AddRangesToBlock
582(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000583 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584 DWARFDebugRanges::RangeList& ranges,
585 addr_t block_base_addr
586)
587{
588 ranges.SubtractOffset (block_base_addr);
589 size_t range_idx = 0;
590 const DWARFDebugRanges::Range *debug_range;
591 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
592 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000593 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 }
595}
596
597
598Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000599SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600{
601 DWARFDebugRanges::RangeList func_ranges;
602 const char *name = NULL;
603 const char *mangled = NULL;
604 int decl_file = 0;
605 int decl_line = 0;
606 int decl_column = 0;
607 int call_file = 0;
608 int call_line = 0;
609 int call_column = 0;
610 DWARFExpression frame_base;
611
Greg Claytonc93237c2010-10-01 20:48:32 +0000612 assert (die->Tag() == DW_TAG_subprogram);
613
614 if (die->Tag() != DW_TAG_subprogram)
615 return NULL;
616
617 const DWARFDebugInfoEntry *parent_die = die->GetParent();
618 switch (parent_die->Tag())
619 {
620 case DW_TAG_structure_type:
621 case DW_TAG_class_type:
622 // We have methods of a class or struct
623 {
624 Type *class_type = ResolveType (dwarf_cu, parent_die);
625 if (class_type)
626 class_type->GetClangType();
627 }
628 break;
629
630 default:
631 // Parse the function prototype as a type that can then be added to concrete function instance
632 ParseTypes (sc, dwarf_cu, die, false, false);
633 break;
634 }
635
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636 //FixupTypes();
637
638 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
639 {
640 // Union of all ranges in the function DIE (if the function is discontiguous)
641 AddressRange func_range;
642 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
643 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
644 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
645 {
646 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
647 if (func_range.GetBaseAddress().IsValid())
648 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
649 }
650
651 if (func_range.GetBaseAddress().IsValid())
652 {
653 Mangled func_name;
654 if (mangled)
655 func_name.SetValue(mangled, true);
656 else if (name)
657 func_name.SetValue(name, false);
658
659 FunctionSP func_sp;
660 std::auto_ptr<Declaration> decl_ap;
661 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
662 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
663
Greg Clayton594e5ed2010-09-27 21:07:38 +0000664 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000665
666 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
667
668 func_range.GetBaseAddress().ResolveLinkedAddress();
669
670 func_sp.reset(new Function (sc.comp_unit,
671 die->GetOffset(), // UserID is the DIE offset
672 die->GetOffset(),
673 func_name,
674 func_type,
675 func_range)); // first address range
676
677 if (func_sp.get() != NULL)
678 {
679 func_sp->GetFrameBaseExpression() = frame_base;
680 sc.comp_unit->AddFunction(func_sp);
681 return func_sp.get();
682 }
683 }
684 }
685 return NULL;
686}
687
688size_t
689SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
690{
691 assert (sc.comp_unit);
692 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000693 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 if (dwarf_cu)
695 {
696 DWARFDIECollection function_dies;
697 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
698 size_t func_idx;
699 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
700 {
701 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
702 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
703 {
704 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
705 ++functions_added;
706 }
707 }
708 //FixupTypes();
709 }
710 return functions_added;
711}
712
713bool
714SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
715{
716 assert (sc.comp_unit);
717 DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
718 assert (cu);
719 const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly();
720
721 if (cu_die)
722 {
723 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
724 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
725
726 // All file indexes in DWARF are one based and a file of index zero is
727 // supposed to be the compile unit itself.
728 support_files.Append (*sc.comp_unit);
729
730 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
731 }
732 return false;
733}
734
735struct ParseDWARFLineTableCallbackInfo
736{
737 LineTable* line_table;
738 const SectionList *section_list;
739 lldb::addr_t prev_sect_file_base_addr;
740 lldb::addr_t curr_sect_file_base_addr;
741 bool is_oso_for_debug_map;
742 bool prev_in_final_executable;
743 DWARFDebugLine::Row prev_row;
744 SectionSP prev_section_sp;
745 SectionSP curr_section_sp;
746};
747
748//----------------------------------------------------------------------
749// ParseStatementTableCallback
750//----------------------------------------------------------------------
751static void
752ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
753{
754 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
755 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
756 {
757 // Just started parsing the line table
758 }
759 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
760 {
761 // Done parsing line table, nothing to do for the cleanup
762 }
763 else
764 {
765 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
766 // We have a new row, lets append it
767
768 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
769 {
770 info->prev_section_sp = info->curr_section_sp;
771 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
772 // If this is an end sequence entry, then we subtract one from the
773 // address to make sure we get an address that is not the end of
774 // a section.
775 if (state.end_sequence && state.address != 0)
776 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
777 else
778 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
779
780 if (info->curr_section_sp.get())
781 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
782 else
783 info->curr_sect_file_base_addr = 0;
784 }
785 if (info->curr_section_sp.get())
786 {
787 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
788 // Check for the fancy section magic to determine if we
789
790 if (info->is_oso_for_debug_map)
791 {
792 // When this is a debug map object file that contains DWARF
793 // (referenced from an N_OSO debug map nlist entry) we will have
794 // a file address in the file range for our section from the
795 // original .o file, and a load address in the executable that
796 // contains the debug map.
797 //
798 // If the sections for the file range and load range are
799 // different, we have a remapped section for the function and
800 // this address is resolved. If they are the same, then the
801 // function for this address didn't make it into the final
802 // executable.
803 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
804
805 // If we are doing DWARF with debug map, then we need to carefully
806 // add each line table entry as there may be gaps as functions
807 // get moved around or removed.
808 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
809 {
810 if (info->prev_in_final_executable)
811 {
812 bool terminate_previous_entry = false;
813 if (!curr_in_final_executable)
814 {
815 // Check for the case where the previous line entry
816 // in a function made it into the final executable,
817 // yet the current line entry falls in a function
818 // that didn't. The line table used to be contiguous
819 // through this address range but now it isn't. We
820 // need to terminate the previous line entry so
821 // that we can reconstruct the line range correctly
822 // for it and to keep the line table correct.
823 terminate_previous_entry = true;
824 }
825 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
826 {
827 // Check for cases where the line entries used to be
828 // contiguous address ranges, but now they aren't.
829 // This can happen when order files specify the
830 // ordering of the functions.
831 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
832 Section *curr_sect = info->curr_section_sp.get();
833 Section *prev_sect = info->prev_section_sp.get();
834 assert (curr_sect->GetLinkedSection());
835 assert (prev_sect->GetLinkedSection());
836 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
837 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
838 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
839 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
840 if (object_file_addr_delta != linked_file_addr_delta)
841 terminate_previous_entry = true;
842 }
843
844 if (terminate_previous_entry)
845 {
846 line_table->InsertLineEntry (info->prev_section_sp,
847 state.address - info->prev_sect_file_base_addr,
848 info->prev_row.line,
849 info->prev_row.column,
850 info->prev_row.file,
851 false, // is_stmt
852 false, // basic_block
853 false, // state.prologue_end
854 false, // state.epilogue_begin
855 true); // end_sequence);
856 }
857 }
858 }
859
860 if (curr_in_final_executable)
861 {
862 line_table->InsertLineEntry (info->curr_section_sp,
863 curr_line_section_offset,
864 state.line,
865 state.column,
866 state.file,
867 state.is_stmt,
868 state.basic_block,
869 state.prologue_end,
870 state.epilogue_begin,
871 state.end_sequence);
872 info->prev_section_sp = info->curr_section_sp;
873 }
874 else
875 {
876 // If the current address didn't make it into the final
877 // executable, the current section will be the __text
878 // segment in the .o file, so we need to clear this so
879 // we can catch the next function that did make it into
880 // the final executable.
881 info->prev_section_sp.reset();
882 info->curr_section_sp.reset();
883 }
884
885 info->prev_in_final_executable = curr_in_final_executable;
886 }
887 else
888 {
889 // We are not in an object file that contains DWARF for an
890 // N_OSO, this is just a normal DWARF file. The DWARF spec
891 // guarantees that the addresses will be in increasing order
892 // so, since we store line tables in file address order, we
893 // can always just append the line entry without needing to
894 // search for the correct insertion point (we don't need to
895 // use LineEntry::InsertLineEntry()).
896 line_table->AppendLineEntry (info->curr_section_sp,
897 curr_line_section_offset,
898 state.line,
899 state.column,
900 state.file,
901 state.is_stmt,
902 state.basic_block,
903 state.prologue_end,
904 state.epilogue_begin,
905 state.end_sequence);
906 }
907 }
908
909 info->prev_row = state;
910 }
911}
912
913bool
914SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
915{
916 assert (sc.comp_unit);
917 if (sc.comp_unit->GetLineTable() != NULL)
918 return true;
919
920 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
921 if (dwarf_cu)
922 {
923 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
924 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
925 if (cu_line_offset != DW_INVALID_OFFSET)
926 {
927 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
928 if (line_table_ap.get())
929 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000930 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000931 uint32_t offset = cu_line_offset;
932 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
933 sc.comp_unit->SetLineTable(line_table_ap.release());
934 return true;
935 }
936 }
937 }
938 return false;
939}
940
941size_t
942SymbolFileDWARF::ParseFunctionBlocks
943(
944 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000945 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +0000946 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000947 const DWARFDebugInfoEntry *die,
948 addr_t subprogram_low_pc,
949 bool parse_siblings,
950 bool parse_children
951)
952{
953 size_t blocks_added = 0;
954 while (die != NULL)
955 {
956 dw_tag_t tag = die->Tag();
957
958 switch (tag)
959 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000960 case DW_TAG_inlined_subroutine:
Jim Inghamb0be4422010-08-12 01:20:14 +0000961 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000962 case DW_TAG_lexical_block:
963 {
964 DWARFDebugRanges::RangeList ranges;
965 const char *name = NULL;
966 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000967 Block *block = NULL;
968 if (tag != DW_TAG_subprogram)
969 {
970 BlockSP block_sp(new Block (die->GetOffset()));
971 parent_block->AddChild(block_sp);
972 block = block_sp.get();
973 }
974 else
975 {
976 block = parent_block;
977 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000978
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000979 int decl_file = 0;
980 int decl_line = 0;
981 int decl_column = 0;
982 int call_file = 0;
983 int call_line = 0;
984 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000985 if (die->GetDIENamesAndRanges (this,
986 dwarf_cu,
987 name,
988 mangled_name,
989 ranges,
990 decl_file, decl_line, decl_column,
991 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000992 {
993 if (tag == DW_TAG_subprogram)
994 {
995 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
996 subprogram_low_pc = ranges.LowestAddress(0);
997 }
Jim Inghamb0be4422010-08-12 01:20:14 +0000998 else if (tag == DW_TAG_inlined_subroutine)
999 {
1000 // We get called here for inlined subroutines in two ways.
1001 // The first time is when we are making the Function object
1002 // for this inlined concrete instance. Since we're creating a top level block at
1003 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1004 // adjust the containing address.
1005 // The second time is when we are parsing the blocks inside the function that contains
1006 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1007 // function the offset will be for that function.
1008 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1009 {
1010 subprogram_low_pc = ranges.LowestAddress(0);
1011 }
1012 }
1013
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001014 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001015
1016 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1017 {
1018 std::auto_ptr<Declaration> decl_ap;
1019 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001020 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1021 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001022
1023 std::auto_ptr<Declaration> call_ap;
1024 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001025 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1026 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001027
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001028 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 }
1030
1031 ++blocks_added;
1032
1033 if (parse_children && die->HasChildren())
1034 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001035 blocks_added += ParseFunctionBlocks (sc,
1036 block,
1037 dwarf_cu,
1038 die->GetFirstChild(),
1039 subprogram_low_pc,
1040 true,
1041 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 }
1043 }
1044 }
1045 break;
1046 default:
1047 break;
1048 }
1049
1050 if (parse_siblings)
1051 die = die->GetSibling();
1052 else
1053 die = NULL;
1054 }
1055 return blocks_added;
1056}
1057
1058size_t
1059SymbolFileDWARF::ParseChildMembers
1060(
1061 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001062 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001064 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001065 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001066 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1067 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001068 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001069 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001070 bool &is_a_class
1071)
1072{
1073 if (parent_die == NULL)
1074 return 0;
1075
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001076 size_t count = 0;
1077 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001078 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1079
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001080 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1081 {
1082 dw_tag_t tag = die->Tag();
1083
1084 switch (tag)
1085 {
1086 case DW_TAG_member:
1087 {
1088 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00001089 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001090 if (num_attributes > 0)
1091 {
1092 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001093 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001095 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001096 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001097 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001098 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 size_t byte_size = 0;
1100 size_t bit_offset = 0;
1101 size_t bit_size = 0;
1102 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001103 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001104 {
1105 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1106 DWARFFormValue form_value;
1107 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1108 {
1109 switch (attr)
1110 {
1111 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1112 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1113 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1114 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1115 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1116 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1117 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1118 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1119 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001120// if (form_value.BlockData())
1121// {
1122// Value initialValue(0);
1123// Value memberOffset(0);
1124// const DataExtractor& debug_info_data = get_debug_info_data();
1125// uint32_t block_length = form_value.Unsigned();
1126// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1127// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1128// {
1129// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1130// }
1131// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001132 break;
1133
Greg Clayton8cf05932010-07-22 18:30:50 +00001134 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001135 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136 case DW_AT_declaration:
1137 case DW_AT_description:
1138 case DW_AT_mutable:
1139 case DW_AT_visibility:
1140 default:
1141 case DW_AT_sibling:
1142 break;
1143 }
1144 }
1145 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001146
1147 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1148
1149 if (class_language == eLanguageTypeObjC ||
1150 class_language == eLanguageTypeObjC_plus_plus)
1151 accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152
Greg Clayton24739922010-10-13 03:15:28 +00001153 if (is_artificial == false)
1154 {
1155 Type *member_type = ResolveTypeUID(encoding_uid);
1156 assert(member_type);
1157 if (accessibility == eAccessNone)
1158 accessibility = default_accessibility;
1159 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001160
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001161 GetClangASTContext().AddFieldToRecordType (class_clang_type, name, member_type->GetClangType(), accessibility, bit_size);
Greg Clayton24739922010-10-13 03:15:28 +00001162 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163 }
1164 }
1165 break;
1166
1167 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001168 // Let the type parsing code handle this one for us.
1169 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001170 break;
1171
1172 case DW_TAG_inheritance:
1173 {
1174 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001175 if (default_accessibility == eAccessNone)
1176 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177 // TODO: implement DW_TAG_inheritance type parsing
1178 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00001179 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180 if (num_attributes > 0)
1181 {
1182 Declaration decl;
1183 DWARFExpression location;
1184 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001185 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001186 bool is_virtual = false;
1187 bool is_base_of_class = true;
1188 off_t member_offset = 0;
1189 uint32_t i;
1190 for (i=0; i<num_attributes; ++i)
1191 {
1192 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1193 DWARFFormValue form_value;
1194 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1195 {
1196 switch (attr)
1197 {
1198 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1199 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1200 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1201 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1202 case DW_AT_data_member_location:
1203 if (form_value.BlockData())
1204 {
1205 Value initialValue(0);
1206 Value memberOffset(0);
1207 const DataExtractor& debug_info_data = get_debug_info_data();
1208 uint32_t block_length = form_value.Unsigned();
1209 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1210 if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1211 {
1212 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1213 }
1214 }
1215 break;
1216
1217 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001218 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001219 break;
1220
1221 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1222 default:
1223 case DW_AT_sibling:
1224 break;
1225 }
1226 }
1227 }
1228
1229 Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1230 assert(base_class_dctype);
Greg Clayton9e409562010-07-28 02:04:09 +00001231
1232 if (class_language == eLanguageTypeObjC)
1233 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001234 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_dctype->GetClangType());
Greg Clayton9e409562010-07-28 02:04:09 +00001235 }
1236 else
1237 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001238 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetClangType(), accessibility, is_virtual, is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001239 assert(base_classes.back());
1240 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001241 }
1242 }
1243 break;
1244
1245 default:
1246 break;
1247 }
1248 }
1249 return count;
1250}
1251
1252
1253clang::DeclContext*
1254SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1255{
1256 DWARFDebugInfo* debug_info = DebugInfo();
1257 if (debug_info)
1258 {
1259 DWARFCompileUnitSP cu_sp;
1260 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1261 if (die)
1262 return GetClangDeclContextForDIE (cu_sp.get(), die);
1263 }
1264 return NULL;
1265}
1266
1267Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001268SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001269{
1270 DWARFDebugInfo* debug_info = DebugInfo();
1271 if (debug_info)
1272 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001273 DWARFCompileUnitSP cu_sp;
1274 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275 if (type_die != NULL)
Greg Clayton594e5ed2010-09-27 21:07:38 +00001276 return ResolveType (cu_sp.get(), type_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001277 }
1278 return NULL;
1279}
1280
Greg Clayton1be10fc2010-09-29 01:12:09 +00001281lldb::clang_type_t
1282SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1283{
1284 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Claytonc93237c2010-10-01 20:48:32 +00001285 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (ClangASTType::RemoveFastQualifiers(clang_type));
Greg Clayton1be10fc2010-09-29 01:12:09 +00001286 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001287 {
1288 // We have already resolved this type...
1289 return clang_type;
1290 }
1291 // Once we start resolving this type, remove it from the forward declaration
1292 // map in case anyone child members or other types require this type to get resolved.
1293 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1294 // are done.
1295 m_forward_decl_clang_type_to_die.erase (ClangASTType::RemoveFastQualifiers(clang_type));
1296
Greg Clayton1be10fc2010-09-29 01:12:09 +00001297
Greg Clayton450e3f32010-10-12 02:24:53 +00001298 DWARFDebugInfo* debug_info = DebugInfo();
1299
1300 DWARFCompileUnit *cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001301 Type *type = m_die_to_type.lookup (die);
1302
1303 const dw_tag_t tag = die->Tag();
1304
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001305 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1306 die->GetOffset(),
1307 DW_TAG_value_to_name(tag),
1308 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001309 assert (clang_type);
1310 DWARFDebugInfoEntry::Attributes attributes;
1311
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001312 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001313
1314 switch (tag)
1315 {
1316 case DW_TAG_structure_type:
1317 case DW_TAG_union_type:
1318 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001319 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001320 if (die->HasChildren())
1321 {
1322 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001323 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1324 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001325 class_language = eLanguageTypeObjC;
1326
1327 int tag_decl_kind = -1;
1328 AccessType default_accessibility = eAccessNone;
1329 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001330 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001331 tag_decl_kind = clang::TTK_Struct;
1332 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001333 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001334 else if (tag == DW_TAG_union_type)
1335 {
1336 tag_decl_kind = clang::TTK_Union;
1337 default_accessibility = eAccessPublic;
1338 }
1339 else if (tag == DW_TAG_class_type)
1340 {
1341 tag_decl_kind = clang::TTK_Class;
1342 default_accessibility = eAccessPrivate;
1343 }
1344
1345 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
1346 std::vector<clang::CXXBaseSpecifier *> base_classes;
1347 std::vector<int> member_accessibilities;
1348 bool is_a_class = false;
1349 // Parse members and base classes first
1350 DWARFDIECollection member_function_dies;
1351
1352 ParseChildMembers (sc,
1353 cu,
1354 die,
1355 clang_type,
1356 class_language,
1357 base_classes,
1358 member_accessibilities,
1359 member_function_dies,
1360 default_accessibility,
1361 is_a_class);
1362
1363 // Now parse any methods if there were any...
1364 size_t num_functions = member_function_dies.Size();
1365 if (num_functions > 0)
1366 {
1367 for (size_t i=0; i<num_functions; ++i)
1368 {
1369 ResolveType(cu, member_function_dies.GetDIEPtrAtIndex(i));
1370 }
1371 }
1372
Greg Clayton450e3f32010-10-12 02:24:53 +00001373 if (class_language == eLanguageTypeObjC)
1374 {
1375 std::string class_str (ClangASTContext::GetTypeName (clang_type));
1376 if (!class_str.empty())
1377 {
1378
1379 ConstString class_name (class_str.c_str());
1380 std::vector<NameToDIE::Info> method_die_infos;
1381 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1382 {
1383 DWARFCompileUnit* method_cu = NULL;
1384 DWARFCompileUnit* prev_method_cu = NULL;
1385 const size_t num_objc_methods = method_die_infos.size();
1386 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1387 {
1388 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1389
1390 if (method_cu != prev_method_cu)
1391 method_cu->ExtractDIEsIfNeeded (false);
1392
1393 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1394
1395 ResolveType (method_cu, method_die);
1396 }
1397 }
1398 }
1399 }
1400
Greg Claytonc93237c2010-10-01 20:48:32 +00001401 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1402 // need to tell the clang type it is actually a class.
1403 if (class_language != eLanguageTypeObjC)
1404 {
1405 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001406 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001407 }
1408
1409 // Since DW_TAG_structure_type gets used for both classes
1410 // and structures, we may need to set any DW_TAG_member
1411 // fields to have a "private" access if none was specified.
1412 // When we parsed the child members we tracked that actual
1413 // accessibility value for each DW_TAG_member in the
1414 // "member_accessibilities" array. If the value for the
1415 // member is zero, then it was set to the "default_accessibility"
1416 // which for structs was "public". Below we correct this
1417 // by setting any fields to "private" that weren't correctly
1418 // set.
1419 if (is_a_class && !member_accessibilities.empty())
1420 {
1421 // This is a class and all members that didn't have
1422 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001423 ast.SetDefaultAccessForRecordFields (clang_type,
1424 eAccessPrivate,
1425 &member_accessibilities.front(),
1426 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001427 }
1428
1429 if (!base_classes.empty())
1430 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001431 ast.SetBaseClassesForClassType (clang_type,
1432 &base_classes.front(),
1433 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001434
1435 // Clang will copy each CXXBaseSpecifier in "base_classes"
1436 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001437 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1438 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001439 }
1440
1441 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001442 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001443 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001444
1445 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001446 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001447 if (die->HasChildren())
1448 {
1449 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
1450 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), cu, die);
1451 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001452 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001453 return clang_type;
1454
1455 default:
1456 assert(false && "not a forward clang type decl!");
1457 break;
1458 }
1459 return NULL;
1460}
1461
Greg Claytonc685f8e2010-09-15 04:15:46 +00001462Type*
Greg Clayton24739922010-10-13 03:15:28 +00001463SymbolFileDWARF::ResolveType (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001464{
1465 if (type_die != NULL)
1466 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001467 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001468 if (type == NULL)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001469 type = GetTypeForDIE (cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001470 if (assert_not_being_parsed)
1471 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001472 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001473 }
1474 return NULL;
1475}
1476
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001477CompileUnit*
Greg Clayton0fffff52010-09-24 05:15:53 +00001478SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001479{
1480 // Check if the symbol vendor already knows about this compile unit?
1481 if (cu->GetUserData() == NULL)
1482 {
1483 // The symbol vendor doesn't know about this compile unit, we
1484 // need to parse and add it to the symbol vendor object.
1485 CompUnitSP dc_cu;
1486 ParseCompileUnit(cu, dc_cu);
1487 if (dc_cu.get())
1488 {
1489 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001490 if (cu_idx == UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001491 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
1492
1493 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001494
1495 if (m_debug_map_symfile)
1496 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001497 }
1498 }
1499 return (CompileUnit*)cu->GetUserData();
1500}
1501
1502bool
1503SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1504{
1505 sc.Clear();
1506 // Check if the symbol vendor already knows about this compile unit?
1507 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton016a95e2010-09-14 02:20:48 +00001508 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001509
1510 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1511 if (sc.function == NULL)
1512 sc.function = ParseCompileUnitFunction(sc, cu, func_die);
1513
1514 return sc.function != NULL;
1515}
1516
1517uint32_t
1518SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1519{
1520 Timer scoped_timer(__PRETTY_FUNCTION__,
1521 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1522 so_addr.GetSection(),
1523 so_addr.GetOffset(),
1524 resolve_scope);
1525 uint32_t resolved = 0;
1526 if (resolve_scope & ( eSymbolContextCompUnit |
1527 eSymbolContextFunction |
1528 eSymbolContextBlock |
1529 eSymbolContextLineEntry))
1530 {
1531 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1532
1533 DWARFDebugAranges* debug_aranges = DebugAranges();
1534 DWARFDebugInfo* debug_info = DebugInfo();
1535 if (debug_aranges)
1536 {
1537 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1538 if (cu_offset != DW_INVALID_OFFSET)
1539 {
1540 uint32_t cu_idx;
1541 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1542 if (cu)
1543 {
1544 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1545 assert(sc.comp_unit != NULL);
1546 resolved |= eSymbolContextCompUnit;
1547
1548 if (resolve_scope & eSymbolContextLineEntry)
1549 {
1550 LineTable *line_table = sc.comp_unit->GetLineTable();
1551 if (line_table == NULL)
1552 {
1553 if (ParseCompileUnitLineTable(sc))
1554 line_table = sc.comp_unit->GetLineTable();
1555 }
1556 if (line_table != NULL)
1557 {
1558 if (so_addr.IsLinkedAddress())
1559 {
1560 Address linked_addr (so_addr);
1561 linked_addr.ResolveLinkedAddress();
1562 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1563 {
1564 resolved |= eSymbolContextLineEntry;
1565 }
1566 }
1567 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1568 {
1569 resolved |= eSymbolContextLineEntry;
1570 }
1571 }
1572 }
1573
1574 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1575 {
1576 DWARFDebugInfoEntry *function_die = NULL;
1577 DWARFDebugInfoEntry *block_die = NULL;
1578 if (resolve_scope & eSymbolContextBlock)
1579 {
1580 cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1581 }
1582 else
1583 {
1584 cu->LookupAddress(file_vm_addr, &function_die, NULL);
1585 }
1586
1587 if (function_die != NULL)
1588 {
1589 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1590 if (sc.function == NULL)
1591 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1592 }
1593
1594 if (sc.function != NULL)
1595 {
1596 resolved |= eSymbolContextFunction;
1597
1598 if (resolve_scope & eSymbolContextBlock)
1599 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001600 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001601
1602 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001603 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001604 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001605 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001606 if (sc.block)
1607 resolved |= eSymbolContextBlock;
1608 }
1609 }
1610 }
1611 }
1612 }
1613 }
1614 }
1615 return resolved;
1616}
1617
1618
1619
1620uint32_t
1621SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1622{
1623 const uint32_t prev_size = sc_list.GetSize();
1624 if (resolve_scope & eSymbolContextCompUnit)
1625 {
1626 DWARFDebugInfo* debug_info = DebugInfo();
1627 if (debug_info)
1628 {
1629 uint32_t cu_idx;
1630 DWARFCompileUnit* cu = NULL;
1631
1632 for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1633 {
1634 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1635 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1636 if (check_inlines || file_spec_matches_cu_file_spec)
1637 {
1638 SymbolContext sc (m_obj_file->GetModule());
1639 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1640 assert(sc.comp_unit != NULL);
1641
1642 uint32_t file_idx = UINT32_MAX;
1643
1644 // If we are looking for inline functions only and we don't
1645 // find it in the support files, we are done.
1646 if (check_inlines)
1647 {
1648 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1649 if (file_idx == UINT32_MAX)
1650 continue;
1651 }
1652
1653 if (line != 0)
1654 {
1655 LineTable *line_table = sc.comp_unit->GetLineTable();
1656
1657 if (line_table != NULL && line != 0)
1658 {
1659 // We will have already looked up the file index if
1660 // we are searching for inline entries.
1661 if (!check_inlines)
1662 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1663
1664 if (file_idx != UINT32_MAX)
1665 {
1666 uint32_t found_line;
1667 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1668 found_line = sc.line_entry.line;
1669
Greg Clayton016a95e2010-09-14 02:20:48 +00001670 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001671 {
1672 sc.function = NULL;
1673 sc.block = NULL;
1674 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1675 {
1676 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1677 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1678 {
1679 DWARFDebugInfoEntry *function_die = NULL;
1680 DWARFDebugInfoEntry *block_die = NULL;
1681 cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1682
1683 if (function_die != NULL)
1684 {
1685 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1686 if (sc.function == NULL)
1687 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1688 }
1689
1690 if (sc.function != NULL)
1691 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001692 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001693
1694 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001695 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001696 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001697 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001698 }
1699 }
1700 }
1701
1702 sc_list.Append(sc);
1703 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1704 }
1705 }
1706 }
1707 else if (file_spec_matches_cu_file_spec && !check_inlines)
1708 {
1709 // only append the context if we aren't looking for inline call sites
1710 // by file and line and if the file spec matches that of the compile unit
1711 sc_list.Append(sc);
1712 }
1713 }
1714 else if (file_spec_matches_cu_file_spec && !check_inlines)
1715 {
1716 // only append the context if we aren't looking for inline call sites
1717 // by file and line and if the file spec matches that of the compile unit
1718 sc_list.Append(sc);
1719 }
1720
1721 if (!check_inlines)
1722 break;
1723 }
1724 }
1725 }
1726 }
1727 return sc_list.GetSize() - prev_size;
1728}
1729
1730void
1731SymbolFileDWARF::Index ()
1732{
1733 if (m_indexed)
1734 return;
1735 m_indexed = true;
1736 Timer scoped_timer (__PRETTY_FUNCTION__,
1737 "SymbolFileDWARF::Index (%s)",
1738 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1739
1740 DWARFDebugInfo* debug_info = DebugInfo();
1741 if (debug_info)
1742 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001743 m_aranges.reset(new DWARFDebugAranges());
1744
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001745 uint32_t cu_idx = 0;
1746 const uint32_t num_compile_units = GetNumCompileUnits();
1747 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1748 {
1749 DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1750
1751 bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
1752
Greg Claytonc685f8e2010-09-15 04:15:46 +00001753 cu->Index (cu_idx,
1754 m_function_basename_index,
1755 m_function_fullname_index,
1756 m_function_method_index,
1757 m_function_selector_index,
Greg Clayton450e3f32010-10-12 02:24:53 +00001758 m_objc_class_selectors_index,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001759 m_global_index,
Greg Clayton69b04882010-10-15 02:03:22 +00001760 m_type_index,
1761 m_namespace_index,
Greg Clayton016a95e2010-09-14 02:20:48 +00001762 DebugRanges(),
1763 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001764
1765 // Keep memory down by clearing DIEs if this generate function
1766 // caused them to be parsed
1767 if (clear_dies)
1768 cu->ClearDIEs (true);
1769 }
1770
Greg Clayton016a95e2010-09-14 02:20:48 +00001771 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001772
Greg Clayton24739922010-10-13 03:15:28 +00001773#if defined (ENABLE_DEBUG_PRINTF)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001774 StreamFile s(stdout);
Greg Clayton24739922010-10-13 03:15:28 +00001775 s.Printf ("DWARF index for (%s) '%s/%s':",
1776 GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1777 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1778 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonc685f8e2010-09-15 04:15:46 +00001779 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1780 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1781 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1782 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
Greg Clayton450e3f32010-10-12 02:24:53 +00001783 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001784 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001785 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
1786 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
1787
Greg Claytonc685f8e2010-09-15 04:15:46 +00001788#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001789 }
1790}
1791
1792uint32_t
1793SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1794{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001795 DWARFDebugInfo* info = DebugInfo();
1796 if (info == NULL)
1797 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001798
1799 // If we aren't appending the results to this list, then clear the list
1800 if (!append)
1801 variables.Clear();
1802
1803 // Remember how many variables are in the list before we search in case
1804 // we are appending the results to a variable list.
1805 const uint32_t original_size = variables.GetSize();
1806
1807 // Index the DWARF if we haven't already
1808 if (!m_indexed)
1809 Index ();
1810
Greg Claytonc685f8e2010-09-15 04:15:46 +00001811 SymbolContext sc;
1812 sc.module_sp = m_obj_file->GetModule()->GetSP();
1813 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001814
Greg Claytonc685f8e2010-09-15 04:15:46 +00001815 DWARFCompileUnit* cu = NULL;
1816 DWARFCompileUnit* prev_cu = NULL;
1817 const DWARFDebugInfoEntry* die = NULL;
1818 std::vector<NameToDIE::Info> die_info_array;
1819 const size_t num_matches = m_global_index.Find(name, die_info_array);
1820 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001821 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001822 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1823
1824 if (cu != prev_cu)
1825 cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001826
Greg Claytonc685f8e2010-09-15 04:15:46 +00001827 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001828
Greg Claytonc685f8e2010-09-15 04:15:46 +00001829 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
1830 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001831
Greg Claytonc685f8e2010-09-15 04:15:46 +00001832 ParseVariables(sc, cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
1833
1834 if (variables.GetSize() - original_size >= max_matches)
1835 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001836 }
1837
1838 // Return the number of variable that were appended to the list
1839 return variables.GetSize() - original_size;
1840}
1841
1842uint32_t
1843SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1844{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001845 DWARFDebugInfo* info = DebugInfo();
1846 if (info == NULL)
1847 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001848
1849 // If we aren't appending the results to this list, then clear the list
1850 if (!append)
1851 variables.Clear();
1852
1853 // Remember how many variables are in the list before we search in case
1854 // we are appending the results to a variable list.
1855 const uint32_t original_size = variables.GetSize();
1856
1857 // Index the DWARF if we haven't already
1858 if (!m_indexed)
1859 Index ();
1860
Greg Claytonc685f8e2010-09-15 04:15:46 +00001861 SymbolContext sc;
1862 sc.module_sp = m_obj_file->GetModule()->GetSP();
1863 assert (sc.module_sp);
1864
1865 DWARFCompileUnit* cu = NULL;
1866 DWARFCompileUnit* prev_cu = NULL;
1867 const DWARFDebugInfoEntry* die = NULL;
1868 std::vector<NameToDIE::Info> die_info_array;
1869 const size_t num_matches = m_global_index.Find(regex, die_info_array);
1870 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001871 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001872 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1873
1874 if (cu != prev_cu)
1875 cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001876
Greg Claytonc685f8e2010-09-15 04:15:46 +00001877 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001878
Greg Claytonc685f8e2010-09-15 04:15:46 +00001879 sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT32_MAX);
1880 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001881
Greg Claytonc685f8e2010-09-15 04:15:46 +00001882 ParseVariables(sc, cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001883
Greg Claytonc685f8e2010-09-15 04:15:46 +00001884 if (variables.GetSize() - original_size >= max_matches)
1885 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001886 }
1887
1888 // Return the number of variable that were appended to the list
1889 return variables.GetSize() - original_size;
1890}
1891
1892
Greg Clayton0c5cd902010-06-28 21:30:43 +00001893void
1894SymbolFileDWARF::FindFunctions
1895(
1896 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001897 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00001898 SymbolContextList& sc_list
1899)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001901 DWARFDebugInfo* info = DebugInfo();
1902 if (info == NULL)
1903 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001904
Greg Claytonc685f8e2010-09-15 04:15:46 +00001905 SymbolContext sc;
1906 sc.module_sp = m_obj_file->GetModule()->GetSP();
1907 assert (sc.module_sp);
1908
1909 DWARFCompileUnit* cu = NULL;
1910 DWARFCompileUnit* prev_cu = NULL;
1911 const DWARFDebugInfoEntry* die = NULL;
1912 std::vector<NameToDIE::Info> die_info_array;
1913 const size_t num_matches = name_to_die.Find(name, die_info_array);
1914 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
1915 {
1916 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1917
1918 if (cu != prev_cu)
1919 cu->ExtractDIEsIfNeeded (false);
1920
1921 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1922 if (GetFunction (cu, die, sc))
1923 {
1924 // We found the function, so we should find the line table
1925 // and line table entry as well
1926 LineTable *line_table = sc.comp_unit->GetLineTable();
1927 if (line_table == NULL)
1928 {
1929 if (ParseCompileUnitLineTable(sc))
1930 line_table = sc.comp_unit->GetLineTable();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001931 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001932 if (line_table != NULL)
1933 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1934
1935 sc_list.Append(sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001936 }
1937 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001938}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001939
Greg Claytonc685f8e2010-09-15 04:15:46 +00001940
1941void
1942SymbolFileDWARF::FindFunctions
1943(
1944 const RegularExpression &regex,
1945 const NameToDIE &name_to_die,
1946 SymbolContextList& sc_list
1947)
1948{
1949 DWARFDebugInfo* info = DebugInfo();
1950 if (info == NULL)
1951 return;
1952
1953 SymbolContext sc;
1954 sc.module_sp = m_obj_file->GetModule()->GetSP();
1955 assert (sc.module_sp);
1956
1957 DWARFCompileUnit* cu = NULL;
1958 DWARFCompileUnit* prev_cu = NULL;
1959 const DWARFDebugInfoEntry* die = NULL;
1960 std::vector<NameToDIE::Info> die_info_array;
1961 const size_t num_matches = name_to_die.Find(regex, die_info_array);
1962 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
1963 {
1964 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1965
1966 if (cu != prev_cu)
1967 cu->ExtractDIEsIfNeeded (false);
1968
1969 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1970 if (GetFunction (cu, die, sc))
1971 {
1972 // We found the function, so we should find the line table
1973 // and line table entry as well
1974 LineTable *line_table = sc.comp_unit->GetLineTable();
1975 if (line_table == NULL)
1976 {
1977 if (ParseCompileUnitLineTable(sc))
1978 line_table = sc.comp_unit->GetLineTable();
1979 }
1980 if (line_table != NULL)
1981 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1982
1983 sc_list.Append(sc);
1984 }
1985 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00001986}
1987
1988uint32_t
1989SymbolFileDWARF::FindFunctions
1990(
1991 const ConstString &name,
1992 uint32_t name_type_mask,
1993 bool append,
1994 SymbolContextList& sc_list
1995)
1996{
1997 Timer scoped_timer (__PRETTY_FUNCTION__,
1998 "SymbolFileDWARF::FindFunctions (name = '%s')",
1999 name.AsCString());
2000
Greg Clayton0c5cd902010-06-28 21:30:43 +00002001 // If we aren't appending the results to this list, then clear the list
2002 if (!append)
2003 sc_list.Clear();
2004
2005 // Remember how many sc_list are in the list before we search in case
2006 // we are appending the results to a variable list.
2007 uint32_t original_size = sc_list.GetSize();
2008
2009 // Index the DWARF if we haven't already
2010 if (!m_indexed)
2011 Index ();
2012
2013 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002014 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002015
2016 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002017 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002018
2019 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002020 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002021
2022 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002023 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002024
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002025 // Return the number of variable that were appended to the list
2026 return sc_list.GetSize() - original_size;
2027}
2028
2029
2030uint32_t
2031SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2032{
2033 Timer scoped_timer (__PRETTY_FUNCTION__,
2034 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2035 regex.GetText());
2036
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002037 // If we aren't appending the results to this list, then clear the list
2038 if (!append)
2039 sc_list.Clear();
2040
2041 // Remember how many sc_list are in the list before we search in case
2042 // we are appending the results to a variable list.
2043 uint32_t original_size = sc_list.GetSize();
2044
2045 // Index the DWARF if we haven't already
2046 if (!m_indexed)
2047 Index ();
2048
Greg Claytonc685f8e2010-09-15 04:15:46 +00002049 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002050
Greg Claytonc685f8e2010-09-15 04:15:46 +00002051 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002052
2053 // Return the number of variable that were appended to the list
2054 return sc_list.GetSize() - original_size;
2055}
2056
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002057uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002058SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002059{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002060 DWARFDebugInfo* info = DebugInfo();
2061 if (info == NULL)
2062 return 0;
2063
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002064 // If we aren't appending the results to this list, then clear the list
2065 if (!append)
2066 types.Clear();
2067
Greg Clayton6dbd3982010-09-15 05:51:24 +00002068 // Index if we already haven't to make sure the compile units
2069 // get indexed and make their global DIE index list
2070 if (!m_indexed)
2071 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002072
Greg Claytonc685f8e2010-09-15 04:15:46 +00002073 const uint32_t initial_types_size = types.GetSize();
2074 DWARFCompileUnit* cu = NULL;
2075 DWARFCompileUnit* prev_cu = NULL;
2076 const DWARFDebugInfoEntry* die = NULL;
2077 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002078 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002079 for (size_t i=0; i<num_matches; ++i, prev_cu = cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002080 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002081 cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2082
2083 if (cu != prev_cu)
2084 cu->ExtractDIEsIfNeeded (false);
2085
2086 die = cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2087
2088 Type *matching_type = ResolveType (cu, die);
2089 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002090 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002091 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002092 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonc685f8e2010-09-15 04:15:46 +00002093 assert (type_sp.get() != NULL);
2094 types.InsertUnique (type_sp);
2095 if (types.GetSize() >= max_matches)
2096 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002097 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002098 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002099 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002100}
2101
2102
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002103uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002104SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002105{
2106 // Remember how many sc_list are in the list before we search in case
2107 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002108 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002109
2110 const uint32_t num_die_offsets = die_offsets.size();
2111 // Parse all of the types we found from the pubtypes matches
2112 uint32_t i;
2113 uint32_t num_matches = 0;
2114 for (i = 0; i < num_die_offsets; ++i)
2115 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002116 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2117 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002118 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002119 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002120 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002121 assert (type_sp.get() != NULL);
2122 types.InsertUnique (type_sp);
2123 ++num_matches;
2124 if (num_matches >= max_matches)
2125 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002126 }
2127 }
2128
2129 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002130 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002131}
2132
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002133
2134size_t
2135SymbolFileDWARF::ParseChildParameters
2136(
2137 const SymbolContext& sc,
2138 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002139 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002140 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002141 bool skip_artificial,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002142 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002143 std::vector<clang_type_t>& function_param_types,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002144 std::vector<clang::ParmVarDecl*>& function_param_decls
2145)
2146{
2147 if (parent_die == NULL)
2148 return 0;
2149
Greg Claytond88d7592010-09-15 08:33:30 +00002150 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2151
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002152 size_t count = 0;
2153 const DWARFDebugInfoEntry *die;
2154 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2155 {
2156 dw_tag_t tag = die->Tag();
2157 switch (tag)
2158 {
2159 case DW_TAG_formal_parameter:
2160 {
2161 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002162 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002163 if (num_attributes > 0)
2164 {
2165 const char *name = NULL;
2166 Declaration decl;
2167 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002168 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002169 // one of None, Auto, Register, Extern, Static, PrivateExtern
2170
Sean Callanane2ef6e32010-09-23 03:01:22 +00002171 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002172 uint32_t i;
2173 for (i=0; i<num_attributes; ++i)
2174 {
2175 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2176 DWARFFormValue form_value;
2177 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2178 {
2179 switch (attr)
2180 {
2181 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2182 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2183 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2184 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2185 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002186 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002187 case DW_AT_location:
2188 // if (form_value.BlockData())
2189 // {
2190 // const DataExtractor& debug_info_data = debug_info();
2191 // uint32_t block_length = form_value.Unsigned();
2192 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2193 // }
2194 // else
2195 // {
2196 // }
2197 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002198 case DW_AT_const_value:
2199 case DW_AT_default_value:
2200 case DW_AT_description:
2201 case DW_AT_endianity:
2202 case DW_AT_is_optional:
2203 case DW_AT_segment:
2204 case DW_AT_variable_parameter:
2205 default:
2206 case DW_AT_abstract_origin:
2207 case DW_AT_sibling:
2208 break;
2209 }
2210 }
2211 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002212
Greg Clayton0fffff52010-09-24 05:15:53 +00002213 bool skip = false;
2214 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002215 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002216 if (is_artificial)
2217 skip = true;
2218 else
2219 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002220
Greg Clayton0fffff52010-09-24 05:15:53 +00002221 // HACK: Objective C formal parameters "self" and "_cmd"
2222 // are not marked as artificial in the DWARF...
2223 CompileUnit *cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2224 if (cu && (cu->GetLanguage() == eLanguageTypeObjC || cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
2225 {
2226 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2227 skip = true;
2228 }
2229 }
2230 }
2231
2232 if (!skip)
2233 {
2234 Type *type = ResolveTypeUID(param_type_die_offset);
2235 if (type)
2236 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002237 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002238
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002239 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002240 assert(param_var_decl);
2241 function_param_decls.push_back(param_var_decl);
2242 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002243 }
2244 }
2245 }
2246 break;
2247
2248 default:
2249 break;
2250 }
2251 }
2252 return count;
2253}
2254
2255size_t
2256SymbolFileDWARF::ParseChildEnumerators
2257(
2258 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002259 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002260 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002261 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002262 const DWARFDebugInfoEntry *parent_die
2263)
2264{
2265 if (parent_die == NULL)
2266 return 0;
2267
2268 size_t enumerators_added = 0;
2269 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002270 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2271
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002272 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2273 {
2274 const dw_tag_t tag = die->Tag();
2275 if (tag == DW_TAG_enumerator)
2276 {
2277 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002278 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002279 if (num_child_attributes > 0)
2280 {
2281 const char *name = NULL;
2282 bool got_value = false;
2283 int64_t enum_value = 0;
2284 Declaration decl;
2285
2286 uint32_t i;
2287 for (i=0; i<num_child_attributes; ++i)
2288 {
2289 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2290 DWARFFormValue form_value;
2291 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2292 {
2293 switch (attr)
2294 {
2295 case DW_AT_const_value:
2296 got_value = true;
2297 enum_value = form_value.Unsigned();
2298 break;
2299
2300 case DW_AT_name:
2301 name = form_value.AsCString(&get_debug_str_data());
2302 break;
2303
2304 case DW_AT_description:
2305 default:
2306 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2307 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2308 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2309 case DW_AT_sibling:
2310 break;
2311 }
2312 }
2313 }
2314
2315 if (name && name[0] && got_value)
2316 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002317 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2318 enumerator_clang_type,
2319 decl,
2320 name,
2321 enum_value,
2322 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002323 ++enumerators_added;
2324 }
2325 }
2326 }
2327 }
2328 return enumerators_added;
2329}
2330
2331void
2332SymbolFileDWARF::ParseChildArrayInfo
2333(
2334 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002335 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002336 const DWARFDebugInfoEntry *parent_die,
2337 int64_t& first_index,
2338 std::vector<uint64_t>& element_orders,
2339 uint32_t& byte_stride,
2340 uint32_t& bit_stride
2341)
2342{
2343 if (parent_die == NULL)
2344 return;
2345
2346 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002347 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002348 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2349 {
2350 const dw_tag_t tag = die->Tag();
2351 switch (tag)
2352 {
2353 case DW_TAG_enumerator:
2354 {
2355 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002356 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002357 if (num_child_attributes > 0)
2358 {
2359 const char *name = NULL;
2360 bool got_value = false;
2361 int64_t enum_value = 0;
2362
2363 uint32_t i;
2364 for (i=0; i<num_child_attributes; ++i)
2365 {
2366 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2367 DWARFFormValue form_value;
2368 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2369 {
2370 switch (attr)
2371 {
2372 case DW_AT_const_value:
2373 got_value = true;
2374 enum_value = form_value.Unsigned();
2375 break;
2376
2377 case DW_AT_name:
2378 name = form_value.AsCString(&get_debug_str_data());
2379 break;
2380
2381 case DW_AT_description:
2382 default:
2383 case DW_AT_decl_file:
2384 case DW_AT_decl_line:
2385 case DW_AT_decl_column:
2386 case DW_AT_sibling:
2387 break;
2388 }
2389 }
2390 }
2391 }
2392 }
2393 break;
2394
2395 case DW_TAG_subrange_type:
2396 {
2397 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002398 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002399 if (num_child_attributes > 0)
2400 {
2401 const char *name = NULL;
2402 bool got_value = false;
2403 uint64_t byte_size = 0;
2404 int64_t enum_value = 0;
2405 uint64_t num_elements = 0;
2406 uint64_t lower_bound = 0;
2407 uint64_t upper_bound = 0;
2408 uint32_t i;
2409 for (i=0; i<num_child_attributes; ++i)
2410 {
2411 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2412 DWARFFormValue form_value;
2413 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2414 {
2415 switch (attr)
2416 {
2417 case DW_AT_const_value:
2418 got_value = true;
2419 enum_value = form_value.Unsigned();
2420 break;
2421
2422 case DW_AT_name:
2423 name = form_value.AsCString(&get_debug_str_data());
2424 break;
2425
2426 case DW_AT_count:
2427 num_elements = form_value.Unsigned();
2428 break;
2429
2430 case DW_AT_bit_stride:
2431 bit_stride = form_value.Unsigned();
2432 break;
2433
2434 case DW_AT_byte_stride:
2435 byte_stride = form_value.Unsigned();
2436 break;
2437
2438 case DW_AT_byte_size:
2439 byte_size = form_value.Unsigned();
2440 break;
2441
2442 case DW_AT_lower_bound:
2443 lower_bound = form_value.Unsigned();
2444 break;
2445
2446 case DW_AT_upper_bound:
2447 upper_bound = form_value.Unsigned();
2448 break;
2449
2450 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002451 case DW_AT_abstract_origin:
2452 case DW_AT_accessibility:
2453 case DW_AT_allocated:
2454 case DW_AT_associated:
2455 case DW_AT_data_location:
2456 case DW_AT_declaration:
2457 case DW_AT_description:
2458 case DW_AT_sibling:
2459 case DW_AT_threads_scaled:
2460 case DW_AT_type:
2461 case DW_AT_visibility:
2462 break;
2463 }
2464 }
2465 }
2466
2467 if (upper_bound > lower_bound)
2468 num_elements = upper_bound - lower_bound + 1;
2469
2470 if (num_elements > 0)
2471 element_orders.push_back (num_elements);
2472 }
2473 }
2474 break;
2475 }
2476 }
2477}
2478
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002479TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002480SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002481{
2482 TypeSP type_sp;
2483 if (die != NULL)
2484 {
2485 assert(cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002486 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002487 if (type_ptr == NULL)
2488 {
2489 SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
Greg Clayton1be10fc2010-09-29 01:12:09 +00002490 type_sp = ParseType(sc, cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002491 }
2492 else if (type_ptr != DIE_IS_BEING_PARSED)
2493 {
2494 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002495 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002496 }
2497
2498 }
2499 return type_sp;
2500}
2501
2502clang::DeclContext *
2503SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2504{
2505 if (die_offset != DW_INVALID_OFFSET)
2506 {
2507 DWARFCompileUnitSP cu_sp;
2508 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2509 return GetClangDeclContextForDIE (cu_sp.get(), die);
2510 }
2511 return NULL;
2512}
2513
2514
2515
2516clang::DeclContext *
Greg Clayton0fffff52010-09-24 05:15:53 +00002517SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002518{
2519 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2520 if (pos != m_die_to_decl_ctx.end())
2521 return pos->second;
2522
2523 while (die != NULL)
2524 {
2525 switch (die->Tag())
2526 {
2527 case DW_TAG_namespace:
2528 {
2529 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
2530 if (namespace_name)
2531 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002532 Declaration decl; // TODO: fill in the decl object
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002533 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002534 if (namespace_decl)
2535 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2536 return namespace_decl;
2537 }
2538 }
2539 break;
2540
2541 default:
2542 break;
2543 }
2544 clang::DeclContext *decl_ctx;
2545 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
2546 if (decl_ctx)
2547 return decl_ctx;
2548
2549 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2550 if (decl_ctx)
2551 return decl_ctx;
2552
2553 die = die->GetParent();
2554 }
Greg Clayton7a345282010-11-09 23:46:37 +00002555 // Right now we have only one translation unit per module...
2556 if (m_clang_tu_decl == NULL)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002557 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Greg Clayton7a345282010-11-09 23:46:37 +00002558 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002559}
2560
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002561// This function can be used when a DIE is found that is a forward declaration
2562// DIE and we want to try and find a type that has the complete definition.
2563TypeSP
2564SymbolFileDWARF::FindDefinitionTypeForDIE (
2565 DWARFCompileUnit* cu,
2566 const DWARFDebugInfoEntry *die,
2567 const ConstString &type_name
2568)
2569{
2570 TypeSP type_sp;
2571
2572 if (cu == NULL || die == NULL || !type_name)
2573 return type_sp;
2574
2575 const dw_tag_t type_tag = die->Tag();
2576 std::vector<NameToDIE::Info> die_info_array;
2577 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2578 if (num_matches > 0)
2579 {
2580 DWARFCompileUnit* type_cu = NULL;
2581 DWARFCompileUnit* curr_cu = cu;
2582 DWARFDebugInfo *info = DebugInfo();
2583 for (size_t i=0; i<num_matches; ++i)
2584 {
2585 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2586
2587 if (type_cu != curr_cu)
2588 {
2589 type_cu->ExtractDIEsIfNeeded (false);
2590 curr_cu = type_cu;
2591 }
2592
2593 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2594
2595 if (type_die != die && type_die->Tag() == type_tag)
2596 {
2597 // Hold off on comparing parent DIE tags until
2598 // we know what happens with stuff in namespaces
2599 // for gcc and clang...
2600 //DWARFDebugInfoEntry *parent_die = die->GetParent();
2601 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2602 //if (parent_die->Tag() == parent_type_die->Tag())
2603 {
2604 Type *resolved_type = ResolveType (type_cu, type_die, false);
2605 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2606 {
2607 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2608 die->GetOffset(),
2609 dwarf_cu->GetOffset(),
2610 m_obj_file->GetFileSpec().GetFilename().AsCString(),
2611 type_die->GetOffset(),
2612 type_cu->GetOffset());
2613
2614 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002615 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00002616 if (!type_sp)
2617 {
2618 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2619 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002620 break;
2621 }
2622 }
2623 }
2624 }
2625 }
2626 return type_sp;
2627}
2628
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002629TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002630SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002631{
2632 TypeSP type_sp;
2633
Greg Clayton1be10fc2010-09-29 01:12:09 +00002634 if (type_is_new_ptr)
2635 *type_is_new_ptr = false;
2636
Sean Callananc7fbf732010-08-06 00:32:49 +00002637 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002638 if (die != NULL)
2639 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002640 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002641 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00002642 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002643 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002644 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002645 if (type_is_new_ptr)
2646 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002647
Greg Clayton594e5ed2010-09-27 21:07:38 +00002648 const dw_tag_t tag = die->Tag();
2649
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002650 bool is_forward_declaration = false;
2651 DWARFDebugInfoEntry::Attributes attributes;
2652 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00002653 ConstString type_name_const_str;
Greg Clayton4957bf62010-09-30 21:49:03 +00002654 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002655 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002656
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002657 dw_attr_t attr;
2658
2659 switch (tag)
2660 {
2661 case DW_TAG_base_type:
2662 case DW_TAG_pointer_type:
2663 case DW_TAG_reference_type:
2664 case DW_TAG_typedef:
2665 case DW_TAG_const_type:
2666 case DW_TAG_restrict_type:
2667 case DW_TAG_volatile_type:
2668 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002669 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002670 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002671
Greg Claytond88d7592010-09-15 08:33:30 +00002672 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002673 Declaration decl;
2674 uint32_t encoding = 0;
2675 size_t byte_size = 0;
2676 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2677
2678 if (num_attributes > 0)
2679 {
2680 uint32_t i;
2681 for (i=0; i<num_attributes; ++i)
2682 {
2683 attr = attributes.AttributeAtIndex(i);
2684 DWARFFormValue form_value;
2685 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2686 {
2687 switch (attr)
2688 {
2689 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2690 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2691 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2692 case DW_AT_name:
2693 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00002694 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002695 break;
2696 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2697 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2698 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2699 default:
2700 case DW_AT_sibling:
2701 break;
2702 }
2703 }
2704 }
2705 }
2706
Greg Claytonc93237c2010-10-01 20:48:32 +00002707 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") type => 0x%8.8x\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
2708
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002709 switch (tag)
2710 {
2711 default:
2712 case DW_TAG_base_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002713 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
2714 encoding,
2715 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002716 break;
2717
2718 case DW_TAG_pointer_type:
2719 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002720 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002721 encoding_data_type = Type::eEncodingIsPointerUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002722 break;
2723
2724 case DW_TAG_reference_type:
2725 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002726 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002727 encoding_data_type = Type::eEncodingIsLValueReferenceUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002728 break;
2729
2730 case DW_TAG_typedef:
2731 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002732 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002733 encoding_data_type = Type::eEncodingIsTypedefUID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002734 break;
2735
2736 case DW_TAG_const_type:
2737 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002738 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002739 encoding_data_type = Type::eEncodingIsConstUID; //ClangASTContext::AddConstModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002740 break;
2741
2742 case DW_TAG_restrict_type:
2743 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002744 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002745 encoding_data_type = Type::eEncodingIsRestrictUID; //ClangASTContext::AddRestrictModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002746 break;
2747
2748 case DW_TAG_volatile_type:
2749 // The encoding_uid will be embedded into the
Greg Clayton1be10fc2010-09-29 01:12:09 +00002750 // Type object and will be looked up when the Type::GetClangType()
Greg Clayton4957bf62010-09-30 21:49:03 +00002751 encoding_data_type = Type::eEncodingIsVolatileUID; //ClangASTContext::AddVolatileModifier (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002752 break;
2753 }
2754
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002755 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
2756 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
2757 {
2758 static ConstString g_objc_type_name_id("id");
2759 static ConstString g_objc_type_name_Class("Class");
2760 static ConstString g_objc_type_name_selector("SEL");
2761
Greg Clayton24739922010-10-13 03:15:28 +00002762 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002763 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002764 clang_type = ast.GetBuiltInType_objc_id();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002765 }
Greg Clayton24739922010-10-13 03:15:28 +00002766 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002767 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002768 clang_type = ast.GetBuiltInType_objc_Class();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002769 }
Greg Clayton24739922010-10-13 03:15:28 +00002770 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002771 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002772 clang_type = ast.GetBuiltInType_objc_selector();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002773 }
2774 }
2775
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002776 type_sp.reset( new Type (die->GetOffset(),
2777 this,
2778 type_name_const_str,
2779 byte_size,
2780 NULL,
2781 encoding_uid,
2782 encoding_data_type,
2783 &decl,
2784 clang_type,
2785 clang_type == NULL));
2786
Greg Clayton594e5ed2010-09-27 21:07:38 +00002787 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002788
2789// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2790// if (encoding_type != NULL)
2791// {
2792// if (encoding_type != DIE_IS_BEING_PARSED)
2793// type_sp->SetEncodingType(encoding_type);
2794// else
2795// m_indirect_fixups.push_back(type_sp.get());
2796// }
2797 }
2798 break;
2799
2800 case DW_TAG_structure_type:
2801 case DW_TAG_union_type:
2802 case DW_TAG_class_type:
2803 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002804 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002805 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002806
2807 size_t byte_size = 0;
Greg Clayton9e409562010-07-28 02:04:09 +00002808 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002809 //bool struct_is_class = false;
2810 Declaration decl;
Greg Claytond88d7592010-09-15 08:33:30 +00002811 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002812 if (num_attributes > 0)
2813 {
2814 uint32_t i;
2815 for (i=0; i<num_attributes; ++i)
2816 {
2817 attr = attributes.AttributeAtIndex(i);
2818 DWARFFormValue form_value;
2819 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2820 {
2821 switch (attr)
2822 {
Greg Clayton9e409562010-07-28 02:04:09 +00002823 case DW_AT_decl_file:
2824 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
2825 break;
2826
2827 case DW_AT_decl_line:
2828 decl.SetLine(form_value.Unsigned());
2829 break;
2830
2831 case DW_AT_decl_column:
2832 decl.SetColumn(form_value.Unsigned());
2833 break;
2834
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002835 case DW_AT_name:
2836 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00002837 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002838 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002839
2840 case DW_AT_byte_size:
2841 byte_size = form_value.Unsigned();
2842 break;
2843
2844 case DW_AT_accessibility:
2845 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2846 break;
2847
2848 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00002849 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00002850 break;
2851
2852 case DW_AT_APPLE_runtime_class:
2853 class_language = (LanguageType)form_value.Signed();
2854 break;
2855
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002856 case DW_AT_allocated:
2857 case DW_AT_associated:
2858 case DW_AT_data_location:
2859 case DW_AT_description:
2860 case DW_AT_start_scope:
2861 case DW_AT_visibility:
2862 default:
2863 case DW_AT_sibling:
2864 break;
2865 }
2866 }
2867 }
2868 }
2869
Greg Claytonc93237c2010-10-01 20:48:32 +00002870 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
2871
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002872 int tag_decl_kind = -1;
Sean Callananc7fbf732010-08-06 00:32:49 +00002873 AccessType default_accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002874 if (tag == DW_TAG_structure_type)
2875 {
2876 tag_decl_kind = clang::TTK_Struct;
Sean Callananc7fbf732010-08-06 00:32:49 +00002877 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002878 }
2879 else if (tag == DW_TAG_union_type)
2880 {
2881 tag_decl_kind = clang::TTK_Union;
Sean Callananc7fbf732010-08-06 00:32:49 +00002882 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002883 }
2884 else if (tag == DW_TAG_class_type)
2885 {
2886 tag_decl_kind = clang::TTK_Class;
Sean Callananc7fbf732010-08-06 00:32:49 +00002887 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002888 }
2889
Greg Clayton24739922010-10-13 03:15:28 +00002890
Greg Claytonc615ce42010-11-09 04:42:43 +00002891 if (is_forward_declaration)
2892 {
2893 // We have a forward declaration to a type and we need
2894 // to try and find a full declaration. We look in the
2895 // current type index just in case we have a forward
2896 // declaration followed by an actual declarations in the
2897 // DWARF. If this fails, we need to look elsewhere...
2898
2899 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
2900
2901 if (!type_sp)
2902 {
2903 // We weren't able to find a full declaration in
2904 // this DWARF, see if we have a declaration anywhere
2905 // else...
2906 if (m_debug_map_symfile)
2907 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
2908 }
2909 if (type_sp)
2910 return type_sp;
2911 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002912 assert (tag_decl_kind != -1);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002913 bool clang_type_was_created = false;
2914 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
2915 if (clang_type == NULL)
2916 {
2917 clang_type_was_created = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002918 clang_type = ast.CreateRecordType (type_name_cstr,
2919 tag_decl_kind,
2920 GetClangDeclContextForDIE (dwarf_cu, die),
2921 class_language);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002922 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002923
Greg Clayton6adffa22010-09-28 01:04:25 +00002924 // Store a forward declaration to this class type in case any
2925 // parameters in any class methods need it for the clang
2926 // types for function prototypes.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002927 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton16c880f2010-09-30 22:25:09 +00002928 const bool is_forward_decl = die->HasChildren();
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002929 type_sp.reset (new Type (die->GetOffset(),
2930 this,
2931 type_name_const_str,
2932 byte_size,
2933 NULL,
2934 LLDB_INVALID_UID,
2935 Type::eEncodingIsUID,
2936 &decl,
2937 clang_type,
2938 is_forward_decl));
2939
Greg Clayton594e5ed2010-09-27 21:07:38 +00002940 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002941
Greg Clayton40328bf2010-11-08 02:05:08 +00002942 if (die->HasChildren() == false && is_forward_declaration == false)
Greg Clayton1be10fc2010-09-29 01:12:09 +00002943 {
Greg Clayton4957bf62010-09-30 21:49:03 +00002944 // No children for this struct/union/class, lets finish it
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002945 ast.StartTagDeclarationDefinition (clang_type);
2946 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton4957bf62010-09-30 21:49:03 +00002947 }
2948 else if (clang_type_was_created)
2949 {
2950 // Leave this as a forward declaration until we need
2951 // to know the details of the type. lldb_private::Type
2952 // will automatically call the SymbolFile virtual function
2953 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
2954 // When the definition needs to be defined.
Greg Clayton1be10fc2010-09-29 01:12:09 +00002955 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00002956 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002957 }
Greg Clayton4957bf62010-09-30 21:49:03 +00002958
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002959 }
2960 break;
2961
2962 case DW_TAG_enumeration_type:
2963 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002964 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002965 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002966
2967 size_t byte_size = 0;
2968 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2969 Declaration decl;
2970
Greg Claytond88d7592010-09-15 08:33:30 +00002971 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002972 if (num_attributes > 0)
2973 {
2974 uint32_t i;
2975
2976 for (i=0; i<num_attributes; ++i)
2977 {
2978 attr = attributes.AttributeAtIndex(i);
2979 DWARFFormValue form_value;
2980 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2981 {
2982 switch (attr)
2983 {
Greg Clayton7a345282010-11-09 23:46:37 +00002984 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2985 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2986 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002987 case DW_AT_name:
2988 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00002989 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002990 break;
Greg Clayton7a345282010-11-09 23:46:37 +00002991 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2992 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2993 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
2994 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002995 case DW_AT_allocated:
2996 case DW_AT_associated:
2997 case DW_AT_bit_stride:
2998 case DW_AT_byte_stride:
2999 case DW_AT_data_location:
3000 case DW_AT_description:
3001 case DW_AT_start_scope:
3002 case DW_AT_visibility:
3003 case DW_AT_specification:
3004 case DW_AT_abstract_origin:
3005 case DW_AT_sibling:
3006 break;
3007 }
3008 }
3009 }
3010
Greg Claytonc93237c2010-10-01 20:48:32 +00003011 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3012
Greg Clayton1be10fc2010-09-29 01:12:09 +00003013 clang_type_t enumerator_clang_type = NULL;
3014 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3015 if (clang_type == NULL)
3016 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003017 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3018 DW_ATE_signed,
3019 byte_size * 8);
3020 clang_type = ast.CreateEnumerationType (decl,
3021 type_name_cstr,
3022 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003023 }
3024 else
3025 {
3026 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3027 assert (enumerator_clang_type != NULL);
3028 }
3029
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003030 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003031 type_sp.reset( new Type (die->GetOffset(),
3032 this,
3033 type_name_const_str,
3034 byte_size,
3035 NULL,
3036 encoding_uid,
3037 Type::eEncodingIsUID,
3038 &decl,
3039 clang_type,
3040 true));
3041
Greg Clayton594e5ed2010-09-27 21:07:38 +00003042 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003043
Greg Clayton1be10fc2010-09-29 01:12:09 +00003044 // Leave this as a forward declaration until we need
3045 // to know the details of the type. lldb_private::Type
3046 // will automatically call the SymbolFile virtual function
3047 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3048 // When the definition needs to be defined.
3049 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003050 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003051
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003052 }
3053 }
3054 break;
3055
Jim Inghamb0be4422010-08-12 01:20:14 +00003056 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003057 case DW_TAG_subprogram:
3058 case DW_TAG_subroutine_type:
3059 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003060 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003061 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003062
3063 const char *mangled = NULL;
3064 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3065 Declaration decl;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003066 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003067 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003068 bool is_static = false;
3069 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003070 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003071
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003072 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003073 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003074
3075
Greg Claytond88d7592010-09-15 08:33:30 +00003076 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003077 if (num_attributes > 0)
3078 {
3079 uint32_t i;
3080 for (i=0; i<num_attributes; ++i)
3081 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003082 const dw_attr_t attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003083 DWARFFormValue form_value;
3084 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3085 {
3086 switch (attr)
3087 {
3088 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3089 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3090 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3091 case DW_AT_name:
3092 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003093 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003094 break;
3095
3096 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3097 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003098 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003099 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003100 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3101 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003102 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3103
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003104 case DW_AT_external:
3105 if (form_value.Unsigned())
3106 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003107 if (storage == clang::SC_None)
3108 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003109 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003110 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003111 }
3112 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003113
3114 case DW_AT_allocated:
3115 case DW_AT_associated:
3116 case DW_AT_address_class:
3117 case DW_AT_artificial:
3118 case DW_AT_calling_convention:
3119 case DW_AT_data_location:
3120 case DW_AT_elemental:
3121 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003122 case DW_AT_frame_base:
3123 case DW_AT_high_pc:
3124 case DW_AT_low_pc:
3125 case DW_AT_object_pointer:
3126 case DW_AT_prototyped:
3127 case DW_AT_pure:
3128 case DW_AT_ranges:
3129 case DW_AT_recursive:
3130 case DW_AT_return_addr:
3131 case DW_AT_segment:
3132 case DW_AT_specification:
3133 case DW_AT_start_scope:
3134 case DW_AT_static_link:
3135 case DW_AT_trampoline:
3136 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003137 case DW_AT_vtable_elem_location:
3138 case DW_AT_abstract_origin:
3139 case DW_AT_description:
3140 case DW_AT_sibling:
3141 break;
3142 }
3143 }
3144 }
Greg Clayton24739922010-10-13 03:15:28 +00003145 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003146
Greg Clayton24739922010-10-13 03:15:28 +00003147 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00003148
Greg Clayton24739922010-10-13 03:15:28 +00003149 clang_type_t return_clang_type = NULL;
3150 Type *func_type = NULL;
3151
3152 if (type_die_offset != DW_INVALID_OFFSET)
3153 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003154
Greg Clayton24739922010-10-13 03:15:28 +00003155 if (func_type)
3156 return_clang_type = func_type->GetClangForwardType();
3157 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003158 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003159
Greg Claytonf51de672010-10-01 02:31:07 +00003160
Greg Clayton24739922010-10-13 03:15:28 +00003161 std::vector<clang_type_t> function_param_types;
3162 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003163
Greg Clayton24739922010-10-13 03:15:28 +00003164 // Parse the function children for the parameters
3165 if (die->HasChildren())
3166 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003167 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003168 ParseChildParameters (sc,
3169 type_sp,
3170 dwarf_cu,
3171 die,
3172 skip_artificial,
3173 type_list,
3174 function_param_types,
3175 function_param_decls);
Greg Clayton24739922010-10-13 03:15:28 +00003176 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003177
Greg Clayton24739922010-10-13 03:15:28 +00003178 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003179 clang_type = ast.CreateFunctionType (return_clang_type,
3180 &function_param_types[0],
3181 function_param_types.size(),
3182 is_variadic,
3183 type_quals);
3184
Greg Clayton24739922010-10-13 03:15:28 +00003185 if (type_name_cstr)
3186 {
3187 bool type_handled = false;
3188 const DWARFDebugInfoEntry *parent_die = die->GetParent();
3189 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003190 {
Greg Clayton24739922010-10-13 03:15:28 +00003191 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003192 {
Greg Clayton24739922010-10-13 03:15:28 +00003193 // We need to find the DW_TAG_class_type or
3194 // DW_TAG_struct_type by name so we can add this
3195 // as a member function of the class.
3196 const char *class_name_start = type_name_cstr + 2;
3197 const char *class_name_end = ::strchr (class_name_start, ' ');
3198 SymbolContext empty_sc;
3199 clang_type_t class_opaque_type = NULL;
3200 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003201 {
Greg Clayton24739922010-10-13 03:15:28 +00003202 ConstString class_name (class_name_start, class_name_end - class_name_start);
3203 TypeList types;
3204 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3205 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003206 {
Greg Clayton24739922010-10-13 03:15:28 +00003207 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003208 {
Greg Clayton24739922010-10-13 03:15:28 +00003209 Type *type = types.GetTypeAtIndex (i).get();
3210 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3211 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003212 {
Greg Clayton24739922010-10-13 03:15:28 +00003213 class_opaque_type = type_clang_forward_type;
3214 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003215 }
3216 }
3217 }
Greg Clayton24739922010-10-13 03:15:28 +00003218 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003219
Greg Clayton24739922010-10-13 03:15:28 +00003220 if (class_opaque_type)
3221 {
3222 // If accessibility isn't set to anything valid, assume public for
3223 // now...
3224 if (accessibility == eAccessNone)
3225 accessibility = eAccessPublic;
3226
3227 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003228 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3229 type_name_cstr,
3230 clang_type,
3231 accessibility);
Greg Clayton24739922010-10-13 03:15:28 +00003232 type_handled = objc_method_decl != NULL;
3233 }
3234 }
3235 else if (parent_die->Tag() == DW_TAG_class_type ||
3236 parent_die->Tag() == DW_TAG_structure_type)
3237 {
3238 // Look at the parent of this DIE and see if is is
3239 // a class or struct and see if this is actually a
3240 // C++ method
3241 Type *class_type = ResolveType (dwarf_cu, parent_die);
3242 if (class_type)
3243 {
3244 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3245 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003246 {
Greg Clayton24739922010-10-13 03:15:28 +00003247 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3248 // in the DWARF for C++ methods... Default to public for now...
Greg Clayton6d01ad92010-09-29 01:57:37 +00003249 if (accessibility == eAccessNone)
3250 accessibility = eAccessPublic;
3251
Greg Clayton24739922010-10-13 03:15:28 +00003252 clang::CXXMethodDecl *cxx_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003253 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3254 type_name_cstr,
3255 clang_type,
3256 accessibility,
3257 is_virtual,
3258 is_static,
3259 is_inline,
3260 is_explicit);
Greg Clayton24739922010-10-13 03:15:28 +00003261 type_handled = cxx_method_decl != NULL;
Greg Clayton0fffff52010-09-24 05:15:53 +00003262 }
3263 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003264 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003265 }
Greg Clayton24739922010-10-13 03:15:28 +00003266
3267 if (!type_handled)
3268 {
3269 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003270 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3271 clang_type,
3272 storage,
3273 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003274
3275 // Add the decl to our DIE to decl context map
3276 assert (function_decl);
3277 m_die_to_decl_ctx[die] = function_decl;
3278 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003279 ast.SetFunctionParameters (function_decl,
3280 &function_param_decls.front(),
3281 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003282 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003283 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003284 type_sp.reset( new Type (die->GetOffset(),
3285 this,
3286 type_name_const_str,
3287 0,
3288 NULL,
3289 LLDB_INVALID_UID,
3290 Type::eEncodingIsUID,
3291 &decl,
3292 clang_type,
3293 false));
3294
Greg Clayton24739922010-10-13 03:15:28 +00003295 m_die_to_type[die] = type_sp.get();
3296 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003297 }
3298 break;
3299
3300 case DW_TAG_array_type:
3301 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003302 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003303 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003304
3305 size_t byte_size = 0;
3306 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3307 Declaration decl;
3308 int64_t first_index = 0;
3309 uint32_t byte_stride = 0;
3310 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003311 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003312
3313 if (num_attributes > 0)
3314 {
3315 uint32_t i;
3316 for (i=0; i<num_attributes; ++i)
3317 {
3318 attr = attributes.AttributeAtIndex(i);
3319 DWARFFormValue form_value;
3320 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3321 {
3322 switch (attr)
3323 {
3324 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3325 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3326 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3327 case DW_AT_name:
3328 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003329 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003330 break;
3331
3332 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3333 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3334 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3335 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003336 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003337 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003338 case DW_AT_allocated:
3339 case DW_AT_associated:
3340 case DW_AT_data_location:
3341 case DW_AT_description:
3342 case DW_AT_ordering:
3343 case DW_AT_start_scope:
3344 case DW_AT_visibility:
3345 case DW_AT_specification:
3346 case DW_AT_abstract_origin:
3347 case DW_AT_sibling:
3348 break;
3349 }
3350 }
3351 }
3352
Greg Claytonc93237c2010-10-01 20:48:32 +00003353 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3354
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003355 Type *element_type = ResolveTypeUID(type_die_offset);
3356
3357 if (element_type)
3358 {
3359 std::vector<uint64_t> element_orders;
3360 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003361 // We have an array that claims to have no members, lets give it at least one member...
3362 if (element_orders.empty())
3363 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003364 if (byte_stride == 0 && bit_stride == 0)
3365 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003366 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003367 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3368 uint64_t num_elements = 0;
3369 std::vector<uint64_t>::const_reverse_iterator pos;
3370 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3371 for (pos = element_orders.rbegin(); pos != end; ++pos)
3372 {
3373 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003374 clang_type = ast.CreateArrayType (array_element_type,
3375 num_elements,
3376 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003377 array_element_type = clang_type;
3378 array_element_bit_stride = array_element_bit_stride * num_elements;
3379 }
3380 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003381 type_sp.reset( new Type (die->GetOffset(),
3382 this,
3383 empty_name,
3384 array_element_bit_stride / 8,
3385 NULL,
3386 LLDB_INVALID_UID,
3387 Type::eEncodingIsUID,
3388 &decl,
3389 clang_type,
3390 false));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003391 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003392 }
3393 }
3394 }
3395 break;
3396
Greg Clayton9b81a312010-06-12 01:20:30 +00003397 case DW_TAG_ptr_to_member_type:
3398 {
3399 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3400 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3401
Greg Claytond88d7592010-09-15 08:33:30 +00003402 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003403
3404 if (num_attributes > 0) {
3405 uint32_t i;
3406 for (i=0; i<num_attributes; ++i)
3407 {
3408 attr = attributes.AttributeAtIndex(i);
3409 DWARFFormValue form_value;
3410 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3411 {
3412 switch (attr)
3413 {
3414 case DW_AT_type:
3415 type_die_offset = form_value.Reference(dwarf_cu); break;
3416 case DW_AT_containing_type:
3417 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3418 }
3419 }
3420 }
3421
3422 Type *pointee_type = ResolveTypeUID(type_die_offset);
3423 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3424
Greg Clayton1be10fc2010-09-29 01:12:09 +00003425 clang_type_t pointee_clang_type = pointee_type->GetClangType();
3426 clang_type_t class_clang_type = class_type->GetClangType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003427
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003428 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3429 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003430
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003431 size_t byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3432 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003433
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003434 type_sp.reset( new Type (die->GetOffset(),
3435 this,
3436 type_name_const_str,
3437 byte_size,
3438 NULL,
3439 LLDB_INVALID_UID,
3440 Type::eEncodingIsUID,
3441 NULL,
3442 clang_type,
3443 false));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003444 m_die_to_type[die] = type_sp.get();
Greg Clayton9b81a312010-06-12 01:20:30 +00003445 }
3446
3447 break;
3448 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003449 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003450 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003451 break;
3452 }
3453
3454 if (type_sp.get())
3455 {
3456 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3457 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3458
3459 SymbolContextScope * symbol_context_scope = NULL;
3460 if (sc_parent_tag == DW_TAG_compile_unit)
3461 {
3462 symbol_context_scope = sc.comp_unit;
3463 }
3464 else if (sc.function != NULL)
3465 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003466 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003467 if (symbol_context_scope == NULL)
3468 symbol_context_scope = sc.function;
3469 }
3470
3471 if (symbol_context_scope != NULL)
3472 {
3473 type_sp->SetSymbolContextScope(symbol_context_scope);
3474 }
3475
3476// if (udt_sp.get())
3477// {
3478// if (is_forward_declaration)
3479// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3480// type_sp->SetUserDefinedType(udt_sp);
3481// }
3482
3483 if (type_sp.unique())
3484 {
3485 // We are ready to put this type into the uniqued list up at the module level
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003486 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00003487
Greg Clayton594e5ed2010-09-27 21:07:38 +00003488 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003489 }
3490 }
3491 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003492 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003493 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003494 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003495 }
3496 }
3497 return type_sp;
3498}
3499
3500size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003501SymbolFileDWARF::ParseTypes
3502(
3503 const SymbolContext& sc,
3504 DWARFCompileUnit* dwarf_cu,
3505 const DWARFDebugInfoEntry *die,
3506 bool parse_siblings,
3507 bool parse_children
3508)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003509{
3510 size_t types_added = 0;
3511 while (die != NULL)
3512 {
3513 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003514 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003515 {
3516 if (type_is_new)
3517 ++types_added;
3518 }
3519
3520 if (parse_children && die->HasChildren())
3521 {
3522 if (die->Tag() == DW_TAG_subprogram)
3523 {
3524 SymbolContext child_sc(sc);
3525 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3526 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3527 }
3528 else
3529 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3530 }
3531
3532 if (parse_siblings)
3533 die = die->GetSibling();
3534 else
3535 die = NULL;
3536 }
3537 return types_added;
3538}
3539
3540
3541size_t
3542SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3543{
3544 assert(sc.comp_unit && sc.function);
3545 size_t functions_added = 0;
3546 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3547 if (dwarf_cu)
3548 {
3549 dw_offset_t function_die_offset = sc.function->GetID();
3550 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3551 if (function_die)
3552 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003553 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003554 }
3555 }
3556
3557 return functions_added;
3558}
3559
3560
3561size_t
3562SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3563{
3564 // At least a compile unit must be valid
3565 assert(sc.comp_unit);
3566 size_t types_added = 0;
3567 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3568 if (dwarf_cu)
3569 {
3570 if (sc.function)
3571 {
3572 dw_offset_t function_die_offset = sc.function->GetID();
3573 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3574 if (func_die && func_die->HasChildren())
3575 {
3576 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3577 }
3578 }
3579 else
3580 {
3581 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3582 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3583 {
3584 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3585 }
3586 }
3587 }
3588
3589 return types_added;
3590}
3591
3592size_t
3593SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3594{
3595 if (sc.comp_unit != NULL)
3596 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003597 DWARFDebugInfo* info = DebugInfo();
3598 if (info == NULL)
3599 return 0;
3600
3601 uint32_t cu_idx = UINT32_MAX;
3602 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003603
3604 if (dwarf_cu == NULL)
3605 return 0;
3606
3607 if (sc.function)
3608 {
3609 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003610
3611 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3612 assert (func_lo_pc != DW_INVALID_ADDRESS);
3613
3614 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003615 }
3616 else if (sc.comp_unit)
3617 {
3618 uint32_t vars_added = 0;
3619 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3620
3621 if (variables.get() == NULL)
3622 {
3623 variables.reset(new VariableList());
3624 sc.comp_unit->SetVariableList(variables);
3625
3626 // Index if we already haven't to make sure the compile units
3627 // get indexed and make their global DIE index list
3628 if (!m_indexed)
3629 Index ();
3630
Greg Claytonc685f8e2010-09-15 04:15:46 +00003631 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00003632 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003633 for (size_t idx=0; idx<num_globals; ++idx)
3634 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003635 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003636 if (var_sp)
3637 {
3638 variables->AddVariable(var_sp);
3639 ++vars_added;
3640 }
3641 }
3642 }
3643 return vars_added;
3644 }
3645 }
3646 return 0;
3647}
3648
3649
3650VariableSP
3651SymbolFileDWARF::ParseVariableDIE
3652(
3653 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003654 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003655 const DWARFDebugInfoEntry *die,
3656 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003657)
3658{
3659
3660 VariableSP var_sp;
3661
3662 const dw_tag_t tag = die->Tag();
3663 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003664 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003665 if (num_attributes > 0)
3666 {
3667 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00003668 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003669 Declaration decl;
3670 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003671 Type *var_type = NULL;
3672 DWARFExpression location;
3673 bool is_external = false;
3674 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00003675 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003676
3677 for (i=0; i<num_attributes; ++i)
3678 {
3679 dw_attr_t attr = attributes.AttributeAtIndex(i);
3680 DWARFFormValue form_value;
3681 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3682 {
3683 switch (attr)
3684 {
3685 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3686 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3687 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3688 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00003689 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003690 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003691 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3692 case DW_AT_location:
3693 {
3694 if (form_value.BlockData())
3695 {
3696 const DataExtractor& debug_info_data = get_debug_info_data();
3697
3698 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3699 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00003700 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003701 }
3702 else
3703 {
3704 const DataExtractor& debug_loc_data = get_debug_loc_data();
3705 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3706
3707 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3708 if (loc_list_length > 0)
3709 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003710 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
3711 assert (func_low_pc != LLDB_INVALID_ADDRESS);
3712 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003713 }
3714 }
3715 }
3716 break;
3717
3718 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003719 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003720 case DW_AT_const_value:
3721 case DW_AT_declaration:
3722 case DW_AT_description:
3723 case DW_AT_endianity:
3724 case DW_AT_segment:
3725 case DW_AT_start_scope:
3726 case DW_AT_visibility:
3727 default:
3728 case DW_AT_abstract_origin:
3729 case DW_AT_sibling:
3730 case DW_AT_specification:
3731 break;
3732 }
3733 }
3734 }
3735
3736 if (location.IsValid())
3737 {
3738 assert(var_type != DIE_IS_BEING_PARSED);
3739
Greg Claytona134cc12010-09-13 02:37:44 +00003740 ConstString var_name;
3741 if (mangled)
3742 {
3743 Mangled mangled_var_name (mangled, true);
3744 var_name = mangled_var_name.GetDemangledName();
3745 }
3746
3747 if (!var_name && name)
3748 {
3749 var_name.SetCString(name);
3750 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003751
3752 ValueType scope = eValueTypeInvalid;
3753
3754 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3755 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3756
3757 if (tag == DW_TAG_formal_parameter)
3758 scope = eValueTypeVariableArgument;
3759 else if (is_external || parent_tag == DW_TAG_compile_unit)
3760 scope = eValueTypeVariableGlobal;
3761 else
3762 scope = eValueTypeVariableLocal;
3763
3764 SymbolContextScope * symbol_context_scope = NULL;
3765 if (parent_tag == DW_TAG_compile_unit)
3766 {
3767 symbol_context_scope = sc.comp_unit;
3768 }
3769 else if (sc.function != NULL)
3770 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003771 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003772 if (symbol_context_scope == NULL)
3773 symbol_context_scope = sc.function;
3774 }
3775
3776 assert(symbol_context_scope != NULL);
3777 var_sp.reset (new Variable(die->GetOffset(),
3778 var_name,
3779 var_type,
3780 scope,
3781 symbol_context_scope,
3782 &decl,
3783 location,
3784 is_external,
3785 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003786
3787 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003788 }
3789 }
3790 return var_sp;
3791}
3792
3793size_t
3794SymbolFileDWARF::ParseVariables
3795(
3796 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003797 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003798 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003799 const DWARFDebugInfoEntry *orig_die,
3800 bool parse_siblings,
3801 bool parse_children,
3802 VariableList* cc_variable_list
3803)
3804{
3805 if (orig_die == NULL)
3806 return 0;
3807
3808 size_t vars_added = 0;
3809 const DWARFDebugInfoEntry *die = orig_die;
3810 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3811 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3812 VariableListSP variables;
3813 switch (parent_tag)
3814 {
3815 case DW_TAG_compile_unit:
3816 if (sc.comp_unit != NULL)
3817 {
3818 variables = sc.comp_unit->GetVariableList(false);
3819 if (variables.get() == NULL)
3820 {
3821 variables.reset(new VariableList());
3822 sc.comp_unit->SetVariableList(variables);
3823 }
3824 }
3825 else
3826 {
3827 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3828 vars_added = 0;
3829 }
3830 break;
3831
3832 case DW_TAG_subprogram:
3833 case DW_TAG_inlined_subroutine:
3834 case DW_TAG_lexical_block:
3835 if (sc.function != NULL)
3836 {
3837 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003838
3839 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3840 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003841 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003842 if (variables.get() == NULL)
3843 {
3844 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003845 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003846 }
3847 }
3848 else
3849 {
3850 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3851 vars_added = 0;
3852 }
3853 break;
3854
3855 default:
3856 assert(!"Didn't find appropriate parent DIE for variable list...");
3857 break;
3858 }
3859
3860 // We need to have a variable list at this point that we can add variables to
3861 assert(variables.get());
3862
3863 while (die != NULL)
3864 {
3865 dw_tag_t tag = die->Tag();
3866
3867 // Check to see if we have already parsed this variable or constant?
Greg Claytonbcf12172010-10-28 00:56:11 +00003868 if (m_die_to_variable_sp[die])
3869 {
3870 if (cc_variable_list)
3871 cc_variable_list->AddVariable (m_die_to_variable_sp[die]);
3872 }
3873 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003874 {
3875 // We haven't already parsed it, lets do that now.
3876 if ((tag == DW_TAG_variable) ||
3877 (tag == DW_TAG_constant) ||
3878 (tag == DW_TAG_formal_parameter && sc.function))
3879 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003880 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003881 if (var_sp)
3882 {
3883 variables->AddVariable(var_sp);
Greg Claytonbcf12172010-10-28 00:56:11 +00003884 if (cc_variable_list)
3885 cc_variable_list->AddVariable (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003886 ++vars_added;
3887 }
3888 }
3889 }
3890
3891 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3892
3893 if (!skip_children && parse_children && die->HasChildren())
3894 {
Greg Claytonbcf12172010-10-28 00:56:11 +00003895 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003896 }
3897
3898 if (parse_siblings)
3899 die = die->GetSibling();
3900 else
3901 die = NULL;
3902 }
3903
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003904 return vars_added;
3905}
3906
3907//------------------------------------------------------------------
3908// PluginInterface protocol
3909//------------------------------------------------------------------
3910const char *
3911SymbolFileDWARF::GetPluginName()
3912{
3913 return "SymbolFileDWARF";
3914}
3915
3916const char *
3917SymbolFileDWARF::GetShortPluginName()
3918{
3919 return GetPluginNameStatic();
3920}
3921
3922uint32_t
3923SymbolFileDWARF::GetPluginVersion()
3924{
3925 return 1;
3926}
3927
3928void
3929SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3930{
3931}
3932
3933Error
3934SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3935{
3936 Error error;
3937 error.SetErrorString("No plug-in command are currently supported.");
3938 return error;
3939}
3940
3941Log *
3942SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3943{
3944 return NULL;
3945}
3946