blob: 8f89df536fc12cf177becfb829dfe76a6657fd6b [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 Clayton62742b12010-11-11 01:09:45 +000056//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000057
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 Clayton96d7d742010-11-10 23:42:09 +0000509SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510{
Greg Clayton96d7d742010-11-10 23:42:09 +0000511 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000513 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 if (cu_die)
515 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000516 const char * cu_die_name = cu_die->GetName(this, curr_cu);
517 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
518 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_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
Greg Clayton96d7d742010-11-10 23:42:09 +0000538 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), class_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539 if (compile_unit_sp.get())
540 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000541 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000542 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 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000566 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
567 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000568 {
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.
Greg Clayton96d7d742010-11-10 23:42:09 +0000573 assert(curr_cu->GetUserData() == NULL);
574 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 }
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);
Greg Clayton96d7d742010-11-10 23:42:09 +0000717 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
718 assert (curr_cu);
719 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000720
721 if (cu_die)
722 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000723 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
724 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725
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 Claytonba2d22d2010-11-13 22:57:37 +00001089 const size_t num_attributes = die->GetAttributes (this,
1090 dwarf_cu,
1091 fixed_form_sizes,
1092 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093 if (num_attributes > 0)
1094 {
1095 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001096 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001098 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001100 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001101 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001102 size_t byte_size = 0;
1103 size_t bit_offset = 0;
1104 size_t bit_size = 0;
1105 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001106 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001107 {
1108 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1109 DWARFFormValue form_value;
1110 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1111 {
1112 switch (attr)
1113 {
1114 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1115 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1116 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1117 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1118 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1119 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1120 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1121 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1122 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001123// if (form_value.BlockData())
1124// {
1125// Value initialValue(0);
1126// Value memberOffset(0);
1127// const DataExtractor& debug_info_data = get_debug_info_data();
1128// uint32_t block_length = form_value.Unsigned();
1129// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1130// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1131// {
1132// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1133// }
1134// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135 break;
1136
Greg Clayton8cf05932010-07-22 18:30:50 +00001137 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001138 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001139 case DW_AT_declaration:
1140 case DW_AT_description:
1141 case DW_AT_mutable:
1142 case DW_AT_visibility:
1143 default:
1144 case DW_AT_sibling:
1145 break;
1146 }
1147 }
1148 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001149
1150 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1151
1152 if (class_language == eLanguageTypeObjC ||
1153 class_language == eLanguageTypeObjC_plus_plus)
1154 accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001155
Greg Clayton24739922010-10-13 03:15:28 +00001156 if (is_artificial == false)
1157 {
1158 Type *member_type = ResolveTypeUID(encoding_uid);
1159 assert(member_type);
1160 if (accessibility == eAccessNone)
1161 accessibility = default_accessibility;
1162 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163
Greg Claytonba2d22d2010-11-13 22:57:37 +00001164 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1165 name,
1166 member_type->GetClangLayoutType(),
1167 accessibility,
1168 bit_size);
Greg Clayton24739922010-10-13 03:15:28 +00001169 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001170 }
1171 }
1172 break;
1173
1174 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001175 // Let the type parsing code handle this one for us.
1176 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177 break;
1178
1179 case DW_TAG_inheritance:
1180 {
1181 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001182 if (default_accessibility == eAccessNone)
1183 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001184 // TODO: implement DW_TAG_inheritance type parsing
1185 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001186 const size_t num_attributes = die->GetAttributes (this,
1187 dwarf_cu,
1188 fixed_form_sizes,
1189 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001190 if (num_attributes > 0)
1191 {
1192 Declaration decl;
1193 DWARFExpression location;
1194 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001195 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001196 bool is_virtual = false;
1197 bool is_base_of_class = true;
1198 off_t member_offset = 0;
1199 uint32_t i;
1200 for (i=0; i<num_attributes; ++i)
1201 {
1202 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1203 DWARFFormValue form_value;
1204 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1205 {
1206 switch (attr)
1207 {
1208 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1209 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1210 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1211 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1212 case DW_AT_data_member_location:
1213 if (form_value.BlockData())
1214 {
1215 Value initialValue(0);
1216 Value memberOffset(0);
1217 const DataExtractor& debug_info_data = get_debug_info_data();
1218 uint32_t block_length = form_value.Unsigned();
1219 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001220 if (DWARFExpression::Evaluate (NULL,
1221 NULL,
1222 debug_info_data,
1223 NULL,
1224 NULL,
1225 block_offset,
1226 block_length,
1227 eRegisterKindDWARF,
1228 &initialValue,
1229 memberOffset,
1230 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231 {
1232 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1233 }
1234 }
1235 break;
1236
1237 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001238 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001239 break;
1240
1241 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1242 default:
1243 case DW_AT_sibling:
1244 break;
1245 }
1246 }
1247 }
1248
Greg Clayton526e5af2010-11-13 03:52:47 +00001249 Type *base_class_type = ResolveTypeUID(encoding_uid);
1250 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001251
1252 if (class_language == eLanguageTypeObjC)
1253 {
Greg Clayton526e5af2010-11-13 03:52:47 +00001254 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_type->GetClangType());
Greg Clayton9e409562010-07-28 02:04:09 +00001255 }
1256 else
1257 {
Greg Claytonba2d22d2010-11-13 22:57:37 +00001258 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_type->GetClangType(),
1259 accessibility,
1260 is_virtual,
1261 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001262 assert(base_classes.back());
1263 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264 }
1265 }
1266 break;
1267
1268 default:
1269 break;
1270 }
1271 }
1272 return count;
1273}
1274
1275
1276clang::DeclContext*
1277SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1278{
1279 DWARFDebugInfo* debug_info = DebugInfo();
1280 if (debug_info)
1281 {
1282 DWARFCompileUnitSP cu_sp;
1283 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1284 if (die)
1285 return GetClangDeclContextForDIE (cu_sp.get(), die);
1286 }
1287 return NULL;
1288}
1289
1290Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001291SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001292{
1293 DWARFDebugInfo* debug_info = DebugInfo();
1294 if (debug_info)
1295 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001296 DWARFCompileUnitSP cu_sp;
1297 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001298 if (type_die != NULL)
Greg Clayton594e5ed2010-09-27 21:07:38 +00001299 return ResolveType (cu_sp.get(), type_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001300 }
1301 return NULL;
1302}
1303
Greg Clayton1be10fc2010-09-29 01:12:09 +00001304lldb::clang_type_t
1305SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1306{
1307 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Claytonc93237c2010-10-01 20:48:32 +00001308 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (ClangASTType::RemoveFastQualifiers(clang_type));
Greg Clayton1be10fc2010-09-29 01:12:09 +00001309 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001310 {
1311 // We have already resolved this type...
1312 return clang_type;
1313 }
1314 // Once we start resolving this type, remove it from the forward declaration
1315 // map in case anyone child members or other types require this type to get resolved.
1316 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1317 // are done.
1318 m_forward_decl_clang_type_to_die.erase (ClangASTType::RemoveFastQualifiers(clang_type));
1319
Greg Clayton1be10fc2010-09-29 01:12:09 +00001320
Greg Clayton450e3f32010-10-12 02:24:53 +00001321 DWARFDebugInfo* debug_info = DebugInfo();
1322
Greg Clayton96d7d742010-11-10 23:42:09 +00001323 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001324 Type *type = m_die_to_type.lookup (die);
1325
1326 const dw_tag_t tag = die->Tag();
1327
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001328 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1329 die->GetOffset(),
1330 DW_TAG_value_to_name(tag),
1331 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001332 assert (clang_type);
1333 DWARFDebugInfoEntry::Attributes attributes;
1334
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001335 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001336
1337 switch (tag)
1338 {
1339 case DW_TAG_structure_type:
1340 case DW_TAG_union_type:
1341 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001342 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001343 if (die->HasChildren())
1344 {
1345 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001346 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1347 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001348 class_language = eLanguageTypeObjC;
1349
1350 int tag_decl_kind = -1;
1351 AccessType default_accessibility = eAccessNone;
1352 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001353 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001354 tag_decl_kind = clang::TTK_Struct;
1355 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001356 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001357 else if (tag == DW_TAG_union_type)
1358 {
1359 tag_decl_kind = clang::TTK_Union;
1360 default_accessibility = eAccessPublic;
1361 }
1362 else if (tag == DW_TAG_class_type)
1363 {
1364 tag_decl_kind = clang::TTK_Class;
1365 default_accessibility = eAccessPrivate;
1366 }
1367
Greg Clayton96d7d742010-11-10 23:42:09 +00001368 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001369 std::vector<clang::CXXBaseSpecifier *> base_classes;
1370 std::vector<int> member_accessibilities;
1371 bool is_a_class = false;
1372 // Parse members and base classes first
1373 DWARFDIECollection member_function_dies;
1374
1375 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001376 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001377 die,
1378 clang_type,
1379 class_language,
1380 base_classes,
1381 member_accessibilities,
1382 member_function_dies,
1383 default_accessibility,
1384 is_a_class);
1385
1386 // Now parse any methods if there were any...
1387 size_t num_functions = member_function_dies.Size();
1388 if (num_functions > 0)
1389 {
1390 for (size_t i=0; i<num_functions; ++i)
1391 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001392 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001393 }
1394 }
1395
Greg Clayton450e3f32010-10-12 02:24:53 +00001396 if (class_language == eLanguageTypeObjC)
1397 {
1398 std::string class_str (ClangASTContext::GetTypeName (clang_type));
1399 if (!class_str.empty())
1400 {
1401
1402 ConstString class_name (class_str.c_str());
1403 std::vector<NameToDIE::Info> method_die_infos;
1404 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1405 {
1406 DWARFCompileUnit* method_cu = NULL;
1407 DWARFCompileUnit* prev_method_cu = NULL;
1408 const size_t num_objc_methods = method_die_infos.size();
1409 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1410 {
1411 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1412
1413 if (method_cu != prev_method_cu)
1414 method_cu->ExtractDIEsIfNeeded (false);
1415
1416 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1417
1418 ResolveType (method_cu, method_die);
1419 }
1420 }
1421 }
1422 }
1423
Greg Claytonc93237c2010-10-01 20:48:32 +00001424 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1425 // need to tell the clang type it is actually a class.
1426 if (class_language != eLanguageTypeObjC)
1427 {
1428 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001429 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001430 }
1431
1432 // Since DW_TAG_structure_type gets used for both classes
1433 // and structures, we may need to set any DW_TAG_member
1434 // fields to have a "private" access if none was specified.
1435 // When we parsed the child members we tracked that actual
1436 // accessibility value for each DW_TAG_member in the
1437 // "member_accessibilities" array. If the value for the
1438 // member is zero, then it was set to the "default_accessibility"
1439 // which for structs was "public". Below we correct this
1440 // by setting any fields to "private" that weren't correctly
1441 // set.
1442 if (is_a_class && !member_accessibilities.empty())
1443 {
1444 // This is a class and all members that didn't have
1445 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001446 ast.SetDefaultAccessForRecordFields (clang_type,
1447 eAccessPrivate,
1448 &member_accessibilities.front(),
1449 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001450 }
1451
1452 if (!base_classes.empty())
1453 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001454 ast.SetBaseClassesForClassType (clang_type,
1455 &base_classes.front(),
1456 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001457
1458 // Clang will copy each CXXBaseSpecifier in "base_classes"
1459 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001460 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1461 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001462 }
1463
1464 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001465 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001466 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001467
1468 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001469 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001470 if (die->HasChildren())
1471 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001472 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1473 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001474 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001475 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001476 return clang_type;
1477
1478 default:
1479 assert(false && "not a forward clang type decl!");
1480 break;
1481 }
1482 return NULL;
1483}
1484
Greg Claytonc685f8e2010-09-15 04:15:46 +00001485Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001486SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001487{
1488 if (type_die != NULL)
1489 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001490 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001491 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001492 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001493 if (assert_not_being_parsed)
1494 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001495 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001496 }
1497 return NULL;
1498}
1499
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001500CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001501SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001502{
1503 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001504 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001505 {
1506 // The symbol vendor doesn't know about this compile unit, we
1507 // need to parse and add it to the symbol vendor object.
1508 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001509 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001510 if (dc_cu.get())
1511 {
1512 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001513 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001514 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001515
1516 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001517
1518 if (m_debug_map_symfile)
1519 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001520 }
1521 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001522 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001523}
1524
1525bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001526SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001527{
1528 sc.Clear();
1529 // Check if the symbol vendor already knows about this compile unit?
1530 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton96d7d742010-11-10 23:42:09 +00001531 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001532
1533 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1534 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001535 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001536
1537 return sc.function != NULL;
1538}
1539
1540uint32_t
1541SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1542{
1543 Timer scoped_timer(__PRETTY_FUNCTION__,
1544 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1545 so_addr.GetSection(),
1546 so_addr.GetOffset(),
1547 resolve_scope);
1548 uint32_t resolved = 0;
1549 if (resolve_scope & ( eSymbolContextCompUnit |
1550 eSymbolContextFunction |
1551 eSymbolContextBlock |
1552 eSymbolContextLineEntry))
1553 {
1554 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1555
1556 DWARFDebugAranges* debug_aranges = DebugAranges();
1557 DWARFDebugInfo* debug_info = DebugInfo();
1558 if (debug_aranges)
1559 {
1560 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1561 if (cu_offset != DW_INVALID_OFFSET)
1562 {
1563 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001564 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1565 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001566 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001567 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001568 assert(sc.comp_unit != NULL);
1569 resolved |= eSymbolContextCompUnit;
1570
1571 if (resolve_scope & eSymbolContextLineEntry)
1572 {
1573 LineTable *line_table = sc.comp_unit->GetLineTable();
1574 if (line_table == NULL)
1575 {
1576 if (ParseCompileUnitLineTable(sc))
1577 line_table = sc.comp_unit->GetLineTable();
1578 }
1579 if (line_table != NULL)
1580 {
1581 if (so_addr.IsLinkedAddress())
1582 {
1583 Address linked_addr (so_addr);
1584 linked_addr.ResolveLinkedAddress();
1585 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1586 {
1587 resolved |= eSymbolContextLineEntry;
1588 }
1589 }
1590 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1591 {
1592 resolved |= eSymbolContextLineEntry;
1593 }
1594 }
1595 }
1596
1597 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1598 {
1599 DWARFDebugInfoEntry *function_die = NULL;
1600 DWARFDebugInfoEntry *block_die = NULL;
1601 if (resolve_scope & eSymbolContextBlock)
1602 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001603 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001604 }
1605 else
1606 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001607 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001608 }
1609
1610 if (function_die != NULL)
1611 {
1612 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1613 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001614 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001615 }
1616
1617 if (sc.function != NULL)
1618 {
1619 resolved |= eSymbolContextFunction;
1620
1621 if (resolve_scope & eSymbolContextBlock)
1622 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001623 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001624
1625 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001626 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001627 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001628 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001629 if (sc.block)
1630 resolved |= eSymbolContextBlock;
1631 }
1632 }
1633 }
1634 }
1635 }
1636 }
1637 }
1638 return resolved;
1639}
1640
1641
1642
1643uint32_t
1644SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1645{
1646 const uint32_t prev_size = sc_list.GetSize();
1647 if (resolve_scope & eSymbolContextCompUnit)
1648 {
1649 DWARFDebugInfo* debug_info = DebugInfo();
1650 if (debug_info)
1651 {
1652 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001653 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001654
Greg Clayton96d7d742010-11-10 23:42:09 +00001655 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001656 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001657 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001658 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1659 if (check_inlines || file_spec_matches_cu_file_spec)
1660 {
1661 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001662 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001663 assert(sc.comp_unit != NULL);
1664
1665 uint32_t file_idx = UINT32_MAX;
1666
1667 // If we are looking for inline functions only and we don't
1668 // find it in the support files, we are done.
1669 if (check_inlines)
1670 {
1671 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1672 if (file_idx == UINT32_MAX)
1673 continue;
1674 }
1675
1676 if (line != 0)
1677 {
1678 LineTable *line_table = sc.comp_unit->GetLineTable();
1679
1680 if (line_table != NULL && line != 0)
1681 {
1682 // We will have already looked up the file index if
1683 // we are searching for inline entries.
1684 if (!check_inlines)
1685 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1686
1687 if (file_idx != UINT32_MAX)
1688 {
1689 uint32_t found_line;
1690 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1691 found_line = sc.line_entry.line;
1692
Greg Clayton016a95e2010-09-14 02:20:48 +00001693 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001694 {
1695 sc.function = NULL;
1696 sc.block = NULL;
1697 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1698 {
1699 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1700 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1701 {
1702 DWARFDebugInfoEntry *function_die = NULL;
1703 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001704 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001705
1706 if (function_die != NULL)
1707 {
1708 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1709 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001710 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001711 }
1712
1713 if (sc.function != NULL)
1714 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001715 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001716
1717 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001718 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001719 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001720 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001721 }
1722 }
1723 }
1724
1725 sc_list.Append(sc);
1726 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1727 }
1728 }
1729 }
1730 else if (file_spec_matches_cu_file_spec && !check_inlines)
1731 {
1732 // only append the context if we aren't looking for inline call sites
1733 // by file and line and if the file spec matches that of the compile unit
1734 sc_list.Append(sc);
1735 }
1736 }
1737 else if (file_spec_matches_cu_file_spec && !check_inlines)
1738 {
1739 // only append the context if we aren't looking for inline call sites
1740 // by file and line and if the file spec matches that of the compile unit
1741 sc_list.Append(sc);
1742 }
1743
1744 if (!check_inlines)
1745 break;
1746 }
1747 }
1748 }
1749 }
1750 return sc_list.GetSize() - prev_size;
1751}
1752
1753void
1754SymbolFileDWARF::Index ()
1755{
1756 if (m_indexed)
1757 return;
1758 m_indexed = true;
1759 Timer scoped_timer (__PRETTY_FUNCTION__,
1760 "SymbolFileDWARF::Index (%s)",
1761 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1762
1763 DWARFDebugInfo* debug_info = DebugInfo();
1764 if (debug_info)
1765 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001766 m_aranges.reset(new DWARFDebugAranges());
1767
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001768 uint32_t cu_idx = 0;
1769 const uint32_t num_compile_units = GetNumCompileUnits();
1770 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1771 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001772 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001773
Greg Clayton96d7d742010-11-10 23:42:09 +00001774 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001775
Greg Clayton96d7d742010-11-10 23:42:09 +00001776 curr_cu->Index (cu_idx,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001777 m_function_basename_index,
1778 m_function_fullname_index,
1779 m_function_method_index,
1780 m_function_selector_index,
Greg Clayton450e3f32010-10-12 02:24:53 +00001781 m_objc_class_selectors_index,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001782 m_global_index,
Greg Clayton69b04882010-10-15 02:03:22 +00001783 m_type_index,
1784 m_namespace_index,
Greg Clayton016a95e2010-09-14 02:20:48 +00001785 DebugRanges(),
1786 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001787
1788 // Keep memory down by clearing DIEs if this generate function
1789 // caused them to be parsed
1790 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001791 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001792 }
1793
Greg Clayton016a95e2010-09-14 02:20:48 +00001794 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001795
Greg Clayton24739922010-10-13 03:15:28 +00001796#if defined (ENABLE_DEBUG_PRINTF)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001797 StreamFile s(stdout);
Greg Clayton24739922010-10-13 03:15:28 +00001798 s.Printf ("DWARF index for (%s) '%s/%s':",
1799 GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1800 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1801 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001802 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1803 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1804 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1805 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1806 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1807 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001808 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001809 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001810#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001811 }
1812}
1813
1814uint32_t
1815SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1816{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001817 DWARFDebugInfo* info = DebugInfo();
1818 if (info == NULL)
1819 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001820
1821 // If we aren't appending the results to this list, then clear the list
1822 if (!append)
1823 variables.Clear();
1824
1825 // Remember how many variables are in the list before we search in case
1826 // we are appending the results to a variable list.
1827 const uint32_t original_size = variables.GetSize();
1828
1829 // Index the DWARF if we haven't already
1830 if (!m_indexed)
1831 Index ();
1832
Greg Claytonc685f8e2010-09-15 04:15:46 +00001833 SymbolContext sc;
1834 sc.module_sp = m_obj_file->GetModule()->GetSP();
1835 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001836
Greg Clayton96d7d742010-11-10 23:42:09 +00001837 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001838 DWARFCompileUnit* prev_cu = NULL;
1839 const DWARFDebugInfoEntry* die = NULL;
1840 std::vector<NameToDIE::Info> die_info_array;
1841 const size_t num_matches = m_global_index.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001842 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001843 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001844 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001845
Greg Clayton96d7d742010-11-10 23:42:09 +00001846 if (curr_cu != prev_cu)
1847 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001848
Greg Clayton96d7d742010-11-10 23:42:09 +00001849 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001850
Greg Clayton96d7d742010-11-10 23:42:09 +00001851 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001852 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001853
Greg Clayton96d7d742010-11-10 23:42:09 +00001854 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001855
1856 if (variables.GetSize() - original_size >= max_matches)
1857 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001858 }
1859
1860 // Return the number of variable that were appended to the list
1861 return variables.GetSize() - original_size;
1862}
1863
1864uint32_t
1865SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1866{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001867 DWARFDebugInfo* info = DebugInfo();
1868 if (info == NULL)
1869 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001870
1871 // If we aren't appending the results to this list, then clear the list
1872 if (!append)
1873 variables.Clear();
1874
1875 // Remember how many variables are in the list before we search in case
1876 // we are appending the results to a variable list.
1877 const uint32_t original_size = variables.GetSize();
1878
1879 // Index the DWARF if we haven't already
1880 if (!m_indexed)
1881 Index ();
1882
Greg Claytonc685f8e2010-09-15 04:15:46 +00001883 SymbolContext sc;
1884 sc.module_sp = m_obj_file->GetModule()->GetSP();
1885 assert (sc.module_sp);
1886
Greg Clayton96d7d742010-11-10 23:42:09 +00001887 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001888 DWARFCompileUnit* prev_cu = NULL;
1889 const DWARFDebugInfoEntry* die = NULL;
1890 std::vector<NameToDIE::Info> die_info_array;
1891 const size_t num_matches = m_global_index.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001892 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001893 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001894 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001895
Greg Clayton96d7d742010-11-10 23:42:09 +00001896 if (curr_cu != prev_cu)
1897 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001898
Greg Clayton96d7d742010-11-10 23:42:09 +00001899 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001900
Greg Clayton96d7d742010-11-10 23:42:09 +00001901 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001902 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001903
Greg Clayton96d7d742010-11-10 23:42:09 +00001904 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001905
Greg Claytonc685f8e2010-09-15 04:15:46 +00001906 if (variables.GetSize() - original_size >= max_matches)
1907 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001908 }
1909
1910 // Return the number of variable that were appended to the list
1911 return variables.GetSize() - original_size;
1912}
1913
1914
Greg Clayton0c5cd902010-06-28 21:30:43 +00001915void
1916SymbolFileDWARF::FindFunctions
1917(
1918 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00001919 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00001920 SymbolContextList& sc_list
1921)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001922{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001923 DWARFDebugInfo* info = DebugInfo();
1924 if (info == NULL)
1925 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001926
Greg Claytonc685f8e2010-09-15 04:15:46 +00001927 SymbolContext sc;
1928 sc.module_sp = m_obj_file->GetModule()->GetSP();
1929 assert (sc.module_sp);
1930
Greg Clayton96d7d742010-11-10 23:42:09 +00001931 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001932 DWARFCompileUnit* prev_cu = NULL;
1933 const DWARFDebugInfoEntry* die = NULL;
1934 std::vector<NameToDIE::Info> die_info_array;
1935 const size_t num_matches = name_to_die.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001936 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001937 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001938 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001939
Greg Clayton96d7d742010-11-10 23:42:09 +00001940 if (curr_cu != prev_cu)
1941 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001942
Greg Clayton96d7d742010-11-10 23:42:09 +00001943 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1944 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00001945 {
1946 // We found the function, so we should find the line table
1947 // and line table entry as well
1948 LineTable *line_table = sc.comp_unit->GetLineTable();
1949 if (line_table == NULL)
1950 {
1951 if (ParseCompileUnitLineTable(sc))
1952 line_table = sc.comp_unit->GetLineTable();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001953 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001954 if (line_table != NULL)
1955 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1956
1957 sc_list.Append(sc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001958 }
1959 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00001960}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001961
Greg Claytonc685f8e2010-09-15 04:15:46 +00001962
1963void
1964SymbolFileDWARF::FindFunctions
1965(
1966 const RegularExpression &regex,
1967 const NameToDIE &name_to_die,
1968 SymbolContextList& sc_list
1969)
1970{
1971 DWARFDebugInfo* info = DebugInfo();
1972 if (info == NULL)
1973 return;
1974
1975 SymbolContext sc;
1976 sc.module_sp = m_obj_file->GetModule()->GetSP();
1977 assert (sc.module_sp);
1978
Greg Clayton96d7d742010-11-10 23:42:09 +00001979 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001980 DWARFCompileUnit* prev_cu = NULL;
1981 const DWARFDebugInfoEntry* die = NULL;
1982 std::vector<NameToDIE::Info> die_info_array;
1983 const size_t num_matches = name_to_die.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001984 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001985 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001986 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001987
Greg Clayton96d7d742010-11-10 23:42:09 +00001988 if (curr_cu != prev_cu)
1989 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001990
Greg Clayton96d7d742010-11-10 23:42:09 +00001991 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1992 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00001993 {
1994 // We found the function, so we should find the line table
1995 // and line table entry as well
1996 LineTable *line_table = sc.comp_unit->GetLineTable();
1997 if (line_table == NULL)
1998 {
1999 if (ParseCompileUnitLineTable(sc))
2000 line_table = sc.comp_unit->GetLineTable();
2001 }
2002 if (line_table != NULL)
2003 line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
2004
2005 sc_list.Append(sc);
2006 }
2007 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00002008}
2009
2010uint32_t
2011SymbolFileDWARF::FindFunctions
2012(
2013 const ConstString &name,
2014 uint32_t name_type_mask,
2015 bool append,
2016 SymbolContextList& sc_list
2017)
2018{
2019 Timer scoped_timer (__PRETTY_FUNCTION__,
2020 "SymbolFileDWARF::FindFunctions (name = '%s')",
2021 name.AsCString());
2022
Greg Clayton0c5cd902010-06-28 21:30:43 +00002023 // If we aren't appending the results to this list, then clear the list
2024 if (!append)
2025 sc_list.Clear();
2026
2027 // Remember how many sc_list are in the list before we search in case
2028 // we are appending the results to a variable list.
2029 uint32_t original_size = sc_list.GetSize();
2030
2031 // Index the DWARF if we haven't already
2032 if (!m_indexed)
2033 Index ();
2034
2035 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002036 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002037
2038 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002039 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002040
2041 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002042 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002043
2044 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002045 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002046
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002047 // Return the number of variable that were appended to the list
2048 return sc_list.GetSize() - original_size;
2049}
2050
2051
2052uint32_t
2053SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2054{
2055 Timer scoped_timer (__PRETTY_FUNCTION__,
2056 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2057 regex.GetText());
2058
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002059 // If we aren't appending the results to this list, then clear the list
2060 if (!append)
2061 sc_list.Clear();
2062
2063 // Remember how many sc_list are in the list before we search in case
2064 // we are appending the results to a variable list.
2065 uint32_t original_size = sc_list.GetSize();
2066
2067 // Index the DWARF if we haven't already
2068 if (!m_indexed)
2069 Index ();
2070
Greg Claytonc685f8e2010-09-15 04:15:46 +00002071 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002072
Greg Claytonc685f8e2010-09-15 04:15:46 +00002073 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002074
2075 // Return the number of variable that were appended to the list
2076 return sc_list.GetSize() - original_size;
2077}
2078
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002079uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002080SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002081{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002082 DWARFDebugInfo* info = DebugInfo();
2083 if (info == NULL)
2084 return 0;
2085
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002086 // If we aren't appending the results to this list, then clear the list
2087 if (!append)
2088 types.Clear();
2089
Greg Clayton6dbd3982010-09-15 05:51:24 +00002090 // Index if we already haven't to make sure the compile units
2091 // get indexed and make their global DIE index list
2092 if (!m_indexed)
2093 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002094
Greg Claytonc685f8e2010-09-15 04:15:46 +00002095 const uint32_t initial_types_size = types.GetSize();
Greg Clayton96d7d742010-11-10 23:42:09 +00002096 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002097 DWARFCompileUnit* prev_cu = NULL;
2098 const DWARFDebugInfoEntry* die = NULL;
2099 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002100 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002101 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002102 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002103 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002104
Greg Clayton96d7d742010-11-10 23:42:09 +00002105 if (curr_cu != prev_cu)
2106 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002107
Greg Clayton96d7d742010-11-10 23:42:09 +00002108 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002109
Greg Clayton96d7d742010-11-10 23:42:09 +00002110 Type *matching_type = ResolveType (curr_cu, die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002111 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002112 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002113 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002114 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonc685f8e2010-09-15 04:15:46 +00002115 assert (type_sp.get() != NULL);
2116 types.InsertUnique (type_sp);
2117 if (types.GetSize() >= max_matches)
2118 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002119 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002120 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002121 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002122}
2123
2124
Greg Clayton526e5af2010-11-13 03:52:47 +00002125ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002126SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2127 const ConstString &name)
2128{
Greg Clayton526e5af2010-11-13 03:52:47 +00002129 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002130 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002131 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002132 {
Greg Clayton526e5af2010-11-13 03:52:47 +00002133 // Index if we already haven't to make sure the compile units
2134 // get indexed and make their global DIE index list
2135 if (!m_indexed)
2136 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002137
Greg Clayton526e5af2010-11-13 03:52:47 +00002138 DWARFCompileUnit* curr_cu = NULL;
2139 DWARFCompileUnit* prev_cu = NULL;
2140 const DWARFDebugInfoEntry* die = NULL;
2141 std::vector<NameToDIE::Info> die_info_array;
2142 const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2143 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2144 {
2145 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2146
2147 if (curr_cu != prev_cu)
2148 curr_cu->ExtractDIEsIfNeeded (false);
Greg Clayton96d7d742010-11-10 23:42:09 +00002149
Greg Clayton526e5af2010-11-13 03:52:47 +00002150 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2151
2152 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2153 if (clang_namespace_decl)
2154 {
2155 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2156 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2157 }
2158 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002159 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002160 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002161}
2162
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002163uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002164SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002165{
2166 // Remember how many sc_list are in the list before we search in case
2167 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002168 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002169
2170 const uint32_t num_die_offsets = die_offsets.size();
2171 // Parse all of the types we found from the pubtypes matches
2172 uint32_t i;
2173 uint32_t num_matches = 0;
2174 for (i = 0; i < num_die_offsets; ++i)
2175 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002176 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2177 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002178 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002179 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002180 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002181 assert (type_sp.get() != NULL);
2182 types.InsertUnique (type_sp);
2183 ++num_matches;
2184 if (num_matches >= max_matches)
2185 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002186 }
2187 }
2188
2189 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002190 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002191}
2192
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002193
2194size_t
2195SymbolFileDWARF::ParseChildParameters
2196(
2197 const SymbolContext& sc,
2198 TypeSP& type_sp,
Greg Clayton0fffff52010-09-24 05:15:53 +00002199 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002200 const DWARFDebugInfoEntry *parent_die,
Greg Claytona51ed9b2010-09-23 01:09:21 +00002201 bool skip_artificial,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002202 TypeList* type_list,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002203 std::vector<clang_type_t>& function_param_types,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002204 std::vector<clang::ParmVarDecl*>& function_param_decls
2205)
2206{
2207 if (parent_die == NULL)
2208 return 0;
2209
Greg Claytond88d7592010-09-15 08:33:30 +00002210 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2211
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002212 size_t count = 0;
2213 const DWARFDebugInfoEntry *die;
2214 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2215 {
2216 dw_tag_t tag = die->Tag();
2217 switch (tag)
2218 {
2219 case DW_TAG_formal_parameter:
2220 {
2221 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002222 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002223 if (num_attributes > 0)
2224 {
2225 const char *name = NULL;
2226 Declaration decl;
2227 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002228 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002229 // one of None, Auto, Register, Extern, Static, PrivateExtern
2230
Sean Callanane2ef6e32010-09-23 03:01:22 +00002231 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002232 uint32_t i;
2233 for (i=0; i<num_attributes; ++i)
2234 {
2235 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2236 DWARFFormValue form_value;
2237 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2238 {
2239 switch (attr)
2240 {
2241 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2242 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2243 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2244 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2245 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002246 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002247 case DW_AT_location:
2248 // if (form_value.BlockData())
2249 // {
2250 // const DataExtractor& debug_info_data = debug_info();
2251 // uint32_t block_length = form_value.Unsigned();
2252 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2253 // }
2254 // else
2255 // {
2256 // }
2257 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002258 case DW_AT_const_value:
2259 case DW_AT_default_value:
2260 case DW_AT_description:
2261 case DW_AT_endianity:
2262 case DW_AT_is_optional:
2263 case DW_AT_segment:
2264 case DW_AT_variable_parameter:
2265 default:
2266 case DW_AT_abstract_origin:
2267 case DW_AT_sibling:
2268 break;
2269 }
2270 }
2271 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002272
Greg Clayton0fffff52010-09-24 05:15:53 +00002273 bool skip = false;
2274 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002275 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002276 if (is_artificial)
2277 skip = true;
2278 else
2279 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002280
Greg Clayton0fffff52010-09-24 05:15:53 +00002281 // HACK: Objective C formal parameters "self" and "_cmd"
2282 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002283 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2284 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002285 {
2286 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2287 skip = true;
2288 }
2289 }
2290 }
2291
2292 if (!skip)
2293 {
2294 Type *type = ResolveTypeUID(param_type_die_offset);
2295 if (type)
2296 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002297 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002298
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002299 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002300 assert(param_var_decl);
2301 function_param_decls.push_back(param_var_decl);
2302 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002303 }
2304 }
2305 }
2306 break;
2307
2308 default:
2309 break;
2310 }
2311 }
2312 return count;
2313}
2314
2315size_t
2316SymbolFileDWARF::ParseChildEnumerators
2317(
2318 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002319 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002320 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002321 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002322 const DWARFDebugInfoEntry *parent_die
2323)
2324{
2325 if (parent_die == NULL)
2326 return 0;
2327
2328 size_t enumerators_added = 0;
2329 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002330 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2331
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002332 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2333 {
2334 const dw_tag_t tag = die->Tag();
2335 if (tag == DW_TAG_enumerator)
2336 {
2337 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002338 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002339 if (num_child_attributes > 0)
2340 {
2341 const char *name = NULL;
2342 bool got_value = false;
2343 int64_t enum_value = 0;
2344 Declaration decl;
2345
2346 uint32_t i;
2347 for (i=0; i<num_child_attributes; ++i)
2348 {
2349 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2350 DWARFFormValue form_value;
2351 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2352 {
2353 switch (attr)
2354 {
2355 case DW_AT_const_value:
2356 got_value = true;
2357 enum_value = form_value.Unsigned();
2358 break;
2359
2360 case DW_AT_name:
2361 name = form_value.AsCString(&get_debug_str_data());
2362 break;
2363
2364 case DW_AT_description:
2365 default:
2366 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2367 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2368 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2369 case DW_AT_sibling:
2370 break;
2371 }
2372 }
2373 }
2374
2375 if (name && name[0] && got_value)
2376 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002377 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2378 enumerator_clang_type,
2379 decl,
2380 name,
2381 enum_value,
2382 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002383 ++enumerators_added;
2384 }
2385 }
2386 }
2387 }
2388 return enumerators_added;
2389}
2390
2391void
2392SymbolFileDWARF::ParseChildArrayInfo
2393(
2394 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002395 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002396 const DWARFDebugInfoEntry *parent_die,
2397 int64_t& first_index,
2398 std::vector<uint64_t>& element_orders,
2399 uint32_t& byte_stride,
2400 uint32_t& bit_stride
2401)
2402{
2403 if (parent_die == NULL)
2404 return;
2405
2406 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002407 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002408 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2409 {
2410 const dw_tag_t tag = die->Tag();
2411 switch (tag)
2412 {
2413 case DW_TAG_enumerator:
2414 {
2415 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002416 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002417 if (num_child_attributes > 0)
2418 {
2419 const char *name = NULL;
2420 bool got_value = false;
2421 int64_t enum_value = 0;
2422
2423 uint32_t i;
2424 for (i=0; i<num_child_attributes; ++i)
2425 {
2426 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2427 DWARFFormValue form_value;
2428 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2429 {
2430 switch (attr)
2431 {
2432 case DW_AT_const_value:
2433 got_value = true;
2434 enum_value = form_value.Unsigned();
2435 break;
2436
2437 case DW_AT_name:
2438 name = form_value.AsCString(&get_debug_str_data());
2439 break;
2440
2441 case DW_AT_description:
2442 default:
2443 case DW_AT_decl_file:
2444 case DW_AT_decl_line:
2445 case DW_AT_decl_column:
2446 case DW_AT_sibling:
2447 break;
2448 }
2449 }
2450 }
2451 }
2452 }
2453 break;
2454
2455 case DW_TAG_subrange_type:
2456 {
2457 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002458 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002459 if (num_child_attributes > 0)
2460 {
2461 const char *name = NULL;
2462 bool got_value = false;
2463 uint64_t byte_size = 0;
2464 int64_t enum_value = 0;
2465 uint64_t num_elements = 0;
2466 uint64_t lower_bound = 0;
2467 uint64_t upper_bound = 0;
2468 uint32_t i;
2469 for (i=0; i<num_child_attributes; ++i)
2470 {
2471 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2472 DWARFFormValue form_value;
2473 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2474 {
2475 switch (attr)
2476 {
2477 case DW_AT_const_value:
2478 got_value = true;
2479 enum_value = form_value.Unsigned();
2480 break;
2481
2482 case DW_AT_name:
2483 name = form_value.AsCString(&get_debug_str_data());
2484 break;
2485
2486 case DW_AT_count:
2487 num_elements = form_value.Unsigned();
2488 break;
2489
2490 case DW_AT_bit_stride:
2491 bit_stride = form_value.Unsigned();
2492 break;
2493
2494 case DW_AT_byte_stride:
2495 byte_stride = form_value.Unsigned();
2496 break;
2497
2498 case DW_AT_byte_size:
2499 byte_size = form_value.Unsigned();
2500 break;
2501
2502 case DW_AT_lower_bound:
2503 lower_bound = form_value.Unsigned();
2504 break;
2505
2506 case DW_AT_upper_bound:
2507 upper_bound = form_value.Unsigned();
2508 break;
2509
2510 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002511 case DW_AT_abstract_origin:
2512 case DW_AT_accessibility:
2513 case DW_AT_allocated:
2514 case DW_AT_associated:
2515 case DW_AT_data_location:
2516 case DW_AT_declaration:
2517 case DW_AT_description:
2518 case DW_AT_sibling:
2519 case DW_AT_threads_scaled:
2520 case DW_AT_type:
2521 case DW_AT_visibility:
2522 break;
2523 }
2524 }
2525 }
2526
2527 if (upper_bound > lower_bound)
2528 num_elements = upper_bound - lower_bound + 1;
2529
2530 if (num_elements > 0)
2531 element_orders.push_back (num_elements);
2532 }
2533 }
2534 break;
2535 }
2536 }
2537}
2538
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002539TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002540SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002541{
2542 TypeSP type_sp;
2543 if (die != NULL)
2544 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002545 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002546 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002547 if (type_ptr == NULL)
2548 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002549 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
2550 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002551 }
2552 else if (type_ptr != DIE_IS_BEING_PARSED)
2553 {
2554 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002555 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002556 }
2557
2558 }
2559 return type_sp;
2560}
2561
2562clang::DeclContext *
2563SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2564{
2565 if (die_offset != DW_INVALID_OFFSET)
2566 {
2567 DWARFCompileUnitSP cu_sp;
2568 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2569 return GetClangDeclContextForDIE (cu_sp.get(), die);
2570 }
2571 return NULL;
2572}
2573
2574
Greg Clayton96d7d742010-11-10 23:42:09 +00002575clang::NamespaceDecl *
2576SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2577{
2578 if (die->Tag() == DW_TAG_namespace)
2579 {
2580 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2581 if (namespace_name)
2582 {
2583 Declaration decl; // TODO: fill in the decl object
2584 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2585 if (namespace_decl)
2586 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2587 return namespace_decl;
2588 }
2589 }
2590 return NULL;
2591}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002592
2593clang::DeclContext *
Greg Clayton96d7d742010-11-10 23:42:09 +00002594SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002595{
2596 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2597 if (pos != m_die_to_decl_ctx.end())
2598 return pos->second;
2599
2600 while (die != NULL)
2601 {
2602 switch (die->Tag())
2603 {
2604 case DW_TAG_namespace:
2605 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002606 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002607 if (namespace_name)
2608 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002609 Declaration decl; // TODO: fill in the decl object
Greg Clayton96d7d742010-11-10 23:42:09 +00002610 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002611 if (namespace_decl)
2612 m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2613 return namespace_decl;
2614 }
2615 }
2616 break;
2617
2618 default:
2619 break;
2620 }
2621 clang::DeclContext *decl_ctx;
Greg Clayton96d7d742010-11-10 23:42:09 +00002622 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002623 if (decl_ctx)
2624 return decl_ctx;
2625
Greg Clayton96d7d742010-11-10 23:42:09 +00002626 decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002627 if (decl_ctx)
2628 return decl_ctx;
2629
2630 die = die->GetParent();
2631 }
Greg Clayton7a345282010-11-09 23:46:37 +00002632 // Right now we have only one translation unit per module...
2633 if (m_clang_tu_decl == NULL)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002634 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Greg Clayton7a345282010-11-09 23:46:37 +00002635 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002636}
2637
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002638// This function can be used when a DIE is found that is a forward declaration
2639// DIE and we want to try and find a type that has the complete definition.
2640TypeSP
2641SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Clayton96d7d742010-11-10 23:42:09 +00002642 DWARFCompileUnit* curr_cu,
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002643 const DWARFDebugInfoEntry *die,
2644 const ConstString &type_name
2645)
2646{
2647 TypeSP type_sp;
2648
Greg Clayton96d7d742010-11-10 23:42:09 +00002649 if (curr_cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002650 return type_sp;
2651
2652 const dw_tag_t type_tag = die->Tag();
2653 std::vector<NameToDIE::Info> die_info_array;
2654 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2655 if (num_matches > 0)
2656 {
2657 DWARFCompileUnit* type_cu = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00002658 DWARFCompileUnit* curr_cu = curr_cu;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002659 DWARFDebugInfo *info = DebugInfo();
2660 for (size_t i=0; i<num_matches; ++i)
2661 {
2662 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2663
2664 if (type_cu != curr_cu)
2665 {
2666 type_cu->ExtractDIEsIfNeeded (false);
2667 curr_cu = type_cu;
2668 }
2669
2670 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2671
2672 if (type_die != die && type_die->Tag() == type_tag)
2673 {
2674 // Hold off on comparing parent DIE tags until
2675 // we know what happens with stuff in namespaces
2676 // for gcc and clang...
2677 //DWARFDebugInfoEntry *parent_die = die->GetParent();
2678 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2679 //if (parent_die->Tag() == parent_type_die->Tag())
2680 {
2681 Type *resolved_type = ResolveType (type_cu, type_die, false);
2682 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2683 {
2684 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2685 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00002686 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002687 m_obj_file->GetFileSpec().GetFilename().AsCString(),
2688 type_die->GetOffset(),
2689 type_cu->GetOffset());
2690
2691 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002692 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00002693 if (!type_sp)
2694 {
2695 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2696 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002697 break;
2698 }
2699 }
2700 }
2701 }
2702 }
2703 return type_sp;
2704}
2705
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002706TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00002707SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002708{
2709 TypeSP type_sp;
2710
Greg Clayton1be10fc2010-09-29 01:12:09 +00002711 if (type_is_new_ptr)
2712 *type_is_new_ptr = false;
2713
Sean Callananc7fbf732010-08-06 00:32:49 +00002714 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002715 if (die != NULL)
2716 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00002717 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002718 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00002719 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002720 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002721 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00002722 if (type_is_new_ptr)
2723 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002724
Greg Clayton594e5ed2010-09-27 21:07:38 +00002725 const dw_tag_t tag = die->Tag();
2726
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002727 bool is_forward_declaration = false;
2728 DWARFDebugInfoEntry::Attributes attributes;
2729 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00002730 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00002731 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
2732 size_t byte_size = 0;
2733 Declaration decl;
2734
Greg Clayton4957bf62010-09-30 21:49:03 +00002735 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00002736 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002737
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002738 dw_attr_t attr;
2739
2740 switch (tag)
2741 {
2742 case DW_TAG_base_type:
2743 case DW_TAG_pointer_type:
2744 case DW_TAG_reference_type:
2745 case DW_TAG_typedef:
2746 case DW_TAG_const_type:
2747 case DW_TAG_restrict_type:
2748 case DW_TAG_volatile_type:
2749 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002750 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002751 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002752
Greg Claytond88d7592010-09-15 08:33:30 +00002753 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002754 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002755 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2756
2757 if (num_attributes > 0)
2758 {
2759 uint32_t i;
2760 for (i=0; i<num_attributes; ++i)
2761 {
2762 attr = attributes.AttributeAtIndex(i);
2763 DWARFFormValue form_value;
2764 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2765 {
2766 switch (attr)
2767 {
2768 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2769 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2770 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2771 case DW_AT_name:
2772 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00002773 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002774 break;
2775 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
2776 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
2777 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
2778 default:
2779 case DW_AT_sibling:
2780 break;
2781 }
2782 }
2783 }
2784 }
2785
Greg Claytonc93237c2010-10-01 20:48:32 +00002786 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);
2787
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002788 switch (tag)
2789 {
2790 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00002791 break;
2792
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002793 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00002794 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002795 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
2796 encoding,
2797 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002798 break;
2799
Greg Clayton526e5af2010-11-13 03:52:47 +00002800 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
2801 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
2802 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
2803 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
2804 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
2805 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002806 }
2807
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002808 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
2809 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
2810 {
2811 static ConstString g_objc_type_name_id("id");
2812 static ConstString g_objc_type_name_Class("Class");
2813 static ConstString g_objc_type_name_selector("SEL");
2814
Greg Clayton24739922010-10-13 03:15:28 +00002815 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002816 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002817 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00002818 resolve_state = Type::eResolveStateFull;
2819
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002820 }
Greg Clayton24739922010-10-13 03:15:28 +00002821 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002822 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002823 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00002824 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002825 }
Greg Clayton24739922010-10-13 03:15:28 +00002826 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002827 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002828 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00002829 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002830 }
2831 }
2832
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002833 type_sp.reset( new Type (die->GetOffset(),
2834 this,
2835 type_name_const_str,
2836 byte_size,
2837 NULL,
2838 encoding_uid,
2839 encoding_data_type,
2840 &decl,
2841 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00002842 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002843
Greg Clayton594e5ed2010-09-27 21:07:38 +00002844 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002845
2846// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2847// if (encoding_type != NULL)
2848// {
2849// if (encoding_type != DIE_IS_BEING_PARSED)
2850// type_sp->SetEncodingType(encoding_type);
2851// else
2852// m_indirect_fixups.push_back(type_sp.get());
2853// }
2854 }
2855 break;
2856
2857 case DW_TAG_structure_type:
2858 case DW_TAG_union_type:
2859 case DW_TAG_class_type:
2860 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002861 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00002862 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002863
Greg Clayton9e409562010-07-28 02:04:09 +00002864 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002865 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00002866 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002867 if (num_attributes > 0)
2868 {
2869 uint32_t i;
2870 for (i=0; i<num_attributes; ++i)
2871 {
2872 attr = attributes.AttributeAtIndex(i);
2873 DWARFFormValue form_value;
2874 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2875 {
2876 switch (attr)
2877 {
Greg Clayton9e409562010-07-28 02:04:09 +00002878 case DW_AT_decl_file:
2879 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
2880 break;
2881
2882 case DW_AT_decl_line:
2883 decl.SetLine(form_value.Unsigned());
2884 break;
2885
2886 case DW_AT_decl_column:
2887 decl.SetColumn(form_value.Unsigned());
2888 break;
2889
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002890 case DW_AT_name:
2891 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00002892 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002893 break;
Greg Clayton9e409562010-07-28 02:04:09 +00002894
2895 case DW_AT_byte_size:
2896 byte_size = form_value.Unsigned();
2897 break;
2898
2899 case DW_AT_accessibility:
2900 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2901 break;
2902
2903 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00002904 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00002905 break;
2906
2907 case DW_AT_APPLE_runtime_class:
2908 class_language = (LanguageType)form_value.Signed();
2909 break;
2910
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002911 case DW_AT_allocated:
2912 case DW_AT_associated:
2913 case DW_AT_data_location:
2914 case DW_AT_description:
2915 case DW_AT_start_scope:
2916 case DW_AT_visibility:
2917 default:
2918 case DW_AT_sibling:
2919 break;
2920 }
2921 }
2922 }
2923 }
2924
Greg Claytonc93237c2010-10-01 20:48:32 +00002925 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
2926
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002927 int tag_decl_kind = -1;
Sean Callananc7fbf732010-08-06 00:32:49 +00002928 AccessType default_accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002929 if (tag == DW_TAG_structure_type)
2930 {
2931 tag_decl_kind = clang::TTK_Struct;
Sean Callananc7fbf732010-08-06 00:32:49 +00002932 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002933 }
2934 else if (tag == DW_TAG_union_type)
2935 {
2936 tag_decl_kind = clang::TTK_Union;
Sean Callananc7fbf732010-08-06 00:32:49 +00002937 default_accessibility = eAccessPublic;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002938 }
2939 else if (tag == DW_TAG_class_type)
2940 {
2941 tag_decl_kind = clang::TTK_Class;
Sean Callananc7fbf732010-08-06 00:32:49 +00002942 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002943 }
2944
Greg Clayton24739922010-10-13 03:15:28 +00002945
Greg Claytonc615ce42010-11-09 04:42:43 +00002946 if (is_forward_declaration)
2947 {
2948 // We have a forward declaration to a type and we need
2949 // to try and find a full declaration. We look in the
2950 // current type index just in case we have a forward
2951 // declaration followed by an actual declarations in the
2952 // DWARF. If this fails, we need to look elsewhere...
2953
2954 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
2955
2956 if (!type_sp)
2957 {
2958 // We weren't able to find a full declaration in
2959 // this DWARF, see if we have a declaration anywhere
2960 // else...
2961 if (m_debug_map_symfile)
2962 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
2963 }
2964 if (type_sp)
2965 return type_sp;
2966 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002967 assert (tag_decl_kind != -1);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002968 bool clang_type_was_created = false;
2969 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
2970 if (clang_type == NULL)
2971 {
2972 clang_type_was_created = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002973 clang_type = ast.CreateRecordType (type_name_cstr,
2974 tag_decl_kind,
2975 GetClangDeclContextForDIE (dwarf_cu, die),
2976 class_language);
Greg Clayton1be10fc2010-09-29 01:12:09 +00002977 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002978
Greg Clayton6adffa22010-09-28 01:04:25 +00002979 // Store a forward declaration to this class type in case any
2980 // parameters in any class methods need it for the clang
2981 // types for function prototypes.
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002982 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002983 type_sp.reset (new Type (die->GetOffset(),
2984 this,
2985 type_name_const_str,
2986 byte_size,
2987 NULL,
2988 LLDB_INVALID_UID,
2989 Type::eEncodingIsUID,
2990 &decl,
2991 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00002992 Type::eResolveStateForward));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002993
Greg Clayton594e5ed2010-09-27 21:07:38 +00002994 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002995
Greg Clayton40328bf2010-11-08 02:05:08 +00002996 if (die->HasChildren() == false && is_forward_declaration == false)
Greg Clayton1be10fc2010-09-29 01:12:09 +00002997 {
Greg Clayton4957bf62010-09-30 21:49:03 +00002998 // No children for this struct/union/class, lets finish it
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002999 ast.StartTagDeclarationDefinition (clang_type);
3000 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton4957bf62010-09-30 21:49:03 +00003001 }
3002 else if (clang_type_was_created)
3003 {
3004 // Leave this as a forward declaration until we need
3005 // to know the details of the type. lldb_private::Type
3006 // will automatically call the SymbolFile virtual function
3007 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3008 // When the definition needs to be defined.
Greg Clayton1be10fc2010-09-29 01:12:09 +00003009 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003010 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003011 }
Greg Clayton4957bf62010-09-30 21:49:03 +00003012
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003013 }
3014 break;
3015
3016 case DW_TAG_enumeration_type:
3017 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003018 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003019 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003020
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003021 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003022
Greg Claytond88d7592010-09-15 08:33:30 +00003023 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003024 if (num_attributes > 0)
3025 {
3026 uint32_t i;
3027
3028 for (i=0; i<num_attributes; ++i)
3029 {
3030 attr = attributes.AttributeAtIndex(i);
3031 DWARFFormValue form_value;
3032 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3033 {
3034 switch (attr)
3035 {
Greg Clayton7a345282010-11-09 23:46:37 +00003036 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3037 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3038 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003039 case DW_AT_name:
3040 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003041 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003042 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003043 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3044 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3045 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3046 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003047 case DW_AT_allocated:
3048 case DW_AT_associated:
3049 case DW_AT_bit_stride:
3050 case DW_AT_byte_stride:
3051 case DW_AT_data_location:
3052 case DW_AT_description:
3053 case DW_AT_start_scope:
3054 case DW_AT_visibility:
3055 case DW_AT_specification:
3056 case DW_AT_abstract_origin:
3057 case DW_AT_sibling:
3058 break;
3059 }
3060 }
3061 }
3062
Greg Claytonc93237c2010-10-01 20:48:32 +00003063 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3064
Greg Clayton1be10fc2010-09-29 01:12:09 +00003065 clang_type_t enumerator_clang_type = NULL;
3066 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3067 if (clang_type == NULL)
3068 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003069 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3070 DW_ATE_signed,
3071 byte_size * 8);
3072 clang_type = ast.CreateEnumerationType (decl,
3073 type_name_cstr,
3074 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003075 }
3076 else
3077 {
3078 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3079 assert (enumerator_clang_type != NULL);
3080 }
3081
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003082 m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003083 type_sp.reset( new Type (die->GetOffset(),
3084 this,
3085 type_name_const_str,
3086 byte_size,
3087 NULL,
3088 encoding_uid,
3089 Type::eEncodingIsUID,
3090 &decl,
3091 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003092 Type::eResolveStateForward));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003093
Greg Clayton594e5ed2010-09-27 21:07:38 +00003094 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003095
Greg Clayton1be10fc2010-09-29 01:12:09 +00003096 // Leave this as a forward declaration until we need
3097 // to know the details of the type. lldb_private::Type
3098 // will automatically call the SymbolFile virtual function
3099 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3100 // When the definition needs to be defined.
3101 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003102 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003103
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003104 }
3105 }
3106 break;
3107
Jim Inghamb0be4422010-08-12 01:20:14 +00003108 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003109 case DW_TAG_subprogram:
3110 case DW_TAG_subroutine_type:
3111 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003112 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003113 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003114
3115 const char *mangled = NULL;
3116 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003117 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003118 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003119 bool is_static = false;
3120 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003121 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003122
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003123 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003124 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003125
3126
Greg Claytond88d7592010-09-15 08:33:30 +00003127 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003128 if (num_attributes > 0)
3129 {
3130 uint32_t i;
3131 for (i=0; i<num_attributes; ++i)
3132 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003133 const dw_attr_t attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003134 DWARFFormValue form_value;
3135 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3136 {
3137 switch (attr)
3138 {
3139 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3140 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3141 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3142 case DW_AT_name:
3143 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003144 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003145 break;
3146
3147 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3148 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003149 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003150 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003151 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3152 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003153 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3154
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003155 case DW_AT_external:
3156 if (form_value.Unsigned())
3157 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003158 if (storage == clang::SC_None)
3159 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003160 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003161 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003162 }
3163 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003164
3165 case DW_AT_allocated:
3166 case DW_AT_associated:
3167 case DW_AT_address_class:
3168 case DW_AT_artificial:
3169 case DW_AT_calling_convention:
3170 case DW_AT_data_location:
3171 case DW_AT_elemental:
3172 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003173 case DW_AT_frame_base:
3174 case DW_AT_high_pc:
3175 case DW_AT_low_pc:
3176 case DW_AT_object_pointer:
3177 case DW_AT_prototyped:
3178 case DW_AT_pure:
3179 case DW_AT_ranges:
3180 case DW_AT_recursive:
3181 case DW_AT_return_addr:
3182 case DW_AT_segment:
3183 case DW_AT_specification:
3184 case DW_AT_start_scope:
3185 case DW_AT_static_link:
3186 case DW_AT_trampoline:
3187 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003188 case DW_AT_vtable_elem_location:
3189 case DW_AT_abstract_origin:
3190 case DW_AT_description:
3191 case DW_AT_sibling:
3192 break;
3193 }
3194 }
3195 }
Greg Clayton24739922010-10-13 03:15:28 +00003196 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003197
Greg Clayton24739922010-10-13 03:15:28 +00003198 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 +00003199
Greg Clayton24739922010-10-13 03:15:28 +00003200 clang_type_t return_clang_type = NULL;
3201 Type *func_type = NULL;
3202
3203 if (type_die_offset != DW_INVALID_OFFSET)
3204 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003205
Greg Clayton24739922010-10-13 03:15:28 +00003206 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003207 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003208 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003209 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003210
Greg Claytonf51de672010-10-01 02:31:07 +00003211
Greg Clayton24739922010-10-13 03:15:28 +00003212 std::vector<clang_type_t> function_param_types;
3213 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003214
Greg Clayton24739922010-10-13 03:15:28 +00003215 // Parse the function children for the parameters
3216 if (die->HasChildren())
3217 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003218 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003219 ParseChildParameters (sc,
3220 type_sp,
3221 dwarf_cu,
3222 die,
3223 skip_artificial,
3224 type_list,
3225 function_param_types,
3226 function_param_decls);
Greg Clayton24739922010-10-13 03:15:28 +00003227 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003228
Greg Clayton24739922010-10-13 03:15:28 +00003229 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003230 clang_type = ast.CreateFunctionType (return_clang_type,
3231 &function_param_types[0],
3232 function_param_types.size(),
3233 is_variadic,
3234 type_quals);
3235
Greg Clayton24739922010-10-13 03:15:28 +00003236 if (type_name_cstr)
3237 {
3238 bool type_handled = false;
3239 const DWARFDebugInfoEntry *parent_die = die->GetParent();
3240 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003241 {
Greg Clayton24739922010-10-13 03:15:28 +00003242 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003243 {
Greg Clayton24739922010-10-13 03:15:28 +00003244 // We need to find the DW_TAG_class_type or
3245 // DW_TAG_struct_type by name so we can add this
3246 // as a member function of the class.
3247 const char *class_name_start = type_name_cstr + 2;
3248 const char *class_name_end = ::strchr (class_name_start, ' ');
3249 SymbolContext empty_sc;
3250 clang_type_t class_opaque_type = NULL;
3251 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003252 {
Greg Clayton24739922010-10-13 03:15:28 +00003253 ConstString class_name (class_name_start, class_name_end - class_name_start);
3254 TypeList types;
3255 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3256 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003257 {
Greg Clayton24739922010-10-13 03:15:28 +00003258 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003259 {
Greg Clayton24739922010-10-13 03:15:28 +00003260 Type *type = types.GetTypeAtIndex (i).get();
3261 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3262 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003263 {
Greg Clayton24739922010-10-13 03:15:28 +00003264 class_opaque_type = type_clang_forward_type;
3265 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003266 }
3267 }
3268 }
Greg Clayton24739922010-10-13 03:15:28 +00003269 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003270
Greg Clayton24739922010-10-13 03:15:28 +00003271 if (class_opaque_type)
3272 {
3273 // If accessibility isn't set to anything valid, assume public for
3274 // now...
3275 if (accessibility == eAccessNone)
3276 accessibility = eAccessPublic;
3277
3278 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003279 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3280 type_name_cstr,
3281 clang_type,
3282 accessibility);
Greg Clayton24739922010-10-13 03:15:28 +00003283 type_handled = objc_method_decl != NULL;
3284 }
3285 }
3286 else if (parent_die->Tag() == DW_TAG_class_type ||
3287 parent_die->Tag() == DW_TAG_structure_type)
3288 {
3289 // Look at the parent of this DIE and see if is is
3290 // a class or struct and see if this is actually a
3291 // C++ method
3292 Type *class_type = ResolveType (dwarf_cu, parent_die);
3293 if (class_type)
3294 {
3295 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3296 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003297 {
Greg Clayton24739922010-10-13 03:15:28 +00003298 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3299 // in the DWARF for C++ methods... Default to public for now...
Greg Clayton6d01ad92010-09-29 01:57:37 +00003300 if (accessibility == eAccessNone)
3301 accessibility = eAccessPublic;
3302
Greg Clayton24739922010-10-13 03:15:28 +00003303 clang::CXXMethodDecl *cxx_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003304 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3305 type_name_cstr,
3306 clang_type,
3307 accessibility,
3308 is_virtual,
3309 is_static,
3310 is_inline,
3311 is_explicit);
Greg Clayton24739922010-10-13 03:15:28 +00003312 type_handled = cxx_method_decl != NULL;
Greg Clayton0fffff52010-09-24 05:15:53 +00003313 }
3314 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003315 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003316 }
Greg Clayton24739922010-10-13 03:15:28 +00003317
3318 if (!type_handled)
3319 {
3320 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003321 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3322 clang_type,
3323 storage,
3324 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003325
3326 // Add the decl to our DIE to decl context map
3327 assert (function_decl);
3328 m_die_to_decl_ctx[die] = function_decl;
3329 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003330 ast.SetFunctionParameters (function_decl,
3331 &function_param_decls.front(),
3332 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003333 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003334 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003335 type_sp.reset( new Type (die->GetOffset(),
3336 this,
3337 type_name_const_str,
3338 0,
3339 NULL,
3340 LLDB_INVALID_UID,
3341 Type::eEncodingIsUID,
3342 &decl,
3343 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003344 Type::eResolveStateFull));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003345
Greg Clayton24739922010-10-13 03:15:28 +00003346 m_die_to_type[die] = type_sp.get();
3347 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003348 }
3349 break;
3350
3351 case DW_TAG_array_type:
3352 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003353 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003354 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003355
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003356 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003357 int64_t first_index = 0;
3358 uint32_t byte_stride = 0;
3359 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003360 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003361
3362 if (num_attributes > 0)
3363 {
3364 uint32_t i;
3365 for (i=0; i<num_attributes; ++i)
3366 {
3367 attr = attributes.AttributeAtIndex(i);
3368 DWARFFormValue form_value;
3369 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3370 {
3371 switch (attr)
3372 {
3373 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3374 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3375 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3376 case DW_AT_name:
3377 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003378 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003379 break;
3380
3381 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
3382 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
3383 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3384 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003385 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003386 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003387 case DW_AT_allocated:
3388 case DW_AT_associated:
3389 case DW_AT_data_location:
3390 case DW_AT_description:
3391 case DW_AT_ordering:
3392 case DW_AT_start_scope:
3393 case DW_AT_visibility:
3394 case DW_AT_specification:
3395 case DW_AT_abstract_origin:
3396 case DW_AT_sibling:
3397 break;
3398 }
3399 }
3400 }
3401
Greg Claytonc93237c2010-10-01 20:48:32 +00003402 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3403
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003404 Type *element_type = ResolveTypeUID(type_die_offset);
3405
3406 if (element_type)
3407 {
3408 std::vector<uint64_t> element_orders;
3409 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003410 // We have an array that claims to have no members, lets give it at least one member...
3411 if (element_orders.empty())
3412 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003413 if (byte_stride == 0 && bit_stride == 0)
3414 byte_stride = element_type->GetByteSize();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003415 clang_type_t array_element_type = element_type->GetClangType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003416 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3417 uint64_t num_elements = 0;
3418 std::vector<uint64_t>::const_reverse_iterator pos;
3419 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3420 for (pos = element_orders.rbegin(); pos != end; ++pos)
3421 {
3422 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003423 clang_type = ast.CreateArrayType (array_element_type,
3424 num_elements,
3425 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003426 array_element_type = clang_type;
3427 array_element_bit_stride = array_element_bit_stride * num_elements;
3428 }
3429 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003430 type_sp.reset( new Type (die->GetOffset(),
3431 this,
3432 empty_name,
3433 array_element_bit_stride / 8,
3434 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00003435 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003436 Type::eEncodingIsUID,
3437 &decl,
3438 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003439 Type::eResolveStateFull));
3440 type_sp->SetEncodingType (element_type);
Greg Clayton594e5ed2010-09-27 21:07:38 +00003441 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003442 }
3443 }
3444 }
3445 break;
3446
Greg Clayton9b81a312010-06-12 01:20:30 +00003447 case DW_TAG_ptr_to_member_type:
3448 {
3449 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3450 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3451
Greg Claytond88d7592010-09-15 08:33:30 +00003452 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003453
3454 if (num_attributes > 0) {
3455 uint32_t i;
3456 for (i=0; i<num_attributes; ++i)
3457 {
3458 attr = attributes.AttributeAtIndex(i);
3459 DWARFFormValue form_value;
3460 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3461 {
3462 switch (attr)
3463 {
3464 case DW_AT_type:
3465 type_die_offset = form_value.Reference(dwarf_cu); break;
3466 case DW_AT_containing_type:
3467 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3468 }
3469 }
3470 }
3471
3472 Type *pointee_type = ResolveTypeUID(type_die_offset);
3473 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3474
Greg Clayton526e5af2010-11-13 03:52:47 +00003475 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
3476 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003477
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003478 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3479 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003480
Greg Clayton526e5af2010-11-13 03:52:47 +00003481 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3482 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003483
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003484 type_sp.reset( new Type (die->GetOffset(),
3485 this,
3486 type_name_const_str,
3487 byte_size,
3488 NULL,
3489 LLDB_INVALID_UID,
3490 Type::eEncodingIsUID,
3491 NULL,
3492 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003493 Type::eResolveStateForward));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003494 m_die_to_type[die] = type_sp.get();
Greg Clayton9b81a312010-06-12 01:20:30 +00003495 }
3496
3497 break;
3498 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003499 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003500 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003501 break;
3502 }
3503
3504 if (type_sp.get())
3505 {
3506 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3507 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3508
3509 SymbolContextScope * symbol_context_scope = NULL;
3510 if (sc_parent_tag == DW_TAG_compile_unit)
3511 {
3512 symbol_context_scope = sc.comp_unit;
3513 }
3514 else if (sc.function != NULL)
3515 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003516 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003517 if (symbol_context_scope == NULL)
3518 symbol_context_scope = sc.function;
3519 }
3520
3521 if (symbol_context_scope != NULL)
3522 {
3523 type_sp->SetSymbolContextScope(symbol_context_scope);
3524 }
3525
3526// if (udt_sp.get())
3527// {
3528// if (is_forward_declaration)
3529// udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3530// type_sp->SetUserDefinedType(udt_sp);
3531// }
3532
3533 if (type_sp.unique())
3534 {
3535 // We are ready to put this type into the uniqued list up at the module level
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003536 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00003537
Greg Clayton594e5ed2010-09-27 21:07:38 +00003538 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003539 }
3540 }
3541 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003542 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003543 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003544 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003545 }
3546 }
3547 return type_sp;
3548}
3549
3550size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003551SymbolFileDWARF::ParseTypes
3552(
3553 const SymbolContext& sc,
3554 DWARFCompileUnit* dwarf_cu,
3555 const DWARFDebugInfoEntry *die,
3556 bool parse_siblings,
3557 bool parse_children
3558)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003559{
3560 size_t types_added = 0;
3561 while (die != NULL)
3562 {
3563 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003564 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003565 {
3566 if (type_is_new)
3567 ++types_added;
3568 }
3569
3570 if (parse_children && die->HasChildren())
3571 {
3572 if (die->Tag() == DW_TAG_subprogram)
3573 {
3574 SymbolContext child_sc(sc);
3575 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3576 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3577 }
3578 else
3579 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3580 }
3581
3582 if (parse_siblings)
3583 die = die->GetSibling();
3584 else
3585 die = NULL;
3586 }
3587 return types_added;
3588}
3589
3590
3591size_t
3592SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3593{
3594 assert(sc.comp_unit && sc.function);
3595 size_t functions_added = 0;
3596 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3597 if (dwarf_cu)
3598 {
3599 dw_offset_t function_die_offset = sc.function->GetID();
3600 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3601 if (function_die)
3602 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003603 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003604 }
3605 }
3606
3607 return functions_added;
3608}
3609
3610
3611size_t
3612SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3613{
3614 // At least a compile unit must be valid
3615 assert(sc.comp_unit);
3616 size_t types_added = 0;
3617 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3618 if (dwarf_cu)
3619 {
3620 if (sc.function)
3621 {
3622 dw_offset_t function_die_offset = sc.function->GetID();
3623 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3624 if (func_die && func_die->HasChildren())
3625 {
3626 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3627 }
3628 }
3629 else
3630 {
3631 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3632 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3633 {
3634 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3635 }
3636 }
3637 }
3638
3639 return types_added;
3640}
3641
3642size_t
3643SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3644{
3645 if (sc.comp_unit != NULL)
3646 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00003647 DWARFDebugInfo* info = DebugInfo();
3648 if (info == NULL)
3649 return 0;
3650
3651 uint32_t cu_idx = UINT32_MAX;
3652 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003653
3654 if (dwarf_cu == NULL)
3655 return 0;
3656
3657 if (sc.function)
3658 {
3659 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00003660
3661 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3662 assert (func_lo_pc != DW_INVALID_ADDRESS);
3663
3664 return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003665 }
3666 else if (sc.comp_unit)
3667 {
3668 uint32_t vars_added = 0;
3669 VariableListSP variables (sc.comp_unit->GetVariableList(false));
3670
3671 if (variables.get() == NULL)
3672 {
3673 variables.reset(new VariableList());
3674 sc.comp_unit->SetVariableList(variables);
3675
3676 // Index if we already haven't to make sure the compile units
3677 // get indexed and make their global DIE index list
3678 if (!m_indexed)
3679 Index ();
3680
Greg Claytonc685f8e2010-09-15 04:15:46 +00003681 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00003682 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003683 for (size_t idx=0; idx<num_globals; ++idx)
3684 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00003685 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 +00003686 if (var_sp)
3687 {
3688 variables->AddVariable(var_sp);
3689 ++vars_added;
3690 }
3691 }
3692 }
3693 return vars_added;
3694 }
3695 }
3696 return 0;
3697}
3698
3699
3700VariableSP
3701SymbolFileDWARF::ParseVariableDIE
3702(
3703 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003704 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003705 const DWARFDebugInfoEntry *die,
3706 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003707)
3708{
3709
3710 VariableSP var_sp;
3711
3712 const dw_tag_t tag = die->Tag();
3713 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003714 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003715 if (num_attributes > 0)
3716 {
3717 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00003718 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003719 Declaration decl;
3720 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003721 Type *var_type = NULL;
3722 DWARFExpression location;
3723 bool is_external = false;
3724 bool is_artificial = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00003725 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003726
3727 for (i=0; i<num_attributes; ++i)
3728 {
3729 dw_attr_t attr = attributes.AttributeAtIndex(i);
3730 DWARFFormValue form_value;
3731 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3732 {
3733 switch (attr)
3734 {
3735 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3736 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3737 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3738 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00003739 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00003740 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003741 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
3742 case DW_AT_location:
3743 {
3744 if (form_value.BlockData())
3745 {
3746 const DataExtractor& debug_info_data = get_debug_info_data();
3747
3748 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3749 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00003750 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003751 }
3752 else
3753 {
3754 const DataExtractor& debug_loc_data = get_debug_loc_data();
3755 const dw_offset_t debug_loc_offset = form_value.Unsigned();
3756
3757 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3758 if (loc_list_length > 0)
3759 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003760 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
3761 assert (func_low_pc != LLDB_INVALID_ADDRESS);
3762 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003763 }
3764 }
3765 }
3766 break;
3767
3768 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003769 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003770 case DW_AT_const_value:
3771 case DW_AT_declaration:
3772 case DW_AT_description:
3773 case DW_AT_endianity:
3774 case DW_AT_segment:
3775 case DW_AT_start_scope:
3776 case DW_AT_visibility:
3777 default:
3778 case DW_AT_abstract_origin:
3779 case DW_AT_sibling:
3780 case DW_AT_specification:
3781 break;
3782 }
3783 }
3784 }
3785
3786 if (location.IsValid())
3787 {
3788 assert(var_type != DIE_IS_BEING_PARSED);
3789
Greg Claytona134cc12010-09-13 02:37:44 +00003790 ConstString var_name;
3791 if (mangled)
3792 {
3793 Mangled mangled_var_name (mangled, true);
3794 var_name = mangled_var_name.GetDemangledName();
3795 }
3796
3797 if (!var_name && name)
3798 {
3799 var_name.SetCString(name);
3800 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003801
3802 ValueType scope = eValueTypeInvalid;
3803
3804 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3805 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3806
3807 if (tag == DW_TAG_formal_parameter)
3808 scope = eValueTypeVariableArgument;
3809 else if (is_external || parent_tag == DW_TAG_compile_unit)
3810 scope = eValueTypeVariableGlobal;
3811 else
3812 scope = eValueTypeVariableLocal;
3813
3814 SymbolContextScope * symbol_context_scope = NULL;
3815 if (parent_tag == DW_TAG_compile_unit)
3816 {
3817 symbol_context_scope = sc.comp_unit;
3818 }
3819 else if (sc.function != NULL)
3820 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003821 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003822 if (symbol_context_scope == NULL)
3823 symbol_context_scope = sc.function;
3824 }
3825
3826 assert(symbol_context_scope != NULL);
3827 var_sp.reset (new Variable(die->GetOffset(),
3828 var_name,
3829 var_type,
3830 scope,
3831 symbol_context_scope,
3832 &decl,
3833 location,
3834 is_external,
3835 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00003836
3837 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003838 }
3839 }
3840 return var_sp;
3841}
3842
3843size_t
3844SymbolFileDWARF::ParseVariables
3845(
3846 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003847 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00003848 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003849 const DWARFDebugInfoEntry *orig_die,
3850 bool parse_siblings,
3851 bool parse_children,
3852 VariableList* cc_variable_list
3853)
3854{
3855 if (orig_die == NULL)
3856 return 0;
3857
3858 size_t vars_added = 0;
3859 const DWARFDebugInfoEntry *die = orig_die;
3860 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3861 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3862 VariableListSP variables;
3863 switch (parent_tag)
3864 {
3865 case DW_TAG_compile_unit:
3866 if (sc.comp_unit != NULL)
3867 {
3868 variables = sc.comp_unit->GetVariableList(false);
3869 if (variables.get() == NULL)
3870 {
3871 variables.reset(new VariableList());
3872 sc.comp_unit->SetVariableList(variables);
3873 }
3874 }
3875 else
3876 {
3877 assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3878 vars_added = 0;
3879 }
3880 break;
3881
3882 case DW_TAG_subprogram:
3883 case DW_TAG_inlined_subroutine:
3884 case DW_TAG_lexical_block:
3885 if (sc.function != NULL)
3886 {
3887 // Check to see if we already have parsed the variables for the given scope
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003888
3889 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3890 assert (block != NULL);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003891 variables = block->GetVariableList(false, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003892 if (variables.get() == NULL)
3893 {
3894 variables.reset(new VariableList());
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003895 block->SetVariableList(variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003896 }
3897 }
3898 else
3899 {
3900 assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3901 vars_added = 0;
3902 }
3903 break;
3904
3905 default:
3906 assert(!"Didn't find appropriate parent DIE for variable list...");
3907 break;
3908 }
3909
3910 // We need to have a variable list at this point that we can add variables to
3911 assert(variables.get());
3912
3913 while (die != NULL)
3914 {
3915 dw_tag_t tag = die->Tag();
3916
3917 // Check to see if we have already parsed this variable or constant?
Greg Claytonbcf12172010-10-28 00:56:11 +00003918 if (m_die_to_variable_sp[die])
3919 {
3920 if (cc_variable_list)
3921 cc_variable_list->AddVariable (m_die_to_variable_sp[die]);
3922 }
3923 else
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003924 {
3925 // We haven't already parsed it, lets do that now.
3926 if ((tag == DW_TAG_variable) ||
3927 (tag == DW_TAG_constant) ||
3928 (tag == DW_TAG_formal_parameter && sc.function))
3929 {
Greg Clayton016a95e2010-09-14 02:20:48 +00003930 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003931 if (var_sp)
3932 {
3933 variables->AddVariable(var_sp);
Greg Claytonbcf12172010-10-28 00:56:11 +00003934 if (cc_variable_list)
3935 cc_variable_list->AddVariable (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003936 ++vars_added;
3937 }
3938 }
3939 }
3940
3941 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3942
3943 if (!skip_children && parse_children && die->HasChildren())
3944 {
Greg Claytonbcf12172010-10-28 00:56:11 +00003945 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003946 }
3947
3948 if (parse_siblings)
3949 die = die->GetSibling();
3950 else
3951 die = NULL;
3952 }
3953
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003954 return vars_added;
3955}
3956
3957//------------------------------------------------------------------
3958// PluginInterface protocol
3959//------------------------------------------------------------------
3960const char *
3961SymbolFileDWARF::GetPluginName()
3962{
3963 return "SymbolFileDWARF";
3964}
3965
3966const char *
3967SymbolFileDWARF::GetShortPluginName()
3968{
3969 return GetPluginNameStatic();
3970}
3971
3972uint32_t
3973SymbolFileDWARF::GetPluginVersion()
3974{
3975 return 1;
3976}
3977
3978void
3979SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3980{
3981}
3982
3983Error
3984SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3985{
3986 Error error;
3987 error.SetErrorString("No plug-in command are currently supported.");
3988 return error;
3989}
3990
3991Log *
3992SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3993{
3994 return NULL;
3995}
3996