blob: ba45a34c9b99d1edb8d7640fde416ca796a4c72f [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolFileDWARF.h"
11
12// Other libraries and framework includes
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
17#include "clang/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
Greg Clayton7fedea22010-11-16 02:10:54 +000023#include "clang/Sema/DeclSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024
Sean Callanancc427fa2011-07-30 02:42:06 +000025#include "llvm/Support/Casting.h"
26
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/Module.h"
28#include "lldb/Core/PluginManager.h"
29#include "lldb/Core/RegularExpression.h"
30#include "lldb/Core/Scalar.h"
31#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000032#include "lldb/Core/StreamFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Core/Timer.h"
34#include "lldb/Core/Value.h"
35
36#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000037#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Symbol/CompileUnit.h"
39#include "lldb/Symbol/LineTable.h"
40#include "lldb/Symbol/ObjectFile.h"
41#include "lldb/Symbol/SymbolVendor.h"
42#include "lldb/Symbol/VariableList.h"
43
44#include "DWARFCompileUnit.h"
45#include "DWARFDebugAbbrev.h"
46#include "DWARFDebugAranges.h"
47#include "DWARFDebugInfo.h"
48#include "DWARFDebugInfoEntry.h"
49#include "DWARFDebugLine.h"
50#include "DWARFDebugPubnames.h"
51#include "DWARFDebugRanges.h"
52#include "DWARFDIECollection.h"
53#include "DWARFFormValue.h"
54#include "DWARFLocationList.h"
55#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000056#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057
58#include <map>
59
Greg Clayton62742b12010-11-11 01:09:45 +000060//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000061
62#ifdef ENABLE_DEBUG_PRINTF
63#include <stdio.h>
64#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
65#else
66#define DEBUG_PRINTF(fmt, ...)
67#endif
68
Greg Clayton594e5ed2010-09-27 21:07:38 +000069#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070
71using namespace lldb;
72using namespace lldb_private;
73
74
Sean Callananc7fbf732010-08-06 00:32:49 +000075static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000076DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077{
78 switch (dwarf_accessibility)
79 {
Sean Callananc7fbf732010-08-06 00:32:49 +000080 case DW_ACCESS_public: return eAccessPublic;
81 case DW_ACCESS_private: return eAccessPrivate;
82 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000083 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084 }
Sean Callananc7fbf732010-08-06 00:32:49 +000085 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086}
87
88void
89SymbolFileDWARF::Initialize()
90{
91 LogChannelDWARF::Initialize();
92 PluginManager::RegisterPlugin (GetPluginNameStatic(),
93 GetPluginDescriptionStatic(),
94 CreateInstance);
95}
96
97void
98SymbolFileDWARF::Terminate()
99{
100 PluginManager::UnregisterPlugin (CreateInstance);
101 LogChannelDWARF::Initialize();
102}
103
104
105const char *
106SymbolFileDWARF::GetPluginNameStatic()
107{
108 return "symbol-file.dwarf2";
109}
110
111const char *
112SymbolFileDWARF::GetPluginDescriptionStatic()
113{
114 return "DWARF and DWARF3 debug symbol file reader.";
115}
116
117
118SymbolFile*
119SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
120{
121 return new SymbolFileDWARF(obj_file);
122}
123
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000124TypeList *
125SymbolFileDWARF::GetTypeList ()
126{
127 if (m_debug_map_symfile)
128 return m_debug_map_symfile->GetTypeList();
129 return m_obj_file->GetModule()->GetTypeList();
130
131}
132
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133//----------------------------------------------------------------------
134// Gets the first parent that is a lexical block, function or inlined
135// subroutine, or compile unit.
136//----------------------------------------------------------------------
137static const DWARFDebugInfoEntry *
138GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
139{
140 const DWARFDebugInfoEntry *die;
141 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
142 {
143 dw_tag_t tag = die->Tag();
144
145 switch (tag)
146 {
147 case DW_TAG_compile_unit:
148 case DW_TAG_subprogram:
149 case DW_TAG_inlined_subroutine:
150 case DW_TAG_lexical_block:
151 return die;
152 }
153 }
154 return NULL;
155}
156
157
Greg Clayton450e3f32010-10-12 02:24:53 +0000158SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
159 SymbolFile (objfile),
160 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000161 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 m_flags(),
163 m_data_debug_abbrev(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164 m_data_debug_frame(),
165 m_data_debug_info(),
166 m_data_debug_line(),
167 m_data_debug_loc(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168 m_data_debug_ranges(),
169 m_data_debug_str(),
170 m_abbr(),
171 m_aranges(),
172 m_info(),
173 m_line(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000174 m_function_basename_index(),
175 m_function_fullname_index(),
176 m_function_method_index(),
177 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000178 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000179 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000180 m_type_index(),
181 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000182 m_indexed (false),
183 m_is_external_ast_source (false),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000184 m_ranges(),
185 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186{
187}
188
189SymbolFileDWARF::~SymbolFileDWARF()
190{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000191 if (m_is_external_ast_source)
192 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
193}
194
195static const ConstString &
196GetDWARFMachOSegmentName ()
197{
198 static ConstString g_dwarf_section_name ("__DWARF");
199 return g_dwarf_section_name;
200}
201
Greg Claytone576ab22011-02-15 00:19:15 +0000202UniqueDWARFASTTypeMap &
203SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
204{
205 if (m_debug_map_symfile)
206 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
207 return m_unique_ast_type_map;
208}
209
Greg Clayton6beaaa62011-01-17 03:46:26 +0000210ClangASTContext &
211SymbolFileDWARF::GetClangASTContext ()
212{
213 if (m_debug_map_symfile)
214 return m_debug_map_symfile->GetClangASTContext ();
215
216 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
217 if (!m_is_external_ast_source)
218 {
219 m_is_external_ast_source = true;
220 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
221 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
222 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000223 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000224 this));
225
226 ast.SetExternalSource (ast_source_ap);
227 }
228 return ast;
229}
230
231void
232SymbolFileDWARF::InitializeObject()
233{
234 // Install our external AST source callbacks so we can complete Clang types.
235 Module *module = m_obj_file->GetModule();
236 if (module)
237 {
238 const SectionList *section_list = m_obj_file->GetSectionList();
239
240 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
241
242 // Memory map the DWARF mach-o segment so we have everything mmap'ed
243 // to keep our heap memory usage down.
244 if (section)
245 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
246 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247}
248
249bool
250SymbolFileDWARF::SupportedVersion(uint16_t version)
251{
252 return version == 2 || version == 3;
253}
254
255uint32_t
256SymbolFileDWARF::GetAbilities ()
257{
258 uint32_t abilities = 0;
259 if (m_obj_file != NULL)
260 {
261 const Section* section = NULL;
262 const SectionList *section_list = m_obj_file->GetSectionList();
263 if (section_list == NULL)
264 return 0;
265
266 uint64_t debug_abbrev_file_size = 0;
267 uint64_t debug_aranges_file_size = 0;
268 uint64_t debug_frame_file_size = 0;
269 uint64_t debug_info_file_size = 0;
270 uint64_t debug_line_file_size = 0;
271 uint64_t debug_loc_file_size = 0;
272 uint64_t debug_macinfo_file_size = 0;
273 uint64_t debug_pubnames_file_size = 0;
274 uint64_t debug_pubtypes_file_size = 0;
275 uint64_t debug_ranges_file_size = 0;
276 uint64_t debug_str_file_size = 0;
277
Greg Clayton6beaaa62011-01-17 03:46:26 +0000278 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279
280 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000281 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282
Greg Clayton4ceb9982010-07-21 22:54:26 +0000283 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284 if (section != NULL)
285 {
286 debug_info_file_size = section->GetByteSize();
287
Greg Clayton4ceb9982010-07-21 22:54:26 +0000288 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289 if (section)
290 debug_abbrev_file_size = section->GetByteSize();
291 else
292 m_flags.Set (flagsGotDebugAbbrevData);
293
Greg Clayton4ceb9982010-07-21 22:54:26 +0000294 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295 if (section)
296 debug_aranges_file_size = section->GetByteSize();
297 else
298 m_flags.Set (flagsGotDebugArangesData);
299
Greg Clayton4ceb9982010-07-21 22:54:26 +0000300 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 if (section)
302 debug_frame_file_size = section->GetByteSize();
303 else
304 m_flags.Set (flagsGotDebugFrameData);
305
Greg Clayton4ceb9982010-07-21 22:54:26 +0000306 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307 if (section)
308 debug_line_file_size = section->GetByteSize();
309 else
310 m_flags.Set (flagsGotDebugLineData);
311
Greg Clayton4ceb9982010-07-21 22:54:26 +0000312 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 if (section)
314 debug_loc_file_size = section->GetByteSize();
315 else
316 m_flags.Set (flagsGotDebugLocData);
317
Greg Clayton4ceb9982010-07-21 22:54:26 +0000318 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 if (section)
320 debug_macinfo_file_size = section->GetByteSize();
321 else
322 m_flags.Set (flagsGotDebugMacInfoData);
323
Greg Clayton4ceb9982010-07-21 22:54:26 +0000324 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000325 if (section)
326 debug_pubnames_file_size = section->GetByteSize();
327 else
328 m_flags.Set (flagsGotDebugPubNamesData);
329
Greg Clayton4ceb9982010-07-21 22:54:26 +0000330 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331 if (section)
332 debug_pubtypes_file_size = section->GetByteSize();
333 else
334 m_flags.Set (flagsGotDebugPubTypesData);
335
Greg Clayton4ceb9982010-07-21 22:54:26 +0000336 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 if (section)
338 debug_ranges_file_size = section->GetByteSize();
339 else
340 m_flags.Set (flagsGotDebugRangesData);
341
Greg Clayton4ceb9982010-07-21 22:54:26 +0000342 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343 if (section)
344 debug_str_file_size = section->GetByteSize();
345 else
346 m_flags.Set (flagsGotDebugStrData);
347 }
348
349 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
350 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
351
352 if (debug_line_file_size > 0)
353 abilities |= LineTables;
354
355 if (debug_aranges_file_size > 0)
356 abilities |= AddressAcceleratorTable;
357
358 if (debug_pubnames_file_size > 0)
359 abilities |= FunctionAcceleratorTable;
360
361 if (debug_pubtypes_file_size > 0)
362 abilities |= TypeAcceleratorTable;
363
364 if (debug_macinfo_file_size > 0)
365 abilities |= MacroInformation;
366
367 if (debug_frame_file_size > 0)
368 abilities |= CallFrameInformation;
369 }
370 return abilities;
371}
372
373const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000374SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375{
376 if (m_flags.IsClear (got_flag))
377 {
378 m_flags.Set (got_flag);
379 const SectionList *section_list = m_obj_file->GetSectionList();
380 if (section_list)
381 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000382 Section *section = section_list->FindSectionByType(sect_type, true).get();
383 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 {
385 // See if we memory mapped the DWARF segment?
386 if (m_dwarf_data.GetByteSize())
387 {
388 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
389 }
390 else
391 {
392 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
393 data.Clear();
394 }
395 }
396 }
397 }
398 return data;
399}
400
401const DataExtractor&
402SymbolFileDWARF::get_debug_abbrev_data()
403{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000404 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405}
406
407const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000408SymbolFileDWARF::get_debug_frame_data()
409{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000410 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411}
412
413const DataExtractor&
414SymbolFileDWARF::get_debug_info_data()
415{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000416 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417}
418
419const DataExtractor&
420SymbolFileDWARF::get_debug_line_data()
421{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000422 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423}
424
425const DataExtractor&
426SymbolFileDWARF::get_debug_loc_data()
427{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000428 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429}
430
431const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432SymbolFileDWARF::get_debug_ranges_data()
433{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000434 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435}
436
437const DataExtractor&
438SymbolFileDWARF::get_debug_str_data()
439{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000440 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441}
442
443
444DWARFDebugAbbrev*
445SymbolFileDWARF::DebugAbbrev()
446{
447 if (m_abbr.get() == NULL)
448 {
449 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
450 if (debug_abbrev_data.GetByteSize() > 0)
451 {
452 m_abbr.reset(new DWARFDebugAbbrev());
453 if (m_abbr.get())
454 m_abbr->Parse(debug_abbrev_data);
455 }
456 }
457 return m_abbr.get();
458}
459
460const DWARFDebugAbbrev*
461SymbolFileDWARF::DebugAbbrev() const
462{
463 return m_abbr.get();
464}
465
466DWARFDebugAranges*
467SymbolFileDWARF::DebugAranges()
468{
Greg Clayton016a95e2010-09-14 02:20:48 +0000469 // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
470 // and we are already parsing all of the DWARF because the .debug_pubnames
471 // is useless (it only mentions symbols that are externally visible), so
472 // don't use the .debug_aranges section, we should be using a debug aranges
473 // we got from SymbolFileDWARF::Index().
474
475 if (!m_indexed)
476 Index();
477
478
479// if (m_aranges.get() == NULL)
480// {
481// Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
482// m_aranges.reset(new DWARFDebugAranges());
483// if (m_aranges.get())
484// {
485// const DataExtractor &debug_aranges_data = get_debug_aranges_data();
486// if (debug_aranges_data.GetByteSize() > 0)
487// m_aranges->Extract(debug_aranges_data);
488// else
489// m_aranges->Generate(this);
490// }
491// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492 return m_aranges.get();
493}
494
495const DWARFDebugAranges*
496SymbolFileDWARF::DebugAranges() const
497{
498 return m_aranges.get();
499}
500
501
502DWARFDebugInfo*
503SymbolFileDWARF::DebugInfo()
504{
505 if (m_info.get() == NULL)
506 {
507 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
508 if (get_debug_info_data().GetByteSize() > 0)
509 {
510 m_info.reset(new DWARFDebugInfo());
511 if (m_info.get())
512 {
513 m_info->SetDwarfData(this);
514 }
515 }
516 }
517 return m_info.get();
518}
519
520const DWARFDebugInfo*
521SymbolFileDWARF::DebugInfo() const
522{
523 return m_info.get();
524}
525
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526DWARFCompileUnit*
527SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
528{
529 DWARFDebugInfo* info = DebugInfo();
530 if (info)
531 return info->GetCompileUnit(cu_uid).get();
532 return NULL;
533}
534
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000535
536DWARFDebugRanges*
537SymbolFileDWARF::DebugRanges()
538{
539 if (m_ranges.get() == NULL)
540 {
541 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
542 if (get_debug_ranges_data().GetByteSize() > 0)
543 {
544 m_ranges.reset(new DWARFDebugRanges());
545 if (m_ranges.get())
546 m_ranges->Extract(this);
547 }
548 }
549 return m_ranges.get();
550}
551
552const DWARFDebugRanges*
553SymbolFileDWARF::DebugRanges() const
554{
555 return m_ranges.get();
556}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557
558bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000559SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000560{
Greg Clayton96d7d742010-11-10 23:42:09 +0000561 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000563 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 if (cu_die)
565 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000566 const char * cu_die_name = cu_die->GetName(this, curr_cu);
567 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
568 LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000569 if (cu_die_name)
570 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000571 FileSpec cu_file_spec;
572
Greg Clayton7bd65b92011-02-09 23:39:34 +0000573 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000575 // If we have a full path to the compile unit, we don't need to resolve
576 // the file. This can be expensive e.g. when the source files are NFS mounted.
577 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578 }
579 else
580 {
581 std::string fullpath(cu_comp_dir);
582 if (*fullpath.rbegin() != '/')
583 fullpath += '/';
584 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000585 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000586 }
587
Greg Clayton96d7d742010-11-10 23:42:09 +0000588 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 +0000589 if (compile_unit_sp.get())
590 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000591 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000592 return true;
593 }
594 }
595 }
596 }
597 return false;
598}
599
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000600uint32_t
601SymbolFileDWARF::GetNumCompileUnits()
602{
603 DWARFDebugInfo* info = DebugInfo();
604 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606 return 0;
607}
608
609CompUnitSP
610SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
611{
612 CompUnitSP comp_unit;
613 DWARFDebugInfo* info = DebugInfo();
614 if (info)
615 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000616 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
617 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 {
619 // Our symbol vendor shouldn't be asking us to add a compile unit that
620 // has already been added to it, which this DWARF plug-in knows as it
621 // stores the lldb compile unit (CompileUnit) pointer in each
622 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000623 assert(curr_cu->GetUserData() == NULL);
624 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625 }
626 }
627 return comp_unit;
628}
629
630static void
631AddRangesToBlock
632(
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000633 Block& block,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634 DWARFDebugRanges::RangeList& ranges,
635 addr_t block_base_addr
636)
637{
638 ranges.SubtractOffset (block_base_addr);
639 size_t range_idx = 0;
640 const DWARFDebugRanges::Range *debug_range;
641 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
642 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000643 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644 }
645}
646
647
648Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000649SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000650{
651 DWARFDebugRanges::RangeList func_ranges;
652 const char *name = NULL;
653 const char *mangled = NULL;
654 int decl_file = 0;
655 int decl_line = 0;
656 int decl_column = 0;
657 int call_file = 0;
658 int call_line = 0;
659 int call_column = 0;
660 DWARFExpression frame_base;
661
Greg Claytonc93237c2010-10-01 20:48:32 +0000662 assert (die->Tag() == DW_TAG_subprogram);
663
664 if (die->Tag() != DW_TAG_subprogram)
665 return NULL;
666
Greg Clayton5113dc82011-08-12 06:47:54 +0000667 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die);
668 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
Greg Claytonc93237c2010-10-01 20:48:32 +0000669
Greg Clayton5113dc82011-08-12 06:47:54 +0000670 switch (containing_decl_kind)
671 {
672 case clang::Decl::Record:
673 case clang::Decl::CXXRecord:
674 case clang::Decl::ObjCClass:
675 case clang::Decl::ObjCImplementation:
676 case clang::Decl::ObjCInterface:
677 // We have methods of a class or struct
678 {
679 const DWARFDebugInfoEntry *containing_decl_die = m_decl_ctx_to_die[containing_decl_ctx];
680 assert (containing_decl_die);
681 Type *class_type = ResolveType (dwarf_cu, containing_decl_die);
682 if (class_type)
683 class_type->GetClangFullType();
684 // Make sure the class definition contains the funciton DIE
685 // we wanted to parse. If it does, we are done. Else, we need
686 // to fall through and parse the function DIE stil...
687 if (containing_decl_die->Contains (die))
688 break; // DIE has been parsed, we are done
689 }
690 // Fall through...
691
692 default:
693 // Parse the function prototype as a type that can then be added to concrete function instance
694 ParseTypes (sc, dwarf_cu, die, false, false);
695 break;
Greg Claytonc93237c2010-10-01 20:48:32 +0000696 }
697
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698 //FixupTypes();
699
700 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
701 {
702 // Union of all ranges in the function DIE (if the function is discontiguous)
703 AddressRange func_range;
704 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
705 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
706 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
707 {
708 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
709 if (func_range.GetBaseAddress().IsValid())
710 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
711 }
712
713 if (func_range.GetBaseAddress().IsValid())
714 {
715 Mangled func_name;
716 if (mangled)
717 func_name.SetValue(mangled, true);
718 else if (name)
719 func_name.SetValue(name, false);
720
721 FunctionSP func_sp;
722 std::auto_ptr<Declaration> decl_ap;
723 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000724 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
725 decl_line,
726 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727
Greg Clayton594e5ed2010-09-27 21:07:38 +0000728 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000729
730 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
731
732 func_range.GetBaseAddress().ResolveLinkedAddress();
733
734 func_sp.reset(new Function (sc.comp_unit,
735 die->GetOffset(), // UserID is the DIE offset
736 die->GetOffset(),
737 func_name,
738 func_type,
739 func_range)); // first address range
740
741 if (func_sp.get() != NULL)
742 {
743 func_sp->GetFrameBaseExpression() = frame_base;
744 sc.comp_unit->AddFunction(func_sp);
745 return func_sp.get();
746 }
747 }
748 }
749 return NULL;
750}
751
752size_t
753SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
754{
755 assert (sc.comp_unit);
756 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000757 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000758 if (dwarf_cu)
759 {
760 DWARFDIECollection function_dies;
761 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
762 size_t func_idx;
763 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
764 {
765 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
766 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
767 {
768 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
769 ++functions_added;
770 }
771 }
772 //FixupTypes();
773 }
774 return functions_added;
775}
776
777bool
778SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
779{
780 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000781 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
782 assert (curr_cu);
783 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000784
785 if (cu_die)
786 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000787 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
788 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 +0000789
790 // All file indexes in DWARF are one based and a file of index zero is
791 // supposed to be the compile unit itself.
792 support_files.Append (*sc.comp_unit);
793
794 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
795 }
796 return false;
797}
798
799struct ParseDWARFLineTableCallbackInfo
800{
801 LineTable* line_table;
802 const SectionList *section_list;
803 lldb::addr_t prev_sect_file_base_addr;
804 lldb::addr_t curr_sect_file_base_addr;
805 bool is_oso_for_debug_map;
806 bool prev_in_final_executable;
807 DWARFDebugLine::Row prev_row;
808 SectionSP prev_section_sp;
809 SectionSP curr_section_sp;
810};
811
812//----------------------------------------------------------------------
813// ParseStatementTableCallback
814//----------------------------------------------------------------------
815static void
816ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
817{
818 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
819 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
820 {
821 // Just started parsing the line table
822 }
823 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
824 {
825 // Done parsing line table, nothing to do for the cleanup
826 }
827 else
828 {
829 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
830 // We have a new row, lets append it
831
832 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
833 {
834 info->prev_section_sp = info->curr_section_sp;
835 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
836 // If this is an end sequence entry, then we subtract one from the
837 // address to make sure we get an address that is not the end of
838 // a section.
839 if (state.end_sequence && state.address != 0)
840 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
841 else
842 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
843
844 if (info->curr_section_sp.get())
845 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
846 else
847 info->curr_sect_file_base_addr = 0;
848 }
849 if (info->curr_section_sp.get())
850 {
851 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
852 // Check for the fancy section magic to determine if we
853
854 if (info->is_oso_for_debug_map)
855 {
856 // When this is a debug map object file that contains DWARF
857 // (referenced from an N_OSO debug map nlist entry) we will have
858 // a file address in the file range for our section from the
859 // original .o file, and a load address in the executable that
860 // contains the debug map.
861 //
862 // If the sections for the file range and load range are
863 // different, we have a remapped section for the function and
864 // this address is resolved. If they are the same, then the
865 // function for this address didn't make it into the final
866 // executable.
867 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
868
869 // If we are doing DWARF with debug map, then we need to carefully
870 // add each line table entry as there may be gaps as functions
871 // get moved around or removed.
872 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
873 {
874 if (info->prev_in_final_executable)
875 {
876 bool terminate_previous_entry = false;
877 if (!curr_in_final_executable)
878 {
879 // Check for the case where the previous line entry
880 // in a function made it into the final executable,
881 // yet the current line entry falls in a function
882 // that didn't. The line table used to be contiguous
883 // through this address range but now it isn't. We
884 // need to terminate the previous line entry so
885 // that we can reconstruct the line range correctly
886 // for it and to keep the line table correct.
887 terminate_previous_entry = true;
888 }
889 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
890 {
891 // Check for cases where the line entries used to be
892 // contiguous address ranges, but now they aren't.
893 // This can happen when order files specify the
894 // ordering of the functions.
895 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
896 Section *curr_sect = info->curr_section_sp.get();
897 Section *prev_sect = info->prev_section_sp.get();
898 assert (curr_sect->GetLinkedSection());
899 assert (prev_sect->GetLinkedSection());
900 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
901 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
902 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
903 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
904 if (object_file_addr_delta != linked_file_addr_delta)
905 terminate_previous_entry = true;
906 }
907
908 if (terminate_previous_entry)
909 {
910 line_table->InsertLineEntry (info->prev_section_sp,
911 state.address - info->prev_sect_file_base_addr,
912 info->prev_row.line,
913 info->prev_row.column,
914 info->prev_row.file,
915 false, // is_stmt
916 false, // basic_block
917 false, // state.prologue_end
918 false, // state.epilogue_begin
919 true); // end_sequence);
920 }
921 }
922 }
923
924 if (curr_in_final_executable)
925 {
926 line_table->InsertLineEntry (info->curr_section_sp,
927 curr_line_section_offset,
928 state.line,
929 state.column,
930 state.file,
931 state.is_stmt,
932 state.basic_block,
933 state.prologue_end,
934 state.epilogue_begin,
935 state.end_sequence);
936 info->prev_section_sp = info->curr_section_sp;
937 }
938 else
939 {
940 // If the current address didn't make it into the final
941 // executable, the current section will be the __text
942 // segment in the .o file, so we need to clear this so
943 // we can catch the next function that did make it into
944 // the final executable.
945 info->prev_section_sp.reset();
946 info->curr_section_sp.reset();
947 }
948
949 info->prev_in_final_executable = curr_in_final_executable;
950 }
951 else
952 {
953 // We are not in an object file that contains DWARF for an
954 // N_OSO, this is just a normal DWARF file. The DWARF spec
955 // guarantees that the addresses will be in increasing order
956 // so, since we store line tables in file address order, we
957 // can always just append the line entry without needing to
958 // search for the correct insertion point (we don't need to
959 // use LineEntry::InsertLineEntry()).
960 line_table->AppendLineEntry (info->curr_section_sp,
961 curr_line_section_offset,
962 state.line,
963 state.column,
964 state.file,
965 state.is_stmt,
966 state.basic_block,
967 state.prologue_end,
968 state.epilogue_begin,
969 state.end_sequence);
970 }
971 }
972
973 info->prev_row = state;
974 }
975}
976
977bool
978SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
979{
980 assert (sc.comp_unit);
981 if (sc.comp_unit->GetLineTable() != NULL)
982 return true;
983
984 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
985 if (dwarf_cu)
986 {
987 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
988 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
989 if (cu_line_offset != DW_INVALID_OFFSET)
990 {
991 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
992 if (line_table_ap.get())
993 {
Greg Clayton450e3f32010-10-12 02:24:53 +0000994 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 +0000995 uint32_t offset = cu_line_offset;
996 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
997 sc.comp_unit->SetLineTable(line_table_ap.release());
998 return true;
999 }
1000 }
1001 }
1002 return false;
1003}
1004
1005size_t
1006SymbolFileDWARF::ParseFunctionBlocks
1007(
1008 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001009 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +00001010 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001011 const DWARFDebugInfoEntry *die,
1012 addr_t subprogram_low_pc,
1013 bool parse_siblings,
1014 bool parse_children
1015)
1016{
1017 size_t blocks_added = 0;
1018 while (die != NULL)
1019 {
1020 dw_tag_t tag = die->Tag();
1021
1022 switch (tag)
1023 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001024 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001025 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001026 case DW_TAG_lexical_block:
1027 {
1028 DWARFDebugRanges::RangeList ranges;
1029 const char *name = NULL;
1030 const char *mangled_name = NULL;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001031 Block *block = NULL;
1032 if (tag != DW_TAG_subprogram)
1033 {
1034 BlockSP block_sp(new Block (die->GetOffset()));
1035 parent_block->AddChild(block_sp);
1036 block = block_sp.get();
1037 }
1038 else
1039 {
1040 block = parent_block;
1041 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001043 int decl_file = 0;
1044 int decl_line = 0;
1045 int decl_column = 0;
1046 int call_file = 0;
1047 int call_line = 0;
1048 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001049 if (die->GetDIENamesAndRanges (this,
1050 dwarf_cu,
1051 name,
1052 mangled_name,
1053 ranges,
1054 decl_file, decl_line, decl_column,
1055 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001056 {
1057 if (tag == DW_TAG_subprogram)
1058 {
1059 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1060 subprogram_low_pc = ranges.LowestAddress(0);
1061 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001062 else if (tag == DW_TAG_inlined_subroutine)
1063 {
1064 // We get called here for inlined subroutines in two ways.
1065 // The first time is when we are making the Function object
1066 // for this inlined concrete instance. Since we're creating a top level block at
1067 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1068 // adjust the containing address.
1069 // The second time is when we are parsing the blocks inside the function that contains
1070 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1071 // function the offset will be for that function.
1072 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1073 {
1074 subprogram_low_pc = ranges.LowestAddress(0);
1075 }
1076 }
1077
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001078 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079
1080 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1081 {
1082 std::auto_ptr<Declaration> decl_ap;
1083 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001084 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1085 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001086
1087 std::auto_ptr<Declaration> call_ap;
1088 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001089 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1090 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001091
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001092 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001093 }
1094
1095 ++blocks_added;
1096
1097 if (parse_children && die->HasChildren())
1098 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001099 blocks_added += ParseFunctionBlocks (sc,
1100 block,
1101 dwarf_cu,
1102 die->GetFirstChild(),
1103 subprogram_low_pc,
1104 true,
1105 true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106 }
1107 }
1108 }
1109 break;
1110 default:
1111 break;
1112 }
1113
1114 if (parse_siblings)
1115 die = die->GetSibling();
1116 else
1117 die = NULL;
1118 }
1119 return blocks_added;
1120}
1121
1122size_t
1123SymbolFileDWARF::ParseChildMembers
1124(
1125 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001126 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001127 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001128 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001129 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001130 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1131 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001132 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001133 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001134 bool &is_a_class
1135)
1136{
1137 if (parent_die == NULL)
1138 return 0;
1139
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001140 size_t count = 0;
1141 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001142 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001143 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001144
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1146 {
1147 dw_tag_t tag = die->Tag();
1148
1149 switch (tag)
1150 {
1151 case DW_TAG_member:
1152 {
1153 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001154 const size_t num_attributes = die->GetAttributes (this,
1155 dwarf_cu,
1156 fixed_form_sizes,
1157 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001158 if (num_attributes > 0)
1159 {
1160 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001161 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001163 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001164 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001165 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001166 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167 size_t byte_size = 0;
1168 size_t bit_offset = 0;
1169 size_t bit_size = 0;
1170 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001171 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001172 {
1173 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1174 DWARFFormValue form_value;
1175 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1176 {
1177 switch (attr)
1178 {
1179 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1180 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1181 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1182 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1183 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1184 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1185 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1186 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1187 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001188// if (form_value.BlockData())
1189// {
1190// Value initialValue(0);
1191// Value memberOffset(0);
1192// const DataExtractor& debug_info_data = get_debug_info_data();
1193// uint32_t block_length = form_value.Unsigned();
1194// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1195// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1196// {
1197// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1198// }
1199// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200 break;
1201
Greg Clayton8cf05932010-07-22 18:30:50 +00001202 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001203 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001204 case DW_AT_declaration:
1205 case DW_AT_description:
1206 case DW_AT_mutable:
1207 case DW_AT_visibility:
1208 default:
1209 case DW_AT_sibling:
1210 break;
1211 }
1212 }
1213 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001214
1215 // FIXME: Make Clang ignore Objective-C accessibility for expressions
1216
1217 if (class_language == eLanguageTypeObjC ||
1218 class_language == eLanguageTypeObjC_plus_plus)
1219 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001220
1221 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1222 {
1223 // Not all compilers will mark the vtable pointer
1224 // member as artificial (llvm-gcc). We can't have
1225 // the virtual members in our classes otherwise it
1226 // throws off all child offsets since we end up
1227 // having and extra pointer sized member in our
1228 // class layouts.
1229 is_artificial = true;
1230 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001231
Greg Clayton24739922010-10-13 03:15:28 +00001232 if (is_artificial == false)
1233 {
1234 Type *member_type = ResolveTypeUID(encoding_uid);
Greg Claytond16e1e52011-07-12 17:06:17 +00001235 if (member_type)
1236 {
1237 if (accessibility == eAccessNone)
1238 accessibility = default_accessibility;
1239 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001240
Greg Claytond16e1e52011-07-12 17:06:17 +00001241 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1242 name,
1243 member_type->GetClangLayoutType(),
1244 accessibility,
1245 bit_size);
1246 }
1247 else
1248 {
1249 if (name)
1250 ReportError ("0x%8.8x: DW_TAG_member '%s' refers to type 0x%8.8x which was unable to be parsed",
1251 die->GetOffset(),
1252 name,
1253 encoding_uid);
1254 else
1255 ReportError ("0x%8.8x: DW_TAG_member refers to type 0x%8.8x which was unable to be parsed",
1256 die->GetOffset(),
1257 encoding_uid);
1258 }
Greg Clayton24739922010-10-13 03:15:28 +00001259 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001260 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001261 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 }
1263 break;
1264
1265 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001266 // Let the type parsing code handle this one for us.
1267 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001268 break;
1269
1270 case DW_TAG_inheritance:
1271 {
1272 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001273 if (default_accessibility == eAccessNone)
1274 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001275 // TODO: implement DW_TAG_inheritance type parsing
1276 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001277 const size_t num_attributes = die->GetAttributes (this,
1278 dwarf_cu,
1279 fixed_form_sizes,
1280 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281 if (num_attributes > 0)
1282 {
1283 Declaration decl;
1284 DWARFExpression location;
1285 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001286 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001287 bool is_virtual = false;
1288 bool is_base_of_class = true;
1289 off_t member_offset = 0;
1290 uint32_t i;
1291 for (i=0; i<num_attributes; ++i)
1292 {
1293 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1294 DWARFFormValue form_value;
1295 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1296 {
1297 switch (attr)
1298 {
1299 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1300 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1301 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1302 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1303 case DW_AT_data_member_location:
1304 if (form_value.BlockData())
1305 {
1306 Value initialValue(0);
1307 Value memberOffset(0);
1308 const DataExtractor& debug_info_data = get_debug_info_data();
1309 uint32_t block_length = form_value.Unsigned();
1310 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001311 if (DWARFExpression::Evaluate (NULL,
1312 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001313 NULL,
1314 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001315 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001316 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001317 block_offset,
1318 block_length,
1319 eRegisterKindDWARF,
1320 &initialValue,
1321 memberOffset,
1322 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001323 {
1324 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1325 }
1326 }
1327 break;
1328
1329 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001330 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001331 break;
1332
1333 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1334 default:
1335 case DW_AT_sibling:
1336 break;
1337 }
1338 }
1339 }
1340
Greg Clayton526e5af2010-11-13 03:52:47 +00001341 Type *base_class_type = ResolveTypeUID(encoding_uid);
1342 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001343
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001344 clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1345 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001346 if (class_language == eLanguageTypeObjC)
1347 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001348 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001349 }
1350 else
1351 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001352 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001353 accessibility,
1354 is_virtual,
1355 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001356 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001357 }
1358 }
1359 break;
1360
1361 default:
1362 break;
1363 }
1364 }
1365 return count;
1366}
1367
1368
1369clang::DeclContext*
Sean Callanan72e49402011-08-05 23:43:37 +00001370SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001371{
1372 DWARFDebugInfo* debug_info = DebugInfo();
1373 if (debug_info)
1374 {
1375 DWARFCompileUnitSP cu_sp;
1376 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1377 if (die)
Sean Callanan72e49402011-08-05 23:43:37 +00001378 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
1379 }
1380 return NULL;
1381}
1382
1383clang::DeclContext*
1384SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1385{
1386 DWARFDebugInfo* debug_info = DebugInfo();
1387 if (debug_info)
1388 {
1389 DWARFCompileUnitSP cu_sp;
1390 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1391 if (die)
1392 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001393 }
1394 return NULL;
1395}
1396
1397Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001398SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001399{
1400 DWARFDebugInfo* debug_info = DebugInfo();
1401 if (debug_info)
1402 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00001403 DWARFCompileUnitSP cu_sp;
1404 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001405 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001406 {
1407 // We might be coming in in the middle of a type tree (a class
1408 // withing a class, an enum within a class), so parse any needed
1409 // parent DIEs before we get to this one...
1410 const DWARFDebugInfoEntry* parent_die = type_die->GetParent();
1411 switch (parent_die->Tag())
1412 {
1413 case DW_TAG_structure_type:
1414 case DW_TAG_union_type:
1415 case DW_TAG_class_type:
1416 ResolveType(cu_sp.get(), parent_die);
1417 break;
1418 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00001419 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001420 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001421 }
1422 return NULL;
1423}
1424
Greg Clayton6beaaa62011-01-17 03:46:26 +00001425// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1426// SymbolFileDWARF objects to detect if this DWARF file is the one that
1427// can resolve a clang_type.
1428bool
1429SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1430{
1431 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1432 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1433 return die != NULL;
1434}
1435
1436
Greg Clayton1be10fc2010-09-29 01:12:09 +00001437lldb::clang_type_t
1438SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1439{
1440 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001441 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1442 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001443 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001444 {
Greg Clayton6beaaa62011-01-17 03:46:26 +00001445// if (m_debug_map_symfile)
1446// {
1447// Type *type = m_die_to_type[die];
1448// if (type && type->GetSymbolFile() != this)
1449// return type->GetClangType();
1450// }
Greg Clayton73b472d2010-10-27 03:32:59 +00001451 // We have already resolved this type...
1452 return clang_type;
1453 }
1454 // Once we start resolving this type, remove it from the forward declaration
1455 // map in case anyone child members or other types require this type to get resolved.
1456 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1457 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001458 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001459
Greg Clayton1be10fc2010-09-29 01:12:09 +00001460
Greg Clayton450e3f32010-10-12 02:24:53 +00001461 DWARFDebugInfo* debug_info = DebugInfo();
1462
Greg Clayton96d7d742010-11-10 23:42:09 +00001463 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001464 Type *type = m_die_to_type.lookup (die);
1465
1466 const dw_tag_t tag = die->Tag();
1467
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001468 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1469 die->GetOffset(),
1470 DW_TAG_value_to_name(tag),
1471 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001472 assert (clang_type);
1473 DWARFDebugInfoEntry::Attributes attributes;
1474
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001475 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001476
1477 switch (tag)
1478 {
1479 case DW_TAG_structure_type:
1480 case DW_TAG_union_type:
1481 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001482 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001483 if (die->HasChildren())
1484 {
1485 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001486 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1487 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001488 class_language = eLanguageTypeObjC;
1489
1490 int tag_decl_kind = -1;
1491 AccessType default_accessibility = eAccessNone;
1492 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001493 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001494 tag_decl_kind = clang::TTK_Struct;
1495 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001496 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001497 else if (tag == DW_TAG_union_type)
1498 {
1499 tag_decl_kind = clang::TTK_Union;
1500 default_accessibility = eAccessPublic;
1501 }
1502 else if (tag == DW_TAG_class_type)
1503 {
1504 tag_decl_kind = clang::TTK_Class;
1505 default_accessibility = eAccessPrivate;
1506 }
1507
Greg Clayton96d7d742010-11-10 23:42:09 +00001508 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001509 std::vector<clang::CXXBaseSpecifier *> base_classes;
1510 std::vector<int> member_accessibilities;
1511 bool is_a_class = false;
1512 // Parse members and base classes first
1513 DWARFDIECollection member_function_dies;
1514
1515 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001516 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001517 die,
1518 clang_type,
1519 class_language,
1520 base_classes,
1521 member_accessibilities,
1522 member_function_dies,
1523 default_accessibility,
1524 is_a_class);
1525
1526 // Now parse any methods if there were any...
1527 size_t num_functions = member_function_dies.Size();
1528 if (num_functions > 0)
1529 {
1530 for (size_t i=0; i<num_functions; ++i)
1531 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001532 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001533 }
1534 }
1535
Greg Clayton450e3f32010-10-12 02:24:53 +00001536 if (class_language == eLanguageTypeObjC)
1537 {
Greg Claytone3055942011-06-30 02:28:26 +00001538 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
Greg Clayton450e3f32010-10-12 02:24:53 +00001539 if (!class_str.empty())
1540 {
1541
1542 ConstString class_name (class_str.c_str());
1543 std::vector<NameToDIE::Info> method_die_infos;
1544 if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1545 {
1546 DWARFCompileUnit* method_cu = NULL;
1547 DWARFCompileUnit* prev_method_cu = NULL;
1548 const size_t num_objc_methods = method_die_infos.size();
1549 for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1550 {
1551 method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1552
1553 if (method_cu != prev_method_cu)
1554 method_cu->ExtractDIEsIfNeeded (false);
1555
1556 DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1557
1558 ResolveType (method_cu, method_die);
1559 }
1560 }
1561 }
1562 }
1563
Greg Claytonc93237c2010-10-01 20:48:32 +00001564 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1565 // need to tell the clang type it is actually a class.
1566 if (class_language != eLanguageTypeObjC)
1567 {
1568 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001569 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001570 }
1571
1572 // Since DW_TAG_structure_type gets used for both classes
1573 // and structures, we may need to set any DW_TAG_member
1574 // fields to have a "private" access if none was specified.
1575 // When we parsed the child members we tracked that actual
1576 // accessibility value for each DW_TAG_member in the
1577 // "member_accessibilities" array. If the value for the
1578 // member is zero, then it was set to the "default_accessibility"
1579 // which for structs was "public". Below we correct this
1580 // by setting any fields to "private" that weren't correctly
1581 // set.
1582 if (is_a_class && !member_accessibilities.empty())
1583 {
1584 // This is a class and all members that didn't have
1585 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001586 ast.SetDefaultAccessForRecordFields (clang_type,
1587 eAccessPrivate,
1588 &member_accessibilities.front(),
1589 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001590 }
1591
1592 if (!base_classes.empty())
1593 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001594 ast.SetBaseClassesForClassType (clang_type,
1595 &base_classes.front(),
1596 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001597
1598 // Clang will copy each CXXBaseSpecifier in "base_classes"
1599 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001600 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1601 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001602 }
1603
1604 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001605 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001606 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001607
1608 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001609 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001610 if (die->HasChildren())
1611 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001612 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1613 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001614 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001615 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001616 return clang_type;
1617
1618 default:
1619 assert(false && "not a forward clang type decl!");
1620 break;
1621 }
1622 return NULL;
1623}
1624
Greg Claytonc685f8e2010-09-15 04:15:46 +00001625Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001626SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001627{
1628 if (type_die != NULL)
1629 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001630 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001631 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001632 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001633 if (assert_not_being_parsed)
1634 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001635 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001636 }
1637 return NULL;
1638}
1639
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001640CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001641SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001642{
1643 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001644 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001645 {
1646 // The symbol vendor doesn't know about this compile unit, we
1647 // need to parse and add it to the symbol vendor object.
1648 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001649 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001650 if (dc_cu.get())
1651 {
1652 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001653 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001654 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001655
1656 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001657
1658 if (m_debug_map_symfile)
1659 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001660 }
1661 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001662 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001663}
1664
1665bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001666SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001667{
1668 sc.Clear();
1669 // Check if the symbol vendor already knows about this compile unit?
1670 sc.module_sp = m_obj_file->GetModule()->GetSP();
Greg Clayton96d7d742010-11-10 23:42:09 +00001671 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001672
1673 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1674 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001675 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001676
1677 return sc.function != NULL;
1678}
1679
1680uint32_t
1681SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1682{
1683 Timer scoped_timer(__PRETTY_FUNCTION__,
1684 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1685 so_addr.GetSection(),
1686 so_addr.GetOffset(),
1687 resolve_scope);
1688 uint32_t resolved = 0;
1689 if (resolve_scope & ( eSymbolContextCompUnit |
1690 eSymbolContextFunction |
1691 eSymbolContextBlock |
1692 eSymbolContextLineEntry))
1693 {
1694 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1695
1696 DWARFDebugAranges* debug_aranges = DebugAranges();
1697 DWARFDebugInfo* debug_info = DebugInfo();
1698 if (debug_aranges)
1699 {
1700 dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1701 if (cu_offset != DW_INVALID_OFFSET)
1702 {
1703 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001704 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1705 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001706 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001707 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001708 assert(sc.comp_unit != NULL);
1709 resolved |= eSymbolContextCompUnit;
1710
1711 if (resolve_scope & eSymbolContextLineEntry)
1712 {
1713 LineTable *line_table = sc.comp_unit->GetLineTable();
1714 if (line_table == NULL)
1715 {
1716 if (ParseCompileUnitLineTable(sc))
1717 line_table = sc.comp_unit->GetLineTable();
1718 }
1719 if (line_table != NULL)
1720 {
1721 if (so_addr.IsLinkedAddress())
1722 {
1723 Address linked_addr (so_addr);
1724 linked_addr.ResolveLinkedAddress();
1725 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1726 {
1727 resolved |= eSymbolContextLineEntry;
1728 }
1729 }
1730 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1731 {
1732 resolved |= eSymbolContextLineEntry;
1733 }
1734 }
1735 }
1736
1737 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1738 {
1739 DWARFDebugInfoEntry *function_die = NULL;
1740 DWARFDebugInfoEntry *block_die = NULL;
1741 if (resolve_scope & eSymbolContextBlock)
1742 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001743 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001744 }
1745 else
1746 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001747 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001748 }
1749
1750 if (function_die != NULL)
1751 {
1752 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1753 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001754 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001755 }
1756
1757 if (sc.function != NULL)
1758 {
1759 resolved |= eSymbolContextFunction;
1760
1761 if (resolve_scope & eSymbolContextBlock)
1762 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001763 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001764
1765 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001766 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001767 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001768 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001769 if (sc.block)
1770 resolved |= eSymbolContextBlock;
1771 }
1772 }
1773 }
1774 }
1775 }
1776 }
1777 }
1778 return resolved;
1779}
1780
1781
1782
1783uint32_t
1784SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1785{
1786 const uint32_t prev_size = sc_list.GetSize();
1787 if (resolve_scope & eSymbolContextCompUnit)
1788 {
1789 DWARFDebugInfo* debug_info = DebugInfo();
1790 if (debug_info)
1791 {
1792 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001793 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001794
Greg Clayton96d7d742010-11-10 23:42:09 +00001795 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001796 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001797 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001798 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1799 if (check_inlines || file_spec_matches_cu_file_spec)
1800 {
1801 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001802 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001803 assert(sc.comp_unit != NULL);
1804
1805 uint32_t file_idx = UINT32_MAX;
1806
1807 // If we are looking for inline functions only and we don't
1808 // find it in the support files, we are done.
1809 if (check_inlines)
1810 {
1811 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1812 if (file_idx == UINT32_MAX)
1813 continue;
1814 }
1815
1816 if (line != 0)
1817 {
1818 LineTable *line_table = sc.comp_unit->GetLineTable();
1819
1820 if (line_table != NULL && line != 0)
1821 {
1822 // We will have already looked up the file index if
1823 // we are searching for inline entries.
1824 if (!check_inlines)
1825 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1826
1827 if (file_idx != UINT32_MAX)
1828 {
1829 uint32_t found_line;
1830 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1831 found_line = sc.line_entry.line;
1832
Greg Clayton016a95e2010-09-14 02:20:48 +00001833 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001834 {
1835 sc.function = NULL;
1836 sc.block = NULL;
1837 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1838 {
1839 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1840 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1841 {
1842 DWARFDebugInfoEntry *function_die = NULL;
1843 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00001844 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001845
1846 if (function_die != NULL)
1847 {
1848 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1849 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001850 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001851 }
1852
1853 if (sc.function != NULL)
1854 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001855 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001856
1857 if (block_die != NULL)
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001858 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001859 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001860 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001861 }
1862 }
1863 }
1864
1865 sc_list.Append(sc);
1866 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1867 }
1868 }
1869 }
1870 else if (file_spec_matches_cu_file_spec && !check_inlines)
1871 {
1872 // only append the context if we aren't looking for inline call sites
1873 // by file and line and if the file spec matches that of the compile unit
1874 sc_list.Append(sc);
1875 }
1876 }
1877 else if (file_spec_matches_cu_file_spec && !check_inlines)
1878 {
1879 // only append the context if we aren't looking for inline call sites
1880 // by file and line and if the file spec matches that of the compile unit
1881 sc_list.Append(sc);
1882 }
1883
1884 if (!check_inlines)
1885 break;
1886 }
1887 }
1888 }
1889 }
1890 return sc_list.GetSize() - prev_size;
1891}
1892
1893void
1894SymbolFileDWARF::Index ()
1895{
1896 if (m_indexed)
1897 return;
1898 m_indexed = true;
1899 Timer scoped_timer (__PRETTY_FUNCTION__,
1900 "SymbolFileDWARF::Index (%s)",
1901 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1902
1903 DWARFDebugInfo* debug_info = DebugInfo();
1904 if (debug_info)
1905 {
Greg Clayton016a95e2010-09-14 02:20:48 +00001906 m_aranges.reset(new DWARFDebugAranges());
1907
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001908 uint32_t cu_idx = 0;
1909 const uint32_t num_compile_units = GetNumCompileUnits();
1910 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1911 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001912 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001913
Greg Clayton96d7d742010-11-10 23:42:09 +00001914 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001915
Greg Clayton96d7d742010-11-10 23:42:09 +00001916 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00001917 m_function_basename_index,
1918 m_function_fullname_index,
1919 m_function_method_index,
1920 m_function_selector_index,
1921 m_objc_class_selectors_index,
1922 m_global_index,
1923 m_type_index,
1924 m_namespace_index,
1925 DebugRanges(),
1926 m_aranges.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001927
1928 // Keep memory down by clearing DIEs if this generate function
1929 // caused them to be parsed
1930 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00001931 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001932 }
1933
Greg Clayton016a95e2010-09-14 02:20:48 +00001934 m_aranges->Sort();
Greg Claytonc685f8e2010-09-15 04:15:46 +00001935
Greg Clayton24739922010-10-13 03:15:28 +00001936#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00001937 StreamFile s(stdout, false);
Greg Clayton24739922010-10-13 03:15:28 +00001938 s.Printf ("DWARF index for (%s) '%s/%s':",
1939 GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1940 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1941 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00001942 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1943 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1944 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1945 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1946 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1947 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00001948 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00001949 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001950#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001951 }
1952}
1953
1954uint32_t
1955SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1956{
Greg Claytonc685f8e2010-09-15 04:15:46 +00001957 DWARFDebugInfo* info = DebugInfo();
1958 if (info == NULL)
1959 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001960
1961 // If we aren't appending the results to this list, then clear the list
1962 if (!append)
1963 variables.Clear();
1964
1965 // Remember how many variables are in the list before we search in case
1966 // we are appending the results to a variable list.
1967 const uint32_t original_size = variables.GetSize();
1968
1969 // Index the DWARF if we haven't already
1970 if (!m_indexed)
1971 Index ();
1972
Greg Claytonc685f8e2010-09-15 04:15:46 +00001973 SymbolContext sc;
1974 sc.module_sp = m_obj_file->GetModule()->GetSP();
1975 assert (sc.module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001976
Greg Clayton96d7d742010-11-10 23:42:09 +00001977 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001978 DWARFCompileUnit* prev_cu = NULL;
1979 const DWARFDebugInfoEntry* die = NULL;
1980 std::vector<NameToDIE::Info> die_info_array;
1981 const size_t num_matches = m_global_index.Find(name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00001982 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001983 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001984 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001985
Greg Clayton96d7d742010-11-10 23:42:09 +00001986 if (curr_cu != prev_cu)
1987 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001988
Greg Clayton96d7d742010-11-10 23:42:09 +00001989 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001990
Greg Clayton96d7d742010-11-10 23:42:09 +00001991 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001992 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001993
Greg Clayton96d7d742010-11-10 23:42:09 +00001994 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001995
1996 if (variables.GetSize() - original_size >= max_matches)
1997 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001998 }
1999
2000 // Return the number of variable that were appended to the list
2001 return variables.GetSize() - original_size;
2002}
2003
2004uint32_t
2005SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2006{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002007 DWARFDebugInfo* info = DebugInfo();
2008 if (info == NULL)
2009 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002010
2011 // If we aren't appending the results to this list, then clear the list
2012 if (!append)
2013 variables.Clear();
2014
2015 // Remember how many variables are in the list before we search in case
2016 // we are appending the results to a variable list.
2017 const uint32_t original_size = variables.GetSize();
2018
2019 // Index the DWARF if we haven't already
2020 if (!m_indexed)
2021 Index ();
2022
Greg Claytonc685f8e2010-09-15 04:15:46 +00002023 SymbolContext sc;
2024 sc.module_sp = m_obj_file->GetModule()->GetSP();
2025 assert (sc.module_sp);
2026
Greg Clayton96d7d742010-11-10 23:42:09 +00002027 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002028 DWARFCompileUnit* prev_cu = NULL;
2029 const DWARFDebugInfoEntry* die = NULL;
2030 std::vector<NameToDIE::Info> die_info_array;
2031 const size_t num_matches = m_global_index.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002032 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002033 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002034 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002035
Greg Clayton96d7d742010-11-10 23:42:09 +00002036 if (curr_cu != prev_cu)
2037 curr_cu->ExtractDIEsIfNeeded (false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002038
Greg Clayton96d7d742010-11-10 23:42:09 +00002039 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002040
Greg Clayton96d7d742010-11-10 23:42:09 +00002041 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002042 assert(sc.comp_unit != NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002043
Greg Clayton96d7d742010-11-10 23:42:09 +00002044 ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002045
Greg Claytonc685f8e2010-09-15 04:15:46 +00002046 if (variables.GetSize() - original_size >= max_matches)
2047 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002048 }
2049
2050 // Return the number of variable that were appended to the list
2051 return variables.GetSize() - original_size;
2052}
2053
2054
Greg Clayton0c5cd902010-06-28 21:30:43 +00002055void
2056SymbolFileDWARF::FindFunctions
2057(
2058 const ConstString &name,
Greg Claytonc685f8e2010-09-15 04:15:46 +00002059 const NameToDIE &name_to_die,
Greg Clayton0c5cd902010-06-28 21:30:43 +00002060 SymbolContextList& sc_list
2061)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002062{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002063 DWARFDebugInfo* info = DebugInfo();
2064 if (info == NULL)
2065 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002066
Greg Claytonc685f8e2010-09-15 04:15:46 +00002067 SymbolContext sc;
2068 sc.module_sp = m_obj_file->GetModule()->GetSP();
2069 assert (sc.module_sp);
2070
Greg Clayton96d7d742010-11-10 23:42:09 +00002071 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002072 DWARFCompileUnit* prev_cu = NULL;
2073 const DWARFDebugInfoEntry* die = NULL;
2074 std::vector<NameToDIE::Info> die_info_array;
Greg Claytond7e05462010-11-14 00:22:48 +00002075 const size_t num_matches = name_to_die.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002076 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002077 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002078 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002079
Greg Clayton96d7d742010-11-10 23:42:09 +00002080 if (curr_cu != prev_cu)
2081 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002082
Greg Clayton96d7d742010-11-10 23:42:09 +00002083 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytond7e05462010-11-14 00:22:48 +00002084
2085 const DWARFDebugInfoEntry* inlined_die = NULL;
2086 if (die->Tag() == DW_TAG_inlined_subroutine)
2087 {
2088 inlined_die = die;
2089
2090 while ((die = die->GetParent()) != NULL)
2091 {
2092 if (die->Tag() == DW_TAG_subprogram)
2093 break;
2094 }
2095 }
2096 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002097 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002098 {
Greg Claytond7e05462010-11-14 00:22:48 +00002099 Address addr;
2100 // Parse all blocks if needed
2101 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002102 {
Greg Claytond7e05462010-11-14 00:22:48 +00002103 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2104 assert (sc.block != NULL);
2105 if (sc.block->GetStartAddress (addr) == false)
2106 addr.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002107 }
Greg Claytond7e05462010-11-14 00:22:48 +00002108 else
2109 {
2110 sc.block = NULL;
2111 addr = sc.function->GetAddressRange().GetBaseAddress();
2112 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002113
Greg Claytond7e05462010-11-14 00:22:48 +00002114 if (addr.IsValid())
2115 {
2116
2117 // We found the function, so we should find the line table
2118 // and line table entry as well
2119 LineTable *line_table = sc.comp_unit->GetLineTable();
2120 if (line_table == NULL)
2121 {
2122 if (ParseCompileUnitLineTable(sc))
2123 line_table = sc.comp_unit->GetLineTable();
2124 }
2125 if (line_table != NULL)
2126 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2127
2128 sc_list.Append(sc);
2129 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002130 }
2131 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002132}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002133
Greg Claytonc685f8e2010-09-15 04:15:46 +00002134
2135void
2136SymbolFileDWARF::FindFunctions
2137(
2138 const RegularExpression &regex,
2139 const NameToDIE &name_to_die,
2140 SymbolContextList& sc_list
2141)
2142{
2143 DWARFDebugInfo* info = DebugInfo();
2144 if (info == NULL)
2145 return;
2146
2147 SymbolContext sc;
2148 sc.module_sp = m_obj_file->GetModule()->GetSP();
2149 assert (sc.module_sp);
2150
Greg Clayton96d7d742010-11-10 23:42:09 +00002151 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002152 DWARFCompileUnit* prev_cu = NULL;
2153 const DWARFDebugInfoEntry* die = NULL;
2154 std::vector<NameToDIE::Info> die_info_array;
2155 const size_t num_matches = name_to_die.Find(regex, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002156 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002157 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002158 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002159
Greg Clayton96d7d742010-11-10 23:42:09 +00002160 if (curr_cu != prev_cu)
2161 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002162
Greg Clayton96d7d742010-11-10 23:42:09 +00002163 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonab843392010-12-03 17:49:14 +00002164
2165 const DWARFDebugInfoEntry* inlined_die = NULL;
2166 if (die->Tag() == DW_TAG_inlined_subroutine)
2167 {
2168 inlined_die = die;
2169
2170 while ((die = die->GetParent()) != NULL)
2171 {
2172 if (die->Tag() == DW_TAG_subprogram)
2173 break;
2174 }
2175 }
2176 assert (die->Tag() == DW_TAG_subprogram);
Greg Clayton96d7d742010-11-10 23:42:09 +00002177 if (GetFunction (curr_cu, die, sc))
Greg Claytonc685f8e2010-09-15 04:15:46 +00002178 {
Greg Claytonab843392010-12-03 17:49:14 +00002179 Address addr;
2180 // Parse all blocks if needed
2181 if (inlined_die)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002182 {
Greg Claytonab843392010-12-03 17:49:14 +00002183 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2184 assert (sc.block != NULL);
2185 if (sc.block->GetStartAddress (addr) == false)
2186 addr.Clear();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002187 }
Greg Claytonab843392010-12-03 17:49:14 +00002188 else
2189 {
2190 sc.block = NULL;
2191 addr = sc.function->GetAddressRange().GetBaseAddress();
2192 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002193
Greg Claytonab843392010-12-03 17:49:14 +00002194 if (addr.IsValid())
2195 {
2196
2197 // We found the function, so we should find the line table
2198 // and line table entry as well
2199 LineTable *line_table = sc.comp_unit->GetLineTable();
2200 if (line_table == NULL)
2201 {
2202 if (ParseCompileUnitLineTable(sc))
2203 line_table = sc.comp_unit->GetLineTable();
2204 }
2205 if (line_table != NULL)
2206 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2207
2208 sc_list.Append(sc);
2209 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002210 }
2211 }
Greg Clayton0c5cd902010-06-28 21:30:43 +00002212}
2213
2214uint32_t
2215SymbolFileDWARF::FindFunctions
2216(
2217 const ConstString &name,
2218 uint32_t name_type_mask,
2219 bool append,
2220 SymbolContextList& sc_list
2221)
2222{
2223 Timer scoped_timer (__PRETTY_FUNCTION__,
2224 "SymbolFileDWARF::FindFunctions (name = '%s')",
2225 name.AsCString());
2226
Greg Clayton0c5cd902010-06-28 21:30:43 +00002227 // If we aren't appending the results to this list, then clear the list
2228 if (!append)
2229 sc_list.Clear();
2230
2231 // Remember how many sc_list are in the list before we search in case
2232 // we are appending the results to a variable list.
2233 uint32_t original_size = sc_list.GetSize();
2234
2235 // Index the DWARF if we haven't already
2236 if (!m_indexed)
2237 Index ();
2238
2239 if (name_type_mask & eFunctionNameTypeBase)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002240 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002241
2242 if (name_type_mask & eFunctionNameTypeFull)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002243 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002244
2245 if (name_type_mask & eFunctionNameTypeMethod)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002246 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002247
2248 if (name_type_mask & eFunctionNameTypeSelector)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002249 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton0c5cd902010-06-28 21:30:43 +00002250
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002251 // Return the number of variable that were appended to the list
2252 return sc_list.GetSize() - original_size;
2253}
2254
2255
2256uint32_t
2257SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2258{
2259 Timer scoped_timer (__PRETTY_FUNCTION__,
2260 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2261 regex.GetText());
2262
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002263 // If we aren't appending the results to this list, then clear the list
2264 if (!append)
2265 sc_list.Clear();
2266
2267 // Remember how many sc_list are in the list before we search in case
2268 // we are appending the results to a variable list.
2269 uint32_t original_size = sc_list.GetSize();
2270
2271 // Index the DWARF if we haven't already
2272 if (!m_indexed)
2273 Index ();
2274
Greg Claytonc685f8e2010-09-15 04:15:46 +00002275 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002276
Greg Claytonc685f8e2010-09-15 04:15:46 +00002277 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002278
2279 // Return the number of variable that were appended to the list
2280 return sc_list.GetSize() - original_size;
2281}
Greg Claytond16e1e52011-07-12 17:06:17 +00002282void
2283SymbolFileDWARF::ReportError (const char *format, ...)
2284{
2285 ::fprintf (stderr,
2286 "error: %s/%s ",
2287 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2288 m_obj_file->GetFileSpec().GetFilename().GetCString());
2289
2290 va_list args;
2291 va_start (args, format);
2292 vfprintf (stderr, format, args);
2293 va_end (args);
2294}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002295
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002296uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002297SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002298{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002299 DWARFDebugInfo* info = DebugInfo();
2300 if (info == NULL)
2301 return 0;
2302
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002303 // If we aren't appending the results to this list, then clear the list
2304 if (!append)
2305 types.Clear();
2306
Greg Clayton6dbd3982010-09-15 05:51:24 +00002307 // Index if we already haven't to make sure the compile units
2308 // get indexed and make their global DIE index list
2309 if (!m_indexed)
2310 Index ();
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002311
Greg Claytonc685f8e2010-09-15 04:15:46 +00002312 const uint32_t initial_types_size = types.GetSize();
Greg Clayton96d7d742010-11-10 23:42:09 +00002313 DWARFCompileUnit* curr_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002314 DWARFCompileUnit* prev_cu = NULL;
2315 const DWARFDebugInfoEntry* die = NULL;
2316 std::vector<NameToDIE::Info> die_info_array;
Greg Clayton69b04882010-10-15 02:03:22 +00002317 const size_t num_matches = m_type_index.Find (name, die_info_array);
Greg Clayton96d7d742010-11-10 23:42:09 +00002318 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002319 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002320 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002321
Greg Clayton96d7d742010-11-10 23:42:09 +00002322 if (curr_cu != prev_cu)
2323 curr_cu->ExtractDIEsIfNeeded (false);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002324
Greg Clayton96d7d742010-11-10 23:42:09 +00002325 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002326
Greg Clayton96d7d742010-11-10 23:42:09 +00002327 Type *matching_type = ResolveType (curr_cu, die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002328 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002329 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00002330 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002331 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Clayton73bf5db2011-06-17 01:22:15 +00002332 if (type_sp)
2333 {
2334 types.InsertUnique (type_sp);
2335 if (types.GetSize() >= max_matches)
2336 break;
2337 }
2338 else
2339 {
2340 fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID());
2341 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002342 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002343 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002344 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002345}
2346
2347
Greg Clayton526e5af2010-11-13 03:52:47 +00002348ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002349SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2350 const ConstString &name)
2351{
Greg Clayton526e5af2010-11-13 03:52:47 +00002352 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002353 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002354 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002355 {
Greg Clayton526e5af2010-11-13 03:52:47 +00002356 // Index if we already haven't to make sure the compile units
2357 // get indexed and make their global DIE index list
2358 if (!m_indexed)
2359 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00002360
Greg Clayton526e5af2010-11-13 03:52:47 +00002361 DWARFCompileUnit* curr_cu = NULL;
2362 DWARFCompileUnit* prev_cu = NULL;
2363 const DWARFDebugInfoEntry* die = NULL;
2364 std::vector<NameToDIE::Info> die_info_array;
2365 const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2366 for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2367 {
2368 curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2369
2370 if (curr_cu != prev_cu)
2371 curr_cu->ExtractDIEsIfNeeded (false);
Greg Clayton96d7d742010-11-10 23:42:09 +00002372
Greg Clayton526e5af2010-11-13 03:52:47 +00002373 die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2374
2375 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2376 if (clang_namespace_decl)
2377 {
2378 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2379 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2380 }
2381 }
Greg Clayton96d7d742010-11-10 23:42:09 +00002382 }
Greg Clayton526e5af2010-11-13 03:52:47 +00002383 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002384}
2385
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002386uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002387SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002388{
2389 // Remember how many sc_list are in the list before we search in case
2390 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002391 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002392
2393 const uint32_t num_die_offsets = die_offsets.size();
2394 // Parse all of the types we found from the pubtypes matches
2395 uint32_t i;
2396 uint32_t num_matches = 0;
2397 for (i = 0; i < num_die_offsets; ++i)
2398 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002399 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2400 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002401 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002402 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002403 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002404 assert (type_sp.get() != NULL);
2405 types.InsertUnique (type_sp);
2406 ++num_matches;
2407 if (num_matches >= max_matches)
2408 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002409 }
2410 }
2411
2412 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00002413 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002414}
2415
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002416
2417size_t
Greg Clayton5113dc82011-08-12 06:47:54 +00002418SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
2419 clang::DeclContext *containing_decl_ctx,
2420 TypeSP& type_sp,
2421 DWARFCompileUnit* dwarf_cu,
2422 const DWARFDebugInfoEntry *parent_die,
2423 bool skip_artificial,
2424 bool &is_static,
2425 TypeList* type_list,
2426 std::vector<clang_type_t>& function_param_types,
2427 std::vector<clang::ParmVarDecl*>& function_param_decls,
2428 unsigned &type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002429{
2430 if (parent_die == NULL)
2431 return 0;
2432
Greg Claytond88d7592010-09-15 08:33:30 +00002433 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2434
Greg Clayton7fedea22010-11-16 02:10:54 +00002435 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002436 const DWARFDebugInfoEntry *die;
2437 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2438 {
2439 dw_tag_t tag = die->Tag();
2440 switch (tag)
2441 {
2442 case DW_TAG_formal_parameter:
2443 {
2444 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002445 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002446 if (num_attributes > 0)
2447 {
2448 const char *name = NULL;
2449 Declaration decl;
2450 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002451 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002452 // one of None, Auto, Register, Extern, Static, PrivateExtern
2453
Sean Callanane2ef6e32010-09-23 03:01:22 +00002454 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002455 uint32_t i;
2456 for (i=0; i<num_attributes; ++i)
2457 {
2458 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2459 DWARFFormValue form_value;
2460 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2461 {
2462 switch (attr)
2463 {
2464 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2465 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2466 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2467 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2468 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00002469 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002470 case DW_AT_location:
2471 // if (form_value.BlockData())
2472 // {
2473 // const DataExtractor& debug_info_data = debug_info();
2474 // uint32_t block_length = form_value.Unsigned();
2475 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2476 // }
2477 // else
2478 // {
2479 // }
2480 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002481 case DW_AT_const_value:
2482 case DW_AT_default_value:
2483 case DW_AT_description:
2484 case DW_AT_endianity:
2485 case DW_AT_is_optional:
2486 case DW_AT_segment:
2487 case DW_AT_variable_parameter:
2488 default:
2489 case DW_AT_abstract_origin:
2490 case DW_AT_sibling:
2491 break;
2492 }
2493 }
2494 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00002495
Greg Clayton0fffff52010-09-24 05:15:53 +00002496 bool skip = false;
2497 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002498 {
Greg Clayton0fffff52010-09-24 05:15:53 +00002499 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00002500 {
2501 // In order to determine if a C++ member function is
2502 // "const" we have to look at the const-ness of "this"...
2503 // Ugly, but that
2504 if (arg_idx == 0)
2505 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002506 if (containing_decl_ctx->getDeclKind() == clang::Decl::CXXRecord)
Sean Callanan763d72a2011-08-02 22:21:50 +00002507 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002508 // Often times compilers omit the "this" name for the
2509 // specification DIEs, so we can't rely upon the name
2510 // being in the formal parameter DIE...
2511 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton7fedea22010-11-16 02:10:54 +00002512 {
Greg Clayton5113dc82011-08-12 06:47:54 +00002513 Type *this_type = ResolveTypeUID (param_type_die_offset);
2514 if (this_type)
2515 {
2516 uint32_t encoding_mask = this_type->GetEncodingMask();
2517 if (encoding_mask & Type::eEncodingIsPointerUID)
2518 {
2519 is_static = false;
2520
2521 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
2522 type_quals |= clang::Qualifiers::Const;
2523 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
2524 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00002525 }
2526 }
2527 }
2528 }
2529 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002530 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00002531 }
Greg Clayton0fffff52010-09-24 05:15:53 +00002532 else
2533 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002534
Greg Clayton0fffff52010-09-24 05:15:53 +00002535 // HACK: Objective C formal parameters "self" and "_cmd"
2536 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00002537 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2538 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00002539 {
2540 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2541 skip = true;
2542 }
2543 }
2544 }
2545
2546 if (!skip)
2547 {
2548 Type *type = ResolveTypeUID(param_type_die_offset);
2549 if (type)
2550 {
Greg Claytonc93237c2010-10-01 20:48:32 +00002551 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00002552
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002553 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00002554 assert(param_var_decl);
2555 function_param_decls.push_back(param_var_decl);
2556 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002557 }
2558 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002559 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002560 }
2561 break;
2562
2563 default:
2564 break;
2565 }
2566 }
Greg Clayton7fedea22010-11-16 02:10:54 +00002567 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002568}
2569
2570size_t
2571SymbolFileDWARF::ParseChildEnumerators
2572(
2573 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00002574 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002575 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00002576 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002577 const DWARFDebugInfoEntry *parent_die
2578)
2579{
2580 if (parent_die == NULL)
2581 return 0;
2582
2583 size_t enumerators_added = 0;
2584 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002585 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2586
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002587 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2588 {
2589 const dw_tag_t tag = die->Tag();
2590 if (tag == DW_TAG_enumerator)
2591 {
2592 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002593 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002594 if (num_child_attributes > 0)
2595 {
2596 const char *name = NULL;
2597 bool got_value = false;
2598 int64_t enum_value = 0;
2599 Declaration decl;
2600
2601 uint32_t i;
2602 for (i=0; i<num_child_attributes; ++i)
2603 {
2604 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2605 DWARFFormValue form_value;
2606 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2607 {
2608 switch (attr)
2609 {
2610 case DW_AT_const_value:
2611 got_value = true;
2612 enum_value = form_value.Unsigned();
2613 break;
2614
2615 case DW_AT_name:
2616 name = form_value.AsCString(&get_debug_str_data());
2617 break;
2618
2619 case DW_AT_description:
2620 default:
2621 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2622 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2623 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2624 case DW_AT_sibling:
2625 break;
2626 }
2627 }
2628 }
2629
2630 if (name && name[0] && got_value)
2631 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002632 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2633 enumerator_clang_type,
2634 decl,
2635 name,
2636 enum_value,
2637 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002638 ++enumerators_added;
2639 }
2640 }
2641 }
2642 }
2643 return enumerators_added;
2644}
2645
2646void
2647SymbolFileDWARF::ParseChildArrayInfo
2648(
2649 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00002650 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002651 const DWARFDebugInfoEntry *parent_die,
2652 int64_t& first_index,
2653 std::vector<uint64_t>& element_orders,
2654 uint32_t& byte_stride,
2655 uint32_t& bit_stride
2656)
2657{
2658 if (parent_die == NULL)
2659 return;
2660
2661 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00002662 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002663 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2664 {
2665 const dw_tag_t tag = die->Tag();
2666 switch (tag)
2667 {
2668 case DW_TAG_enumerator:
2669 {
2670 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002671 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002672 if (num_child_attributes > 0)
2673 {
2674 const char *name = NULL;
2675 bool got_value = false;
2676 int64_t enum_value = 0;
2677
2678 uint32_t i;
2679 for (i=0; i<num_child_attributes; ++i)
2680 {
2681 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2682 DWARFFormValue form_value;
2683 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2684 {
2685 switch (attr)
2686 {
2687 case DW_AT_const_value:
2688 got_value = true;
2689 enum_value = form_value.Unsigned();
2690 break;
2691
2692 case DW_AT_name:
2693 name = form_value.AsCString(&get_debug_str_data());
2694 break;
2695
2696 case DW_AT_description:
2697 default:
2698 case DW_AT_decl_file:
2699 case DW_AT_decl_line:
2700 case DW_AT_decl_column:
2701 case DW_AT_sibling:
2702 break;
2703 }
2704 }
2705 }
2706 }
2707 }
2708 break;
2709
2710 case DW_TAG_subrange_type:
2711 {
2712 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00002713 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002714 if (num_child_attributes > 0)
2715 {
2716 const char *name = NULL;
2717 bool got_value = false;
2718 uint64_t byte_size = 0;
2719 int64_t enum_value = 0;
2720 uint64_t num_elements = 0;
2721 uint64_t lower_bound = 0;
2722 uint64_t upper_bound = 0;
2723 uint32_t i;
2724 for (i=0; i<num_child_attributes; ++i)
2725 {
2726 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2727 DWARFFormValue form_value;
2728 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2729 {
2730 switch (attr)
2731 {
2732 case DW_AT_const_value:
2733 got_value = true;
2734 enum_value = form_value.Unsigned();
2735 break;
2736
2737 case DW_AT_name:
2738 name = form_value.AsCString(&get_debug_str_data());
2739 break;
2740
2741 case DW_AT_count:
2742 num_elements = form_value.Unsigned();
2743 break;
2744
2745 case DW_AT_bit_stride:
2746 bit_stride = form_value.Unsigned();
2747 break;
2748
2749 case DW_AT_byte_stride:
2750 byte_stride = form_value.Unsigned();
2751 break;
2752
2753 case DW_AT_byte_size:
2754 byte_size = form_value.Unsigned();
2755 break;
2756
2757 case DW_AT_lower_bound:
2758 lower_bound = form_value.Unsigned();
2759 break;
2760
2761 case DW_AT_upper_bound:
2762 upper_bound = form_value.Unsigned();
2763 break;
2764
2765 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002766 case DW_AT_abstract_origin:
2767 case DW_AT_accessibility:
2768 case DW_AT_allocated:
2769 case DW_AT_associated:
2770 case DW_AT_data_location:
2771 case DW_AT_declaration:
2772 case DW_AT_description:
2773 case DW_AT_sibling:
2774 case DW_AT_threads_scaled:
2775 case DW_AT_type:
2776 case DW_AT_visibility:
2777 break;
2778 }
2779 }
2780 }
2781
2782 if (upper_bound > lower_bound)
2783 num_elements = upper_bound - lower_bound + 1;
2784
2785 if (num_elements > 0)
2786 element_orders.push_back (num_elements);
2787 }
2788 }
2789 break;
2790 }
2791 }
2792}
2793
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002794TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00002795SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002796{
2797 TypeSP type_sp;
2798 if (die != NULL)
2799 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002800 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00002801 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002802 if (type_ptr == NULL)
2803 {
Greg Claytonca512b32011-01-14 04:54:56 +00002804 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
2805 assert (lldb_cu);
2806 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00002807 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002808 }
2809 else if (type_ptr != DIE_IS_BEING_PARSED)
2810 {
2811 // Grab the existing type from the master types lists
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00002812 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002813 }
2814
2815 }
2816 return type_sp;
2817}
2818
2819clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00002820SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002821{
2822 if (die_offset != DW_INVALID_OFFSET)
2823 {
2824 DWARFCompileUnitSP cu_sp;
2825 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Sean Callanan72e49402011-08-05 23:43:37 +00002826 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002827 }
2828 return NULL;
2829}
2830
Sean Callanan72e49402011-08-05 23:43:37 +00002831clang::DeclContext *
2832SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
2833{
2834 if (die_offset != DW_INVALID_OFFSET)
2835 {
2836 DWARFCompileUnitSP cu_sp;
2837 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2838 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
2839 }
2840 return NULL;
2841}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002842
Greg Clayton96d7d742010-11-10 23:42:09 +00002843clang::NamespaceDecl *
2844SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2845{
2846 if (die->Tag() == DW_TAG_namespace)
2847 {
2848 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2849 if (namespace_name)
2850 {
2851 Declaration decl; // TODO: fill in the decl object
Sean Callanan72e49402011-08-05 23:43:37 +00002852 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent()));
Greg Clayton96d7d742010-11-10 23:42:09 +00002853 if (namespace_decl)
Greg Claytona2721472011-06-25 00:44:06 +00002854 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Clayton96d7d742010-11-10 23:42:09 +00002855 return namespace_decl;
2856 }
2857 }
2858 return NULL;
2859}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002860
2861clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00002862SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2863{
2864 // If this DIE has a specification, or an abstract origin, then trace to those.
2865
2866 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
2867 if (die_offset != DW_INVALID_OFFSET)
2868 return GetClangDeclContextForDIEOffset (sc, die_offset);
2869
2870 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
2871 if (die_offset != DW_INVALID_OFFSET)
2872 return GetClangDeclContextForDIEOffset (sc, die_offset);
2873
2874 // This is the DIE we want. Parse it, then query our map.
2875
2876 ParseType(sc, curr_cu, die, NULL);
2877
2878 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2879 if (pos != m_die_to_decl_ctx.end())
2880 return pos->second;
2881 else
2882 return NULL;
2883}
2884
2885clang::DeclContext *
2886SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002887{
Greg Claytonca512b32011-01-14 04:54:56 +00002888 if (m_clang_tu_decl == NULL)
2889 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002890
Sean Callanan72e49402011-08-05 23:43:37 +00002891 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x )\n", die->GetOffset());
Greg Claytonca512b32011-01-14 04:54:56 +00002892 const DWARFDebugInfoEntry * const decl_die = die;
Greg Clayton4cd17802011-01-25 06:17:32 +00002893 clang::DeclContext *decl_ctx = NULL;
2894
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002895 while (die != NULL)
2896 {
Greg Claytonca512b32011-01-14 04:54:56 +00002897 // If this is the original DIE that we are searching for a declaration
2898 // for, then don't look in the cache as we don't want our own decl
2899 // context to be our decl context...
2900 if (decl_die != die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002901 {
Greg Claytonca512b32011-01-14 04:54:56 +00002902 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2903 if (pos != m_die_to_decl_ctx.end())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002904 {
Sean Callanan72e49402011-08-05 23:43:37 +00002905 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytonca512b32011-01-14 04:54:56 +00002906 return pos->second;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002907 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002908
Sean Callanan72e49402011-08-05 23:43:37 +00002909 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytonca512b32011-01-14 04:54:56 +00002910
2911 switch (die->Tag())
2912 {
2913 case DW_TAG_namespace:
2914 {
2915 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2916 if (namespace_name)
2917 {
2918 Declaration decl; // TODO: fill in the decl object
Sean Callanan72e49402011-08-05 23:43:37 +00002919 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die));
Greg Claytonca512b32011-01-14 04:54:56 +00002920 if (namespace_decl)
2921 {
Sean Callanan72e49402011-08-05 23:43:37 +00002922 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytona2721472011-06-25 00:44:06 +00002923 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Claytonca512b32011-01-14 04:54:56 +00002924 }
2925 return namespace_decl;
2926 }
2927 }
2928 break;
2929
2930 case DW_TAG_structure_type:
2931 case DW_TAG_union_type:
2932 case DW_TAG_class_type:
2933 {
Greg Clayton4cd17802011-01-25 06:17:32 +00002934 Type* type = ResolveType (curr_cu, die);
Greg Claytonca512b32011-01-14 04:54:56 +00002935 pos = m_die_to_decl_ctx.find(die);
Greg Claytonca512b32011-01-14 04:54:56 +00002936 if (pos != m_die_to_decl_ctx.end())
2937 {
Sean Callanan72e49402011-08-05 23:43:37 +00002938 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytonca512b32011-01-14 04:54:56 +00002939 return pos->second;
2940 }
Greg Clayton4cd17802011-01-25 06:17:32 +00002941 else
2942 {
2943 if (type)
2944 {
2945 decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
2946 if (decl_ctx)
2947 return decl_ctx;
2948 }
2949 }
Greg Claytonca512b32011-01-14 04:54:56 +00002950 }
2951 break;
2952
2953 default:
2954 break;
2955 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002956 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002957
Greg Clayton6beaaa62011-01-17 03:46:26 +00002958 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00002959 if (die_offset != DW_INVALID_OFFSET)
2960 {
Sean Callanan72e49402011-08-05 23:43:37 +00002961 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2962 decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset);
Greg Claytonca512b32011-01-14 04:54:56 +00002963 if (decl_ctx != m_clang_tu_decl)
2964 return decl_ctx;
2965 }
2966
Greg Clayton6beaaa62011-01-17 03:46:26 +00002967 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
Greg Claytonca512b32011-01-14 04:54:56 +00002968 if (die_offset != DW_INVALID_OFFSET)
2969 {
Sean Callanan72e49402011-08-05 23:43:37 +00002970 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2971 decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset);
Greg Claytonca512b32011-01-14 04:54:56 +00002972 if (decl_ctx != m_clang_tu_decl)
2973 return decl_ctx;
2974 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002975
2976 die = die->GetParent();
2977 }
Greg Clayton7a345282010-11-09 23:46:37 +00002978 // Right now we have only one translation unit per module...
Sean Callanan72e49402011-08-05 23:43:37 +00002979 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset());
Greg Clayton7a345282010-11-09 23:46:37 +00002980 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002981}
2982
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002983// This function can be used when a DIE is found that is a forward declaration
2984// DIE and we want to try and find a type that has the complete definition.
2985TypeSP
2986SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Clayton1a65ae12011-01-25 23:55:37 +00002987 DWARFCompileUnit* cu,
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002988 const DWARFDebugInfoEntry *die,
2989 const ConstString &type_name
2990)
2991{
2992 TypeSP type_sp;
2993
Greg Clayton1a65ae12011-01-25 23:55:37 +00002994 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00002995 return type_sp;
2996
Greg Clayton69974892010-12-03 21:42:06 +00002997 if (!m_indexed)
2998 Index ();
2999
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003000 const dw_tag_t type_tag = die->Tag();
3001 std::vector<NameToDIE::Info> die_info_array;
3002 const size_t num_matches = m_type_index.Find (type_name, die_info_array);
3003 if (num_matches > 0)
3004 {
3005 DWARFCompileUnit* type_cu = NULL;
Greg Clayton1a65ae12011-01-25 23:55:37 +00003006 DWARFCompileUnit* curr_cu = cu;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003007 DWARFDebugInfo *info = DebugInfo();
3008 for (size_t i=0; i<num_matches; ++i)
3009 {
3010 type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
3011
3012 if (type_cu != curr_cu)
3013 {
3014 type_cu->ExtractDIEsIfNeeded (false);
3015 curr_cu = type_cu;
3016 }
3017
3018 DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
3019
3020 if (type_die != die && type_die->Tag() == type_tag)
3021 {
3022 // Hold off on comparing parent DIE tags until
3023 // we know what happens with stuff in namespaces
3024 // for gcc and clang...
3025 //DWARFDebugInfoEntry *parent_die = die->GetParent();
3026 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
3027 //if (parent_die->Tag() == parent_type_die->Tag())
3028 {
3029 Type *resolved_type = ResolveType (type_cu, type_die, false);
3030 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3031 {
3032 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
3033 die->GetOffset(),
Greg Clayton96d7d742010-11-10 23:42:09 +00003034 curr_cu->GetOffset(),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003035 m_obj_file->GetFileSpec().GetFilename().AsCString(),
3036 type_die->GetOffset(),
3037 type_cu->GetOffset());
3038
3039 m_die_to_type[die] = resolved_type;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003040 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Clayton40328bf2010-11-08 02:05:08 +00003041 if (!type_sp)
3042 {
3043 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
3044 }
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003045 break;
3046 }
3047 }
3048 }
3049 }
3050 }
3051 return type_sp;
3052}
3053
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003054TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00003055SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003056{
3057 TypeSP type_sp;
3058
Greg Clayton1be10fc2010-09-29 01:12:09 +00003059 if (type_is_new_ptr)
3060 *type_is_new_ptr = false;
3061
Sean Callananc7fbf732010-08-06 00:32:49 +00003062 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003063 if (die != NULL)
3064 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00003065 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003066 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00003067 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003068 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003069 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003070 if (type_is_new_ptr)
3071 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003072
Greg Clayton594e5ed2010-09-27 21:07:38 +00003073 const dw_tag_t tag = die->Tag();
3074
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003075 bool is_forward_declaration = false;
3076 DWARFDebugInfoEntry::Attributes attributes;
3077 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00003078 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00003079 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3080 size_t byte_size = 0;
Greg Clayton36909642011-03-15 04:38:20 +00003081 bool byte_size_valid = false;
Greg Clayton526e5af2010-11-13 03:52:47 +00003082 Declaration decl;
3083
Greg Clayton4957bf62010-09-30 21:49:03 +00003084 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003085 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003086
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003087 dw_attr_t attr;
3088
3089 switch (tag)
3090 {
3091 case DW_TAG_base_type:
3092 case DW_TAG_pointer_type:
3093 case DW_TAG_reference_type:
3094 case DW_TAG_typedef:
3095 case DW_TAG_const_type:
3096 case DW_TAG_restrict_type:
3097 case DW_TAG_volatile_type:
3098 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003099 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003100 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003101
Greg Claytond88d7592010-09-15 08:33:30 +00003102 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003103 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003104 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3105
3106 if (num_attributes > 0)
3107 {
3108 uint32_t i;
3109 for (i=0; i<num_attributes; ++i)
3110 {
3111 attr = attributes.AttributeAtIndex(i);
3112 DWARFFormValue form_value;
3113 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3114 {
3115 switch (attr)
3116 {
3117 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3118 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3119 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3120 case DW_AT_name:
Jim Ingham337030f2011-04-15 23:41:23 +00003121
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003122 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00003123 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3124 // include the "&"...
3125 if (tag == DW_TAG_reference_type)
3126 {
3127 if (strchr (type_name_cstr, '&') == NULL)
3128 type_name_cstr = NULL;
3129 }
3130 if (type_name_cstr)
3131 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003132 break;
Greg Clayton36909642011-03-15 04:38:20 +00003133 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003134 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3135 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3136 default:
3137 case DW_AT_sibling:
3138 break;
3139 }
3140 }
3141 }
3142 }
3143
Greg Claytonc93237c2010-10-01 20:48:32 +00003144 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);
3145
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003146 switch (tag)
3147 {
3148 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003149 break;
3150
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003151 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003152 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003153 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3154 encoding,
3155 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003156 break;
3157
Greg Clayton526e5af2010-11-13 03:52:47 +00003158 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3159 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3160 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3161 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3162 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3163 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003164 }
3165
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003166 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3167 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3168 {
3169 static ConstString g_objc_type_name_id("id");
3170 static ConstString g_objc_type_name_Class("Class");
3171 static ConstString g_objc_type_name_selector("SEL");
3172
Greg Clayton24739922010-10-13 03:15:28 +00003173 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003174 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003175 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003176 resolve_state = Type::eResolveStateFull;
3177
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003178 }
Greg Clayton24739922010-10-13 03:15:28 +00003179 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003180 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003181 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003182 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003183 }
Greg Clayton24739922010-10-13 03:15:28 +00003184 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003185 {
Sean Callananf6c73082010-12-06 23:53:20 +00003186 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003187 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003188 }
3189 }
3190
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003191 type_sp.reset( new Type (die->GetOffset(),
3192 this,
3193 type_name_const_str,
3194 byte_size,
3195 NULL,
3196 encoding_uid,
3197 encoding_data_type,
3198 &decl,
3199 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003200 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003201
Greg Clayton594e5ed2010-09-27 21:07:38 +00003202 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003203
3204// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3205// if (encoding_type != NULL)
3206// {
3207// if (encoding_type != DIE_IS_BEING_PARSED)
3208// type_sp->SetEncodingType(encoding_type);
3209// else
3210// m_indirect_fixups.push_back(type_sp.get());
3211// }
3212 }
3213 break;
3214
3215 case DW_TAG_structure_type:
3216 case DW_TAG_union_type:
3217 case DW_TAG_class_type:
3218 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003219 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003220 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003221
Greg Clayton9e409562010-07-28 02:04:09 +00003222 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003223 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003224 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003225 if (num_attributes > 0)
3226 {
3227 uint32_t i;
3228 for (i=0; i<num_attributes; ++i)
3229 {
3230 attr = attributes.AttributeAtIndex(i);
3231 DWARFFormValue form_value;
3232 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3233 {
3234 switch (attr)
3235 {
Greg Clayton9e409562010-07-28 02:04:09 +00003236 case DW_AT_decl_file:
3237 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3238 break;
3239
3240 case DW_AT_decl_line:
3241 decl.SetLine(form_value.Unsigned());
3242 break;
3243
3244 case DW_AT_decl_column:
3245 decl.SetColumn(form_value.Unsigned());
3246 break;
3247
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003248 case DW_AT_name:
3249 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003250 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003251 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003252
3253 case DW_AT_byte_size:
3254 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00003255 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003256 break;
3257
3258 case DW_AT_accessibility:
3259 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3260 break;
3261
3262 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003263 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003264 break;
3265
3266 case DW_AT_APPLE_runtime_class:
3267 class_language = (LanguageType)form_value.Signed();
3268 break;
3269
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003270 case DW_AT_allocated:
3271 case DW_AT_associated:
3272 case DW_AT_data_location:
3273 case DW_AT_description:
3274 case DW_AT_start_scope:
3275 case DW_AT_visibility:
3276 default:
3277 case DW_AT_sibling:
3278 break;
3279 }
3280 }
3281 }
3282 }
3283
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003284 UniqueDWARFASTType unique_ast_entry;
3285 if (decl.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003286 {
Greg Claytone576ab22011-02-15 00:19:15 +00003287 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Greg Clayton36909642011-03-15 04:38:20 +00003288 this,
3289 dwarf_cu,
Greg Claytone576ab22011-02-15 00:19:15 +00003290 die,
3291 decl,
Greg Clayton36909642011-03-15 04:38:20 +00003292 byte_size_valid ? byte_size : -1,
Greg Claytone576ab22011-02-15 00:19:15 +00003293 unique_ast_entry))
Greg Claytonc615ce42010-11-09 04:42:43 +00003294 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003295 // We have already parsed this type or from another
3296 // compile unit. GCC loves to use the "one definition
3297 // rule" which can result in multiple definitions
3298 // of the same class over and over in each compile
3299 // unit.
3300 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003301 if (type_sp)
3302 {
Greg Clayton4272cc72011-02-02 02:24:04 +00003303 m_die_to_type[die] = type_sp.get();
3304 return type_sp;
3305 }
3306 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003307 }
3308
3309 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3310
3311 int tag_decl_kind = -1;
3312 AccessType default_accessibility = eAccessNone;
3313 if (tag == DW_TAG_structure_type)
3314 {
3315 tag_decl_kind = clang::TTK_Struct;
3316 default_accessibility = eAccessPublic;
3317 }
3318 else if (tag == DW_TAG_union_type)
3319 {
3320 tag_decl_kind = clang::TTK_Union;
3321 default_accessibility = eAccessPublic;
3322 }
3323 else if (tag == DW_TAG_class_type)
3324 {
3325 tag_decl_kind = clang::TTK_Class;
3326 default_accessibility = eAccessPrivate;
3327 }
3328
3329
3330 if (is_forward_declaration)
3331 {
3332 // We have a forward declaration to a type and we need
3333 // to try and find a full declaration. We look in the
3334 // current type index just in case we have a forward
3335 // declaration followed by an actual declarations in the
3336 // DWARF. If this fails, we need to look elsewhere...
3337
3338 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3339
3340 if (!type_sp && m_debug_map_symfile)
Greg Clayton4272cc72011-02-02 02:24:04 +00003341 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003342 // We weren't able to find a full declaration in
3343 // this DWARF, see if we have a declaration anywhere
3344 // else...
3345 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton4272cc72011-02-02 02:24:04 +00003346 }
3347
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003348 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00003349 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003350 // We found a real definition for this type elsewhere
3351 // so lets use it and cache the fact that we found
3352 // a complete type for this die
3353 m_die_to_type[die] = type_sp.get();
3354 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00003355 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003356 }
3357 assert (tag_decl_kind != -1);
3358 bool clang_type_was_created = false;
3359 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3360 if (clang_type == NULL)
3361 {
3362 clang_type_was_created = true;
3363 clang_type = ast.CreateRecordType (type_name_cstr,
3364 tag_decl_kind,
Sean Callanan72e49402011-08-05 23:43:37 +00003365 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003366 class_language);
3367 }
3368
3369 // Store a forward declaration to this class type in case any
3370 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00003371 // types for function prototypes.
3372 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003373 type_sp.reset (new Type (die->GetOffset(),
3374 this,
3375 type_name_const_str,
3376 byte_size,
3377 NULL,
3378 LLDB_INVALID_UID,
3379 Type::eEncodingIsUID,
3380 &decl,
3381 clang_type,
3382 Type::eResolveStateForward));
3383
3384
3385 // Add our type to the unique type map so we don't
3386 // end up creating many copies of the same type over
3387 // and over in the ASTContext for our module
3388 unique_ast_entry.m_type_sp = type_sp;
Greg Clayton36909642011-03-15 04:38:20 +00003389 unique_ast_entry.m_symfile = this;
3390 unique_ast_entry.m_cu = dwarf_cu;
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003391 unique_ast_entry.m_die = die;
3392 unique_ast_entry.m_declaration = decl;
Greg Claytone576ab22011-02-15 00:19:15 +00003393 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
3394 unique_ast_entry);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003395
3396 if (die->HasChildren() == false && is_forward_declaration == false)
3397 {
3398 // No children for this struct/union/class, lets finish it
3399 ast.StartTagDeclarationDefinition (clang_type);
3400 ast.CompleteTagDeclarationDefinition (clang_type);
3401 }
3402 else if (clang_type_was_created)
3403 {
3404 // Leave this as a forward declaration until we need
3405 // to know the details of the type. lldb_private::Type
3406 // will automatically call the SymbolFile virtual function
3407 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3408 // When the definition needs to be defined.
3409 m_forward_decl_die_to_clang_type[die] = clang_type;
3410 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3411 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Claytonc615ce42010-11-09 04:42:43 +00003412 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003413 }
3414 break;
3415
3416 case DW_TAG_enumeration_type:
3417 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003418 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003419 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003420
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003421 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003422
Greg Claytond88d7592010-09-15 08:33:30 +00003423 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003424 if (num_attributes > 0)
3425 {
3426 uint32_t i;
3427
3428 for (i=0; i<num_attributes; ++i)
3429 {
3430 attr = attributes.AttributeAtIndex(i);
3431 DWARFFormValue form_value;
3432 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3433 {
3434 switch (attr)
3435 {
Greg Clayton7a345282010-11-09 23:46:37 +00003436 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3437 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3438 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003439 case DW_AT_name:
3440 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003441 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003442 break;
Greg Clayton7a345282010-11-09 23:46:37 +00003443 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00003444 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Greg Clayton7a345282010-11-09 23:46:37 +00003445 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3446 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003447 case DW_AT_allocated:
3448 case DW_AT_associated:
3449 case DW_AT_bit_stride:
3450 case DW_AT_byte_stride:
3451 case DW_AT_data_location:
3452 case DW_AT_description:
3453 case DW_AT_start_scope:
3454 case DW_AT_visibility:
3455 case DW_AT_specification:
3456 case DW_AT_abstract_origin:
3457 case DW_AT_sibling:
3458 break;
3459 }
3460 }
3461 }
3462
Greg Claytonc93237c2010-10-01 20:48:32 +00003463 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3464
Greg Clayton1be10fc2010-09-29 01:12:09 +00003465 clang_type_t enumerator_clang_type = NULL;
3466 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3467 if (clang_type == NULL)
3468 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003469 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3470 DW_ATE_signed,
3471 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00003472 clang_type = ast.CreateEnumerationType (type_name_cstr,
Sean Callanan72e49402011-08-05 23:43:37 +00003473 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Claytonca512b32011-01-14 04:54:56 +00003474 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003475 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00003476 }
3477 else
3478 {
3479 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3480 assert (enumerator_clang_type != NULL);
3481 }
3482
Greg Claytona2721472011-06-25 00:44:06 +00003483 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
3484
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003485 type_sp.reset( new Type (die->GetOffset(),
3486 this,
3487 type_name_const_str,
3488 byte_size,
3489 NULL,
3490 encoding_uid,
3491 Type::eEncodingIsUID,
3492 &decl,
3493 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003494 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003495
Greg Clayton6beaaa62011-01-17 03:46:26 +00003496#if LEAVE_ENUMS_FORWARD_DECLARED
Greg Clayton1be10fc2010-09-29 01:12:09 +00003497 // Leave this as a forward declaration until we need
3498 // to know the details of the type. lldb_private::Type
3499 // will automatically call the SymbolFile virtual function
3500 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3501 // When the definition needs to be defined.
3502 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonc93237c2010-10-01 20:48:32 +00003503 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Clayton6beaaa62011-01-17 03:46:26 +00003504 ClangASTContext::SetHasExternalStorage (clang_type, true);
3505#else
3506 ast.StartTagDeclarationDefinition (clang_type);
3507 if (die->HasChildren())
3508 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003509 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3510 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00003511 }
3512 ast.CompleteTagDeclarationDefinition (clang_type);
3513#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003514 }
3515 }
3516 break;
3517
Jim Inghamb0be4422010-08-12 01:20:14 +00003518 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003519 case DW_TAG_subprogram:
3520 case DW_TAG_subroutine_type:
3521 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003522 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003523 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003524
3525 const char *mangled = NULL;
3526 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003527 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003528 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003529 bool is_static = false;
3530 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00003531 bool is_explicit = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00003532
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003533 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00003534 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003535
3536
Greg Claytond88d7592010-09-15 08:33:30 +00003537 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003538 if (num_attributes > 0)
3539 {
3540 uint32_t i;
3541 for (i=0; i<num_attributes; ++i)
3542 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00003543 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003544 DWARFFormValue form_value;
3545 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3546 {
3547 switch (attr)
3548 {
3549 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3550 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3551 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3552 case DW_AT_name:
3553 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003554 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003555 break;
3556
3557 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3558 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003559 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003560 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003561 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3562 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00003563 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3564
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003565 case DW_AT_external:
3566 if (form_value.Unsigned())
3567 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00003568 if (storage == clang::SC_None)
3569 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003570 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00003571 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003572 }
3573 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003574
3575 case DW_AT_allocated:
3576 case DW_AT_associated:
3577 case DW_AT_address_class:
3578 case DW_AT_artificial:
3579 case DW_AT_calling_convention:
3580 case DW_AT_data_location:
3581 case DW_AT_elemental:
3582 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003583 case DW_AT_frame_base:
3584 case DW_AT_high_pc:
3585 case DW_AT_low_pc:
3586 case DW_AT_object_pointer:
3587 case DW_AT_prototyped:
3588 case DW_AT_pure:
3589 case DW_AT_ranges:
3590 case DW_AT_recursive:
3591 case DW_AT_return_addr:
3592 case DW_AT_segment:
3593 case DW_AT_specification:
3594 case DW_AT_start_scope:
3595 case DW_AT_static_link:
3596 case DW_AT_trampoline:
3597 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003598 case DW_AT_vtable_elem_location:
3599 case DW_AT_abstract_origin:
3600 case DW_AT_description:
3601 case DW_AT_sibling:
3602 break;
3603 }
3604 }
3605 }
Greg Clayton24739922010-10-13 03:15:28 +00003606 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003607
Greg Clayton24739922010-10-13 03:15:28 +00003608 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 +00003609
Greg Clayton24739922010-10-13 03:15:28 +00003610 clang_type_t return_clang_type = NULL;
3611 Type *func_type = NULL;
3612
3613 if (type_die_offset != DW_INVALID_OFFSET)
3614 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00003615
Greg Clayton24739922010-10-13 03:15:28 +00003616 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00003617 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00003618 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003619 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003620
Greg Claytonf51de672010-10-01 02:31:07 +00003621
Greg Clayton24739922010-10-13 03:15:28 +00003622 std::vector<clang_type_t> function_param_types;
3623 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003624
Greg Clayton24739922010-10-13 03:15:28 +00003625 // Parse the function children for the parameters
Sean Callanan763d72a2011-08-02 22:21:50 +00003626
Greg Clayton5113dc82011-08-12 06:47:54 +00003627 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die);
3628 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
3629
3630 const bool is_cxx_method = containing_decl_kind == clang::Decl::CXXRecord;
3631 // Start off static. This will be set to false in ParseChildParameters(...)
3632 // if we find a "this" paramters as the first parameter
3633 if (is_cxx_method)
Sean Callanan763d72a2011-08-02 22:21:50 +00003634 is_static = true;
3635
Greg Clayton24739922010-10-13 03:15:28 +00003636 if (die->HasChildren())
3637 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003638 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003639 ParseChildParameters (sc,
Greg Clayton5113dc82011-08-12 06:47:54 +00003640 containing_decl_ctx,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003641 type_sp,
3642 dwarf_cu,
3643 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00003644 skip_artificial,
3645 is_static,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003646 type_list,
3647 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00003648 function_param_decls,
3649 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00003650 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003651
Greg Clayton24739922010-10-13 03:15:28 +00003652 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003653 clang_type = ast.CreateFunctionType (return_clang_type,
3654 &function_param_types[0],
3655 function_param_types.size(),
3656 is_variadic,
3657 type_quals);
3658
Greg Clayton24739922010-10-13 03:15:28 +00003659 if (type_name_cstr)
3660 {
3661 bool type_handled = false;
Greg Clayton24739922010-10-13 03:15:28 +00003662 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003663 {
Greg Clayton24739922010-10-13 03:15:28 +00003664 if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
Greg Clayton0fffff52010-09-24 05:15:53 +00003665 {
Greg Clayton24739922010-10-13 03:15:28 +00003666 // We need to find the DW_TAG_class_type or
3667 // DW_TAG_struct_type by name so we can add this
3668 // as a member function of the class.
3669 const char *class_name_start = type_name_cstr + 2;
3670 const char *class_name_end = ::strchr (class_name_start, ' ');
3671 SymbolContext empty_sc;
3672 clang_type_t class_opaque_type = NULL;
3673 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00003674 {
Greg Clayton24739922010-10-13 03:15:28 +00003675 ConstString class_name (class_name_start, class_name_end - class_name_start);
3676 TypeList types;
3677 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3678 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00003679 {
Greg Clayton24739922010-10-13 03:15:28 +00003680 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00003681 {
Greg Clayton24739922010-10-13 03:15:28 +00003682 Type *type = types.GetTypeAtIndex (i).get();
3683 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3684 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003685 {
Greg Clayton24739922010-10-13 03:15:28 +00003686 class_opaque_type = type_clang_forward_type;
3687 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00003688 }
3689 }
3690 }
Greg Clayton24739922010-10-13 03:15:28 +00003691 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003692
Greg Clayton24739922010-10-13 03:15:28 +00003693 if (class_opaque_type)
3694 {
3695 // If accessibility isn't set to anything valid, assume public for
3696 // now...
3697 if (accessibility == eAccessNone)
3698 accessibility = eAccessPublic;
3699
3700 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003701 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3702 type_name_cstr,
3703 clang_type,
3704 accessibility);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00003705 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Clayton24739922010-10-13 03:15:28 +00003706 type_handled = objc_method_decl != NULL;
3707 }
3708 }
Greg Clayton5113dc82011-08-12 06:47:54 +00003709 else if (is_cxx_method)
Greg Clayton24739922010-10-13 03:15:28 +00003710 {
3711 // Look at the parent of this DIE and see if is is
3712 // a class or struct and see if this is actually a
3713 // C++ method
Greg Clayton5113dc82011-08-12 06:47:54 +00003714 Type *class_type = ResolveType (dwarf_cu, m_decl_ctx_to_die[containing_decl_ctx]);
Greg Clayton24739922010-10-13 03:15:28 +00003715 if (class_type)
3716 {
3717 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3718 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00003719 {
Greg Clayton24739922010-10-13 03:15:28 +00003720 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3721 // in the DWARF for C++ methods... Default to public for now...
Greg Clayton6d01ad92010-09-29 01:57:37 +00003722 if (accessibility == eAccessNone)
3723 accessibility = eAccessPublic;
Greg Clayton931180e2011-01-27 06:44:37 +00003724
3725 if (!is_static && !die->HasChildren())
3726 {
3727 // We have a C++ member function with no children (this pointer!)
3728 // and clang will get mad if we try and make a function that isn't
3729 // well formed in the DWARF, so we will just skip it...
3730 type_handled = true;
3731 }
3732 else
3733 {
3734 clang::CXXMethodDecl *cxx_method_decl;
3735 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3736 type_name_cstr,
3737 clang_type,
3738 accessibility,
3739 is_virtual,
3740 is_static,
3741 is_inline,
3742 is_explicit);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00003743 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
3744
Greg Clayton931180e2011-01-27 06:44:37 +00003745 type_handled = cxx_method_decl != NULL;
3746 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003747 }
3748 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003749 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003750 }
Greg Clayton24739922010-10-13 03:15:28 +00003751
3752 if (!type_handled)
3753 {
3754 // We just have a function that isn't part of a class
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003755 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3756 clang_type,
3757 storage,
3758 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00003759
3760 // Add the decl to our DIE to decl context map
3761 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00003762 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00003763 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003764 ast.SetFunctionParameters (function_decl,
3765 &function_param_decls.front(),
3766 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00003767 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003768 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003769 type_sp.reset( new Type (die->GetOffset(),
3770 this,
3771 type_name_const_str,
3772 0,
3773 NULL,
3774 LLDB_INVALID_UID,
3775 Type::eEncodingIsUID,
3776 &decl,
3777 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003778 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00003779 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003780 }
3781 break;
3782
3783 case DW_TAG_array_type:
3784 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003786 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003787
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003788 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003789 int64_t first_index = 0;
3790 uint32_t byte_stride = 0;
3791 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00003792 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003793
3794 if (num_attributes > 0)
3795 {
3796 uint32_t i;
3797 for (i=0; i<num_attributes; ++i)
3798 {
3799 attr = attributes.AttributeAtIndex(i);
3800 DWARFFormValue form_value;
3801 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3802 {
3803 switch (attr)
3804 {
3805 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3806 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3807 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3808 case DW_AT_name:
3809 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003810 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003811 break;
3812
3813 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00003814 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003815 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3816 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00003817 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00003818 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003819 case DW_AT_allocated:
3820 case DW_AT_associated:
3821 case DW_AT_data_location:
3822 case DW_AT_description:
3823 case DW_AT_ordering:
3824 case DW_AT_start_scope:
3825 case DW_AT_visibility:
3826 case DW_AT_specification:
3827 case DW_AT_abstract_origin:
3828 case DW_AT_sibling:
3829 break;
3830 }
3831 }
3832 }
3833
Greg Claytonc93237c2010-10-01 20:48:32 +00003834 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3835
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003836 Type *element_type = ResolveTypeUID(type_die_offset);
3837
3838 if (element_type)
3839 {
3840 std::vector<uint64_t> element_orders;
3841 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00003842 // We have an array that claims to have no members, lets give it at least one member...
3843 if (element_orders.empty())
3844 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003845 if (byte_stride == 0 && bit_stride == 0)
3846 byte_stride = element_type->GetByteSize();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00003847 clang_type_t array_element_type = element_type->GetClangFullType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003848 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3849 uint64_t num_elements = 0;
3850 std::vector<uint64_t>::const_reverse_iterator pos;
3851 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3852 for (pos = element_orders.rbegin(); pos != end; ++pos)
3853 {
3854 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003855 clang_type = ast.CreateArrayType (array_element_type,
3856 num_elements,
3857 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003858 array_element_type = clang_type;
3859 array_element_bit_stride = array_element_bit_stride * num_elements;
3860 }
3861 ConstString empty_name;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003862 type_sp.reset( new Type (die->GetOffset(),
3863 this,
3864 empty_name,
3865 array_element_bit_stride / 8,
3866 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00003867 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003868 Type::eEncodingIsUID,
3869 &decl,
3870 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003871 Type::eResolveStateFull));
3872 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003873 }
3874 }
3875 }
3876 break;
3877
Greg Clayton9b81a312010-06-12 01:20:30 +00003878 case DW_TAG_ptr_to_member_type:
3879 {
3880 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3881 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3882
Greg Claytond88d7592010-09-15 08:33:30 +00003883 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00003884
3885 if (num_attributes > 0) {
3886 uint32_t i;
3887 for (i=0; i<num_attributes; ++i)
3888 {
3889 attr = attributes.AttributeAtIndex(i);
3890 DWARFFormValue form_value;
3891 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3892 {
3893 switch (attr)
3894 {
3895 case DW_AT_type:
3896 type_die_offset = form_value.Reference(dwarf_cu); break;
3897 case DW_AT_containing_type:
3898 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3899 }
3900 }
3901 }
3902
3903 Type *pointee_type = ResolveTypeUID(type_die_offset);
3904 Type *class_type = ResolveTypeUID(containing_type_die_offset);
3905
Greg Clayton526e5af2010-11-13 03:52:47 +00003906 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
3907 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00003908
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003909 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3910 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00003911
Greg Clayton526e5af2010-11-13 03:52:47 +00003912 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3913 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00003914
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003915 type_sp.reset( new Type (die->GetOffset(),
3916 this,
3917 type_name_const_str,
3918 byte_size,
3919 NULL,
3920 LLDB_INVALID_UID,
3921 Type::eEncodingIsUID,
3922 NULL,
3923 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003924 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00003925 }
3926
3927 break;
3928 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003929 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00003930 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003931 break;
3932 }
3933
3934 if (type_sp.get())
3935 {
3936 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3937 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3938
3939 SymbolContextScope * symbol_context_scope = NULL;
3940 if (sc_parent_tag == DW_TAG_compile_unit)
3941 {
3942 symbol_context_scope = sc.comp_unit;
3943 }
3944 else if (sc.function != NULL)
3945 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00003946 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003947 if (symbol_context_scope == NULL)
3948 symbol_context_scope = sc.function;
3949 }
3950
3951 if (symbol_context_scope != NULL)
3952 {
3953 type_sp->SetSymbolContextScope(symbol_context_scope);
3954 }
3955
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003956 // We are ready to put this type into the uniqued list up at the module level
3957 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00003958
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003959 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003960 }
3961 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00003962 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003963 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003964 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003965 }
3966 }
3967 return type_sp;
3968}
3969
3970size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00003971SymbolFileDWARF::ParseTypes
3972(
3973 const SymbolContext& sc,
3974 DWARFCompileUnit* dwarf_cu,
3975 const DWARFDebugInfoEntry *die,
3976 bool parse_siblings,
3977 bool parse_children
3978)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003979{
3980 size_t types_added = 0;
3981 while (die != NULL)
3982 {
3983 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003984 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003985 {
3986 if (type_is_new)
3987 ++types_added;
3988 }
3989
3990 if (parse_children && die->HasChildren())
3991 {
3992 if (die->Tag() == DW_TAG_subprogram)
3993 {
3994 SymbolContext child_sc(sc);
3995 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3996 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3997 }
3998 else
3999 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
4000 }
4001
4002 if (parse_siblings)
4003 die = die->GetSibling();
4004 else
4005 die = NULL;
4006 }
4007 return types_added;
4008}
4009
4010
4011size_t
4012SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
4013{
4014 assert(sc.comp_unit && sc.function);
4015 size_t functions_added = 0;
4016 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4017 if (dwarf_cu)
4018 {
4019 dw_offset_t function_die_offset = sc.function->GetID();
4020 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
4021 if (function_die)
4022 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004023 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004024 }
4025 }
4026
4027 return functions_added;
4028}
4029
4030
4031size_t
4032SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
4033{
4034 // At least a compile unit must be valid
4035 assert(sc.comp_unit);
4036 size_t types_added = 0;
4037 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4038 if (dwarf_cu)
4039 {
4040 if (sc.function)
4041 {
4042 dw_offset_t function_die_offset = sc.function->GetID();
4043 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
4044 if (func_die && func_die->HasChildren())
4045 {
4046 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
4047 }
4048 }
4049 else
4050 {
4051 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
4052 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
4053 {
4054 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
4055 }
4056 }
4057 }
4058
4059 return types_added;
4060}
4061
4062size_t
4063SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4064{
4065 if (sc.comp_unit != NULL)
4066 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00004067 DWARFDebugInfo* info = DebugInfo();
4068 if (info == NULL)
4069 return 0;
4070
4071 uint32_t cu_idx = UINT32_MAX;
4072 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004073
4074 if (dwarf_cu == NULL)
4075 return 0;
4076
4077 if (sc.function)
4078 {
4079 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00004080
4081 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4082 assert (func_lo_pc != DW_INVALID_ADDRESS);
4083
Greg Claytonc662ec82011-06-17 22:10:16 +00004084 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4085
4086 // Let all blocks know they have parse all their variables
4087 sc.function->GetBlock (false).SetDidParseVariables (true, true);
4088
4089 return num_variables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004090 }
4091 else if (sc.comp_unit)
4092 {
4093 uint32_t vars_added = 0;
4094 VariableListSP variables (sc.comp_unit->GetVariableList(false));
4095
4096 if (variables.get() == NULL)
4097 {
4098 variables.reset(new VariableList());
4099 sc.comp_unit->SetVariableList(variables);
4100
4101 // Index if we already haven't to make sure the compile units
4102 // get indexed and make their global DIE index list
4103 if (!m_indexed)
4104 Index ();
4105
Greg Claytonc685f8e2010-09-15 04:15:46 +00004106 std::vector<NameToDIE::Info> global_die_info_array;
Greg Clayton4b3dc102010-11-01 20:32:12 +00004107 const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004108 for (size_t idx=0; idx<num_globals; ++idx)
4109 {
Greg Claytonc685f8e2010-09-15 04:15:46 +00004110 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 +00004111 if (var_sp)
4112 {
Greg Clayton83c5cd92010-11-14 22:13:40 +00004113 variables->AddVariableIfUnique (var_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004114 ++vars_added;
4115 }
4116 }
4117 }
4118 return vars_added;
4119 }
4120 }
4121 return 0;
4122}
4123
4124
4125VariableSP
4126SymbolFileDWARF::ParseVariableDIE
4127(
4128 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004129 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004130 const DWARFDebugInfoEntry *die,
4131 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004132)
4133{
4134
Greg Clayton83c5cd92010-11-14 22:13:40 +00004135 VariableSP var_sp (m_die_to_variable_sp[die]);
4136 if (var_sp)
4137 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004138
4139 const dw_tag_t tag = die->Tag();
4140 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00004141 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004142 if (num_attributes > 0)
4143 {
4144 const char *name = NULL;
Greg Claytona134cc12010-09-13 02:37:44 +00004145 const char *mangled = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004146 Declaration decl;
4147 uint32_t i;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004148 Type *var_type = NULL;
4149 DWARFExpression location;
4150 bool is_external = false;
4151 bool is_artificial = false;
Greg Clayton007d5be2011-05-30 00:49:24 +00004152 bool location_is_const_value_data = false;
Sean Callananc7fbf732010-08-06 00:32:49 +00004153 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004154
4155 for (i=0; i<num_attributes; ++i)
4156 {
4157 dw_attr_t attr = attributes.AttributeAtIndex(i);
4158 DWARFFormValue form_value;
4159 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4160 {
4161 switch (attr)
4162 {
4163 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4164 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4165 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4166 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytona134cc12010-09-13 02:37:44 +00004167 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton594e5ed2010-09-27 21:07:38 +00004168 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004169 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
Greg Clayton007d5be2011-05-30 00:49:24 +00004170 case DW_AT_const_value:
4171 location_is_const_value_data = true;
4172 // Fall through...
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004173 case DW_AT_location:
4174 {
4175 if (form_value.BlockData())
4176 {
4177 const DataExtractor& debug_info_data = get_debug_info_data();
4178
4179 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4180 uint32_t block_length = form_value.Unsigned();
Greg Clayton016a95e2010-09-14 02:20:48 +00004181 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004182 }
4183 else
4184 {
4185 const DataExtractor& debug_loc_data = get_debug_loc_data();
4186 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4187
4188 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4189 if (loc_list_length > 0)
4190 {
Greg Clayton016a95e2010-09-14 02:20:48 +00004191 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4192 assert (func_low_pc != LLDB_INVALID_ADDRESS);
4193 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004194 }
4195 }
4196 }
4197 break;
4198
4199 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004200 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004201 case DW_AT_declaration:
4202 case DW_AT_description:
4203 case DW_AT_endianity:
4204 case DW_AT_segment:
4205 case DW_AT_start_scope:
4206 case DW_AT_visibility:
4207 default:
4208 case DW_AT_abstract_origin:
4209 case DW_AT_sibling:
4210 case DW_AT_specification:
4211 break;
4212 }
4213 }
4214 }
4215
4216 if (location.IsValid())
4217 {
4218 assert(var_type != DIE_IS_BEING_PARSED);
4219
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004220 ValueType scope = eValueTypeInvalid;
4221
4222 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4223 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4224
4225 if (tag == DW_TAG_formal_parameter)
4226 scope = eValueTypeVariableArgument;
4227 else if (is_external || parent_tag == DW_TAG_compile_unit)
4228 scope = eValueTypeVariableGlobal;
4229 else
4230 scope = eValueTypeVariableLocal;
4231
4232 SymbolContextScope * symbol_context_scope = NULL;
4233 if (parent_tag == DW_TAG_compile_unit)
4234 {
4235 symbol_context_scope = sc.comp_unit;
4236 }
4237 else if (sc.function != NULL)
4238 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00004239 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004240 if (symbol_context_scope == NULL)
4241 symbol_context_scope = sc.function;
4242 }
4243
4244 assert(symbol_context_scope != NULL);
4245 var_sp.reset (new Variable(die->GetOffset(),
Greg Clayton83c5cd92010-11-14 22:13:40 +00004246 name,
4247 mangled,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004248 var_type,
4249 scope,
4250 symbol_context_scope,
4251 &decl,
4252 location,
4253 is_external,
4254 is_artificial));
Greg Clayton594e5ed2010-09-27 21:07:38 +00004255
Greg Clayton007d5be2011-05-30 00:49:24 +00004256 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004257 }
4258 }
Greg Clayton83c5cd92010-11-14 22:13:40 +00004259 // Cache var_sp even if NULL (the variable was just a specification or
4260 // was missing vital information to be able to be displayed in the debugger
4261 // (missing location due to optimization, etc)) so we don't re-parse
4262 // this DIE over and over later...
4263 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004264 return var_sp;
4265}
4266
Greg Claytonc662ec82011-06-17 22:10:16 +00004267
4268const DWARFDebugInfoEntry *
4269SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
4270 dw_offset_t spec_block_die_offset,
4271 DWARFCompileUnit **result_die_cu_handle)
4272{
4273 // Give the concrete function die specified by "func_die_offset", find the
4274 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4275 // to "spec_block_die_offset"
4276 DWARFDebugInfo* info = DebugInfo();
4277
4278 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
4279 if (die)
4280 {
4281 assert (*result_die_cu_handle);
4282 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
4283 }
4284 return NULL;
4285}
4286
4287
4288const DWARFDebugInfoEntry *
4289SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
4290 const DWARFDebugInfoEntry *die,
4291 dw_offset_t spec_block_die_offset,
4292 DWARFCompileUnit **result_die_cu_handle)
4293{
4294 if (die)
4295 {
4296 switch (die->Tag())
4297 {
4298 case DW_TAG_subprogram:
4299 case DW_TAG_inlined_subroutine:
4300 case DW_TAG_lexical_block:
4301 {
4302 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4303 {
4304 *result_die_cu_handle = dwarf_cu;
4305 return die;
4306 }
4307
4308 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4309 {
4310 *result_die_cu_handle = dwarf_cu;
4311 return die;
4312 }
4313 }
4314 break;
4315 }
4316
4317 // Give the concrete function die specified by "func_die_offset", find the
4318 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4319 // to "spec_block_die_offset"
4320 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
4321 {
4322 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
4323 child_die,
4324 spec_block_die_offset,
4325 result_die_cu_handle);
4326 if (result_die)
4327 return result_die;
4328 }
4329 }
4330
4331 *result_die_cu_handle = NULL;
4332 return NULL;
4333}
4334
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004335size_t
4336SymbolFileDWARF::ParseVariables
4337(
4338 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004339 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004340 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004341 const DWARFDebugInfoEntry *orig_die,
4342 bool parse_siblings,
4343 bool parse_children,
4344 VariableList* cc_variable_list
4345)
4346{
4347 if (orig_die == NULL)
4348 return 0;
4349
Greg Claytonc662ec82011-06-17 22:10:16 +00004350 VariableListSP variable_list_sp;
4351
4352 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004353 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00004354 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004355 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004356 dw_tag_t tag = die->Tag();
4357
4358 // Check to see if we have already parsed this variable or constant?
4359 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004360 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004361 if (cc_variable_list)
4362 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004363 }
4364 else
4365 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004366 // We haven't already parsed it, lets do that now.
4367 if ((tag == DW_TAG_variable) ||
4368 (tag == DW_TAG_constant) ||
4369 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004370 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004371 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00004372 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004373 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4374 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4375 switch (parent_tag)
4376 {
4377 case DW_TAG_compile_unit:
4378 if (sc.comp_unit != NULL)
4379 {
4380 variable_list_sp = sc.comp_unit->GetVariableList(false);
4381 if (variable_list_sp.get() == NULL)
4382 {
4383 variable_list_sp.reset(new VariableList());
4384 sc.comp_unit->SetVariableList(variable_list_sp);
4385 }
4386 }
4387 else
4388 {
4389 fprintf (stderr,
4390 "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
4391 sc_parent_die->GetOffset(),
4392 DW_TAG_value_to_name (parent_tag),
4393 orig_die->GetOffset(),
4394 DW_TAG_value_to_name (orig_die->Tag()));
4395 }
4396 break;
4397
4398 case DW_TAG_subprogram:
4399 case DW_TAG_inlined_subroutine:
4400 case DW_TAG_lexical_block:
4401 if (sc.function != NULL)
4402 {
4403 // Check to see if we already have parsed the variables for the given scope
4404
4405 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4406 if (block == NULL)
4407 {
4408 // This must be a specification or abstract origin with
4409 // a concrete block couterpart in the current function. We need
4410 // to find the concrete block so we can correctly add the
4411 // variable to it
4412 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
4413 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
4414 sc_parent_die->GetOffset(),
4415 &concrete_block_die_cu);
4416 if (concrete_block_die)
4417 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset());
4418 }
4419
4420 if (block != NULL)
4421 {
4422 const bool can_create = false;
4423 variable_list_sp = block->GetBlockVariableList (can_create);
4424 if (variable_list_sp.get() == NULL)
4425 {
4426 variable_list_sp.reset(new VariableList());
4427 block->SetVariableList(variable_list_sp);
4428 }
4429 }
4430 }
4431 break;
4432
4433 default:
4434 fprintf (stderr,
4435 "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
4436 orig_die->GetOffset(),
4437 DW_TAG_value_to_name (orig_die->Tag()));
4438 break;
4439 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00004440 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004441
4442 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004443 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00004444 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
4445 if (var_sp)
4446 {
Greg Claytonc662ec82011-06-17 22:10:16 +00004447 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00004448 if (cc_variable_list)
4449 cc_variable_list->AddVariableIfUnique (var_sp);
4450 ++vars_added;
4451 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004452 }
4453 }
4454 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004455
4456 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4457
4458 if (!skip_children && parse_children && die->HasChildren())
4459 {
4460 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
4461 }
4462
4463 if (parse_siblings)
4464 die = die->GetSibling();
4465 else
4466 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004467 }
Greg Claytonc662ec82011-06-17 22:10:16 +00004468 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004469}
4470
4471//------------------------------------------------------------------
4472// PluginInterface protocol
4473//------------------------------------------------------------------
4474const char *
4475SymbolFileDWARF::GetPluginName()
4476{
4477 return "SymbolFileDWARF";
4478}
4479
4480const char *
4481SymbolFileDWARF::GetShortPluginName()
4482{
4483 return GetPluginNameStatic();
4484}
4485
4486uint32_t
4487SymbolFileDWARF::GetPluginVersion()
4488{
4489 return 1;
4490}
4491
4492void
Greg Clayton6beaaa62011-01-17 03:46:26 +00004493SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4494{
4495 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4496 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4497 if (clang_type)
4498 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4499}
4500
4501void
4502SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4503{
4504 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4505 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4506 if (clang_type)
4507 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4508}
4509
Greg Claytona2721472011-06-25 00:44:06 +00004510void
Sean Callanancc427fa2011-07-30 02:42:06 +00004511SymbolFileDWARF::DumpIndexes ()
4512{
4513 StreamFile s(stdout, false);
4514
4515 s.Printf ("DWARF index for (%s) '%s/%s':",
4516 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4517 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
4518 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
4519 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
4520 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
4521 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
4522 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
4523 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
4524 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
4525 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
4526 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
4527}
4528
4529void
4530SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
4531 const char *name,
4532 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00004533{
Sean Callanancc427fa2011-07-30 02:42:06 +00004534 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00004535
4536 if (iter == m_decl_ctx_to_die.end())
4537 return;
4538
Sean Callanancc427fa2011-07-30 02:42:06 +00004539 const DWARFDebugInfoEntry *context_die = iter->second;
Greg Claytona2721472011-06-25 00:44:06 +00004540
4541 if (!results)
4542 return;
4543
4544 DWARFDebugInfo* info = DebugInfo();
4545
4546 std::vector<NameToDIE::Info> die_info_array;
4547
Greg Clayton1d4313b2011-07-07 04:49:07 +00004548 size_t num_matches = m_type_index.Find (ConstString(name), die_info_array);
Greg Claytona2721472011-06-25 00:44:06 +00004549
4550 if (num_matches)
4551 {
4552 for (int i = 0;
4553 i < num_matches;
4554 ++i)
4555 {
4556 DWARFCompileUnit* compile_unit = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
4557 compile_unit->ExtractDIEsIfNeeded (false);
4558 const DWARFDebugInfoEntry *die = compile_unit->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
4559
Sean Callanancc427fa2011-07-30 02:42:06 +00004560 if (die->GetParent() != context_die)
Greg Claytona2721472011-06-25 00:44:06 +00004561 continue;
4562
4563 Type *matching_type = ResolveType (compile_unit, die);
4564
4565 lldb::clang_type_t type = matching_type->GetClangFullType();
4566 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
4567
Sean Callanancc427fa2011-07-30 02:42:06 +00004568 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00004569 {
4570 clang::TagDecl *tag_decl = tag_type->getDecl();
4571 results->push_back(tag_decl);
4572 }
Sean Callanancc427fa2011-07-30 02:42:06 +00004573 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
Greg Claytona2721472011-06-25 00:44:06 +00004574 {
4575 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
4576 results->push_back(typedef_decl);
4577 }
4578 }
4579 }
4580}
4581
4582void
4583SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
4584 const clang::DeclContext *DC,
4585 clang::DeclarationName Name,
4586 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
4587{
4588 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4589
Sean Callanancc427fa2011-07-30 02:42:06 +00004590 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results);
Greg Claytona2721472011-06-25 00:44:06 +00004591}