blob: 535c9103c7e07a989859e1edae66e8bdd915d084 [file] [log] [blame]
Chris Lattner24943d22010-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 Clayton2403b5e2010-11-16 02:10:54 +000023#include "clang/Sema/DeclSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024
Sean Callanan9b6898f2011-07-30 02:42:06 +000025#include "llvm/Support/Casting.h"
26
Chris Lattner24943d22010-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 Clayton74124752010-09-15 04:15:46 +000032#include "lldb/Core/StreamFile.h"
Jim Ingham54548922011-08-26 19:44:13 +000033#include "lldb/Core/StreamString.h"
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Core/Timer.h"
35#include "lldb/Core/Value.h"
36
37#include "lldb/Symbol/Block.h"
Greg Claytonb01000f2011-01-17 03:46:26 +000038#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner24943d22010-06-08 16:52:24 +000039#include "lldb/Symbol/CompileUnit.h"
40#include "lldb/Symbol/LineTable.h"
41#include "lldb/Symbol/ObjectFile.h"
42#include "lldb/Symbol/SymbolVendor.h"
43#include "lldb/Symbol/VariableList.h"
44
Jim Inghamfdf24ef2011-09-08 22:13:49 +000045#include "lldb/Target/ObjCLanguageRuntime.h"
46
Chris Lattner24943d22010-06-08 16:52:24 +000047#include "DWARFCompileUnit.h"
48#include "DWARFDebugAbbrev.h"
49#include "DWARFDebugAranges.h"
50#include "DWARFDebugInfo.h"
51#include "DWARFDebugInfoEntry.h"
52#include "DWARFDebugLine.h"
53#include "DWARFDebugPubnames.h"
54#include "DWARFDebugRanges.h"
55#include "DWARFDIECollection.h"
56#include "DWARFFormValue.h"
57#include "DWARFLocationList.h"
58#include "LogChannelDWARF.h"
Greg Claytonad60bf42010-10-12 02:24:53 +000059#include "SymbolFileDWARFDebugMap.h"
Chris Lattner24943d22010-06-08 16:52:24 +000060
61#include <map>
62
Greg Clayton07c55d12010-11-11 01:09:45 +000063//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonb433a3d2010-10-01 20:48:32 +000064
65#ifdef ENABLE_DEBUG_PRINTF
66#include <stdio.h>
67#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
68#else
69#define DEBUG_PRINTF(fmt, ...)
70#endif
71
Greg Clayton4fb400f2010-09-27 21:07:38 +000072#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner24943d22010-06-08 16:52:24 +000073
74using namespace lldb;
75using namespace lldb_private;
76
77
Sean Callanan70a4f922010-08-06 00:32:49 +000078static AccessType
Greg Clayton84f80752010-07-22 18:30:50 +000079DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner24943d22010-06-08 16:52:24 +000080{
81 switch (dwarf_accessibility)
82 {
Sean Callanan70a4f922010-08-06 00:32:49 +000083 case DW_ACCESS_public: return eAccessPublic;
84 case DW_ACCESS_private: return eAccessPrivate;
85 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton84f80752010-07-22 18:30:50 +000086 default: break;
Chris Lattner24943d22010-06-08 16:52:24 +000087 }
Sean Callanan70a4f922010-08-06 00:32:49 +000088 return eAccessNone;
Chris Lattner24943d22010-06-08 16:52:24 +000089}
90
91void
92SymbolFileDWARF::Initialize()
93{
94 LogChannelDWARF::Initialize();
95 PluginManager::RegisterPlugin (GetPluginNameStatic(),
96 GetPluginDescriptionStatic(),
97 CreateInstance);
98}
99
100void
101SymbolFileDWARF::Terminate()
102{
103 PluginManager::UnregisterPlugin (CreateInstance);
104 LogChannelDWARF::Initialize();
105}
106
107
108const char *
109SymbolFileDWARF::GetPluginNameStatic()
110{
Greg Clayton144188b2011-09-12 23:21:58 +0000111 return "dwarf";
Chris Lattner24943d22010-06-08 16:52:24 +0000112}
113
114const char *
115SymbolFileDWARF::GetPluginDescriptionStatic()
116{
117 return "DWARF and DWARF3 debug symbol file reader.";
118}
119
120
121SymbolFile*
122SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
123{
124 return new SymbolFileDWARF(obj_file);
125}
126
Greg Claytone98ac252010-11-10 04:57:04 +0000127TypeList *
128SymbolFileDWARF::GetTypeList ()
129{
130 if (m_debug_map_symfile)
131 return m_debug_map_symfile->GetTypeList();
132 return m_obj_file->GetModule()->GetTypeList();
133
134}
135
Chris Lattner24943d22010-06-08 16:52:24 +0000136//----------------------------------------------------------------------
137// Gets the first parent that is a lexical block, function or inlined
138// subroutine, or compile unit.
139//----------------------------------------------------------------------
140static const DWARFDebugInfoEntry *
141GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
142{
143 const DWARFDebugInfoEntry *die;
144 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
145 {
146 dw_tag_t tag = die->Tag();
147
148 switch (tag)
149 {
150 case DW_TAG_compile_unit:
151 case DW_TAG_subprogram:
152 case DW_TAG_inlined_subroutine:
153 case DW_TAG_lexical_block:
154 return die;
155 }
156 }
157 return NULL;
158}
159
160
Greg Claytonad60bf42010-10-12 02:24:53 +0000161SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
162 SymbolFile (objfile),
163 m_debug_map_symfile (NULL),
Greg Claytone5748d82010-11-09 23:46:37 +0000164 m_clang_tu_decl (NULL),
Chris Lattner24943d22010-06-08 16:52:24 +0000165 m_flags(),
Greg Clayton144188b2011-09-12 23:21:58 +0000166 m_data_debug_abbrev (),
167 m_data_debug_aranges (),
168 m_data_debug_frame (),
169 m_data_debug_info (),
170 m_data_debug_line (),
171 m_data_debug_loc (),
172 m_data_debug_ranges (),
173 m_data_debug_str (),
Greg Claytonf6e3de22011-09-28 17:06:40 +0000174 m_data_apple_names (),
175 m_data_apple_types (),
Chris Lattner24943d22010-06-08 16:52:24 +0000176 m_abbr(),
Chris Lattner24943d22010-06-08 16:52:24 +0000177 m_info(),
178 m_line(),
Greg Claytonf6e3de22011-09-28 17:06:40 +0000179 m_apple_names (this, m_data_apple_names, true),
Greg Clayton74124752010-09-15 04:15:46 +0000180 m_function_basename_index(),
181 m_function_fullname_index(),
182 m_function_method_index(),
183 m_function_selector_index(),
Greg Claytonad60bf42010-10-12 02:24:53 +0000184 m_objc_class_selectors_index(),
Greg Clayton74124752010-09-15 04:15:46 +0000185 m_global_index(),
Greg Claytonfcf06fb2010-10-15 02:03:22 +0000186 m_type_index(),
187 m_namespace_index(),
Greg Claytonb01000f2011-01-17 03:46:26 +0000188 m_indexed (false),
189 m_is_external_ast_source (false),
Greg Claytona8d42412011-02-09 19:06:17 +0000190 m_ranges(),
191 m_unique_ast_type_map ()
Chris Lattner24943d22010-06-08 16:52:24 +0000192{
Greg Claytonf6e3de22011-09-28 17:06:40 +0000193 get_apple_names_data();
194 m_apple_names.Initialize();
Chris Lattner24943d22010-06-08 16:52:24 +0000195}
196
197SymbolFileDWARF::~SymbolFileDWARF()
198{
Greg Claytonb01000f2011-01-17 03:46:26 +0000199 if (m_is_external_ast_source)
200 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
201}
202
203static const ConstString &
204GetDWARFMachOSegmentName ()
205{
206 static ConstString g_dwarf_section_name ("__DWARF");
207 return g_dwarf_section_name;
208}
209
Greg Claytonc3c46612011-02-15 00:19:15 +0000210UniqueDWARFASTTypeMap &
211SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
212{
213 if (m_debug_map_symfile)
214 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
215 return m_unique_ast_type_map;
216}
217
Greg Claytonb01000f2011-01-17 03:46:26 +0000218ClangASTContext &
219SymbolFileDWARF::GetClangASTContext ()
220{
221 if (m_debug_map_symfile)
222 return m_debug_map_symfile->GetClangASTContext ();
223
224 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
225 if (!m_is_external_ast_source)
226 {
227 m_is_external_ast_source = true;
228 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
229 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
230 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytone6d72ca2011-06-25 00:44:06 +0000231 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Claytonb01000f2011-01-17 03:46:26 +0000232 this));
233
234 ast.SetExternalSource (ast_source_ap);
235 }
236 return ast;
237}
238
239void
240SymbolFileDWARF::InitializeObject()
241{
242 // Install our external AST source callbacks so we can complete Clang types.
243 Module *module = m_obj_file->GetModule();
244 if (module)
245 {
246 const SectionList *section_list = m_obj_file->GetSectionList();
247
248 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
249
250 // Memory map the DWARF mach-o segment so we have everything mmap'ed
251 // to keep our heap memory usage down.
252 if (section)
253 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
254 }
Chris Lattner24943d22010-06-08 16:52:24 +0000255}
256
257bool
258SymbolFileDWARF::SupportedVersion(uint16_t version)
259{
260 return version == 2 || version == 3;
261}
262
263uint32_t
264SymbolFileDWARF::GetAbilities ()
265{
266 uint32_t abilities = 0;
267 if (m_obj_file != NULL)
268 {
269 const Section* section = NULL;
270 const SectionList *section_list = m_obj_file->GetSectionList();
271 if (section_list == NULL)
272 return 0;
273
274 uint64_t debug_abbrev_file_size = 0;
275 uint64_t debug_aranges_file_size = 0;
276 uint64_t debug_frame_file_size = 0;
277 uint64_t debug_info_file_size = 0;
278 uint64_t debug_line_file_size = 0;
279 uint64_t debug_loc_file_size = 0;
280 uint64_t debug_macinfo_file_size = 0;
281 uint64_t debug_pubnames_file_size = 0;
282 uint64_t debug_pubtypes_file_size = 0;
283 uint64_t debug_ranges_file_size = 0;
284 uint64_t debug_str_file_size = 0;
285
Greg Claytonb01000f2011-01-17 03:46:26 +0000286 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000287
288 if (section)
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000289 section_list = &section->GetChildren ();
Chris Lattner24943d22010-06-08 16:52:24 +0000290
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000291 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000292 if (section != NULL)
293 {
294 debug_info_file_size = section->GetByteSize();
295
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000296 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000297 if (section)
298 debug_abbrev_file_size = section->GetByteSize();
299 else
300 m_flags.Set (flagsGotDebugAbbrevData);
301
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000302 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000303 if (section)
304 debug_aranges_file_size = section->GetByteSize();
305 else
306 m_flags.Set (flagsGotDebugArangesData);
307
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000308 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000309 if (section)
310 debug_frame_file_size = section->GetByteSize();
311 else
312 m_flags.Set (flagsGotDebugFrameData);
313
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000314 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000315 if (section)
316 debug_line_file_size = section->GetByteSize();
317 else
318 m_flags.Set (flagsGotDebugLineData);
319
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000320 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000321 if (section)
322 debug_loc_file_size = section->GetByteSize();
323 else
324 m_flags.Set (flagsGotDebugLocData);
325
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000326 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000327 if (section)
328 debug_macinfo_file_size = section->GetByteSize();
329 else
330 m_flags.Set (flagsGotDebugMacInfoData);
331
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000332 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000333 if (section)
334 debug_pubnames_file_size = section->GetByteSize();
335 else
336 m_flags.Set (flagsGotDebugPubNamesData);
337
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000338 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000339 if (section)
340 debug_pubtypes_file_size = section->GetByteSize();
341 else
342 m_flags.Set (flagsGotDebugPubTypesData);
343
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000344 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000345 if (section)
346 debug_ranges_file_size = section->GetByteSize();
347 else
348 m_flags.Set (flagsGotDebugRangesData);
349
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000350 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000351 if (section)
352 debug_str_file_size = section->GetByteSize();
353 else
354 m_flags.Set (flagsGotDebugStrData);
355 }
356
357 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
358 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
359
360 if (debug_line_file_size > 0)
361 abilities |= LineTables;
362
363 if (debug_aranges_file_size > 0)
364 abilities |= AddressAcceleratorTable;
365
366 if (debug_pubnames_file_size > 0)
367 abilities |= FunctionAcceleratorTable;
368
369 if (debug_pubtypes_file_size > 0)
370 abilities |= TypeAcceleratorTable;
371
372 if (debug_macinfo_file_size > 0)
373 abilities |= MacroInformation;
374
375 if (debug_frame_file_size > 0)
376 abilities |= CallFrameInformation;
377 }
378 return abilities;
379}
380
381const DataExtractor&
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000382SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner24943d22010-06-08 16:52:24 +0000383{
384 if (m_flags.IsClear (got_flag))
385 {
386 m_flags.Set (got_flag);
387 const SectionList *section_list = m_obj_file->GetSectionList();
388 if (section_list)
389 {
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000390 Section *section = section_list->FindSectionByType(sect_type, true).get();
391 if (section)
Chris Lattner24943d22010-06-08 16:52:24 +0000392 {
393 // See if we memory mapped the DWARF segment?
394 if (m_dwarf_data.GetByteSize())
395 {
396 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
397 }
398 else
399 {
400 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
401 data.Clear();
402 }
403 }
404 }
405 }
406 return data;
407}
408
409const DataExtractor&
410SymbolFileDWARF::get_debug_abbrev_data()
411{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000412 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner24943d22010-06-08 16:52:24 +0000413}
414
415const DataExtractor&
Greg Clayton144188b2011-09-12 23:21:58 +0000416SymbolFileDWARF::get_debug_aranges_data()
417{
418 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
419}
420
421const DataExtractor&
Chris Lattner24943d22010-06-08 16:52:24 +0000422SymbolFileDWARF::get_debug_frame_data()
423{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000424 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner24943d22010-06-08 16:52:24 +0000425}
426
427const DataExtractor&
428SymbolFileDWARF::get_debug_info_data()
429{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000430 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner24943d22010-06-08 16:52:24 +0000431}
432
433const DataExtractor&
434SymbolFileDWARF::get_debug_line_data()
435{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000436 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner24943d22010-06-08 16:52:24 +0000437}
438
439const DataExtractor&
440SymbolFileDWARF::get_debug_loc_data()
441{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000442 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner24943d22010-06-08 16:52:24 +0000443}
444
445const DataExtractor&
Chris Lattner24943d22010-06-08 16:52:24 +0000446SymbolFileDWARF::get_debug_ranges_data()
447{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000448 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner24943d22010-06-08 16:52:24 +0000449}
450
451const DataExtractor&
452SymbolFileDWARF::get_debug_str_data()
453{
Greg Clayton32a8c7e2010-07-21 22:54:26 +0000454 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner24943d22010-06-08 16:52:24 +0000455}
456
Greg Claytonc8cf5e22011-09-01 23:16:13 +0000457const DataExtractor&
Greg Claytonf6e3de22011-09-28 17:06:40 +0000458SymbolFileDWARF::get_apple_names_data()
Greg Claytonc8cf5e22011-09-01 23:16:13 +0000459{
Greg Claytonf6e3de22011-09-28 17:06:40 +0000460 return GetCachedSectionData (flagsGotDebugNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonc8cf5e22011-09-01 23:16:13 +0000461}
462
463const DataExtractor&
Greg Claytonf6e3de22011-09-28 17:06:40 +0000464SymbolFileDWARF::get_apple_types_data()
Greg Claytonc8cf5e22011-09-01 23:16:13 +0000465{
Greg Claytonf6e3de22011-09-28 17:06:40 +0000466 return GetCachedSectionData (flagsGotDebugTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonc8cf5e22011-09-01 23:16:13 +0000467}
468
Chris Lattner24943d22010-06-08 16:52:24 +0000469
470DWARFDebugAbbrev*
471SymbolFileDWARF::DebugAbbrev()
472{
473 if (m_abbr.get() == NULL)
474 {
475 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
476 if (debug_abbrev_data.GetByteSize() > 0)
477 {
478 m_abbr.reset(new DWARFDebugAbbrev());
479 if (m_abbr.get())
480 m_abbr->Parse(debug_abbrev_data);
481 }
482 }
483 return m_abbr.get();
484}
485
486const DWARFDebugAbbrev*
487SymbolFileDWARF::DebugAbbrev() const
488{
489 return m_abbr.get();
490}
491
Chris Lattner24943d22010-06-08 16:52:24 +0000492
493DWARFDebugInfo*
494SymbolFileDWARF::DebugInfo()
495{
496 if (m_info.get() == NULL)
497 {
498 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
499 if (get_debug_info_data().GetByteSize() > 0)
500 {
501 m_info.reset(new DWARFDebugInfo());
502 if (m_info.get())
503 {
504 m_info->SetDwarfData(this);
505 }
506 }
507 }
508 return m_info.get();
509}
510
511const DWARFDebugInfo*
512SymbolFileDWARF::DebugInfo() const
513{
514 return m_info.get();
515}
516
Chris Lattner24943d22010-06-08 16:52:24 +0000517DWARFCompileUnit*
518SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
519{
520 DWARFDebugInfo* info = DebugInfo();
521 if (info)
522 return info->GetCompileUnit(cu_uid).get();
523 return NULL;
524}
525
Chris Lattner24943d22010-06-08 16:52:24 +0000526
527DWARFDebugRanges*
528SymbolFileDWARF::DebugRanges()
529{
530 if (m_ranges.get() == NULL)
531 {
532 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
533 if (get_debug_ranges_data().GetByteSize() > 0)
534 {
535 m_ranges.reset(new DWARFDebugRanges());
536 if (m_ranges.get())
537 m_ranges->Extract(this);
538 }
539 }
540 return m_ranges.get();
541}
542
543const DWARFDebugRanges*
544SymbolFileDWARF::DebugRanges() const
545{
546 return m_ranges.get();
547}
Chris Lattner24943d22010-06-08 16:52:24 +0000548
549bool
Greg Claytond7cb26e2010-11-10 23:42:09 +0000550SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000551{
Greg Claytond7cb26e2010-11-10 23:42:09 +0000552 if (curr_cu != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000553 {
Greg Claytond7cb26e2010-11-10 23:42:09 +0000554 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner24943d22010-06-08 16:52:24 +0000555 if (cu_die)
556 {
Greg Claytond7cb26e2010-11-10 23:42:09 +0000557 const char * cu_die_name = cu_die->GetName(this, curr_cu);
558 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
Jim Ingham24429c02011-08-24 23:34:20 +0000559 LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000560 if (cu_die_name)
561 {
Jim Inghamc4547c52010-09-16 00:57:33 +0000562 FileSpec cu_file_spec;
563
Greg Clayton7bb069b2011-02-09 23:39:34 +0000564 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
Chris Lattner24943d22010-06-08 16:52:24 +0000565 {
Jim Inghamc4547c52010-09-16 00:57:33 +0000566 // If we have a full path to the compile unit, we don't need to resolve
567 // the file. This can be expensive e.g. when the source files are NFS mounted.
568 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000569 }
570 else
571 {
572 std::string fullpath(cu_comp_dir);
573 if (*fullpath.rbegin() != '/')
574 fullpath += '/';
575 fullpath += cu_die_name;
Jim Inghamc4547c52010-09-16 00:57:33 +0000576 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000577 }
578
Jim Ingham24429c02011-08-24 23:34:20 +0000579 compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), cu_language));
Chris Lattner24943d22010-06-08 16:52:24 +0000580 if (compile_unit_sp.get())
581 {
Greg Claytond7cb26e2010-11-10 23:42:09 +0000582 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000583 return true;
584 }
585 }
586 }
587 }
588 return false;
589}
590
Chris Lattner24943d22010-06-08 16:52:24 +0000591uint32_t
592SymbolFileDWARF::GetNumCompileUnits()
593{
594 DWARFDebugInfo* info = DebugInfo();
595 if (info)
Chris Lattner24943d22010-06-08 16:52:24 +0000596 return info->GetNumCompileUnits();
Chris Lattner24943d22010-06-08 16:52:24 +0000597 return 0;
598}
599
600CompUnitSP
601SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
602{
603 CompUnitSP comp_unit;
604 DWARFDebugInfo* info = DebugInfo();
605 if (info)
606 {
Greg Claytond7cb26e2010-11-10 23:42:09 +0000607 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
608 if (curr_cu != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000609 {
610 // Our symbol vendor shouldn't be asking us to add a compile unit that
611 // has already been added to it, which this DWARF plug-in knows as it
612 // stores the lldb compile unit (CompileUnit) pointer in each
613 // DWARFCompileUnit object when it gets added.
Greg Claytond7cb26e2010-11-10 23:42:09 +0000614 assert(curr_cu->GetUserData() == NULL);
615 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner24943d22010-06-08 16:52:24 +0000616 }
617 }
618 return comp_unit;
619}
620
621static void
622AddRangesToBlock
623(
Greg Clayton75ccf502010-08-21 02:22:51 +0000624 Block& block,
Chris Lattner24943d22010-06-08 16:52:24 +0000625 DWARFDebugRanges::RangeList& ranges,
626 addr_t block_base_addr
627)
628{
629 ranges.SubtractOffset (block_base_addr);
630 size_t range_idx = 0;
631 const DWARFDebugRanges::Range *debug_range;
632 for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
633 {
Greg Clayton75ccf502010-08-21 02:22:51 +0000634 block.AddRange(debug_range->begin_offset, debug_range->end_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000635 }
636}
637
638
639Function *
Greg Clayton1d8173f2010-09-24 05:15:53 +0000640SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner24943d22010-06-08 16:52:24 +0000641{
642 DWARFDebugRanges::RangeList func_ranges;
643 const char *name = NULL;
644 const char *mangled = NULL;
645 int decl_file = 0;
646 int decl_line = 0;
647 int decl_column = 0;
648 int call_file = 0;
649 int call_line = 0;
650 int call_column = 0;
651 DWARFExpression frame_base;
652
Greg Claytonb433a3d2010-10-01 20:48:32 +0000653 assert (die->Tag() == DW_TAG_subprogram);
654
655 if (die->Tag() != DW_TAG_subprogram)
656 return NULL;
657
Greg Claytonc5dca6c2011-08-12 06:47:54 +0000658 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die);
659 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
Greg Claytonb433a3d2010-10-01 20:48:32 +0000660
Greg Claytonc5dca6c2011-08-12 06:47:54 +0000661 switch (containing_decl_kind)
662 {
663 case clang::Decl::Record:
664 case clang::Decl::CXXRecord:
665 case clang::Decl::ObjCClass:
666 case clang::Decl::ObjCImplementation:
667 case clang::Decl::ObjCInterface:
668 // We have methods of a class or struct
669 {
670 const DWARFDebugInfoEntry *containing_decl_die = m_decl_ctx_to_die[containing_decl_ctx];
671 assert (containing_decl_die);
672 Type *class_type = ResolveType (dwarf_cu, containing_decl_die);
673 if (class_type)
674 class_type->GetClangFullType();
675 // Make sure the class definition contains the funciton DIE
676 // we wanted to parse. If it does, we are done. Else, we need
677 // to fall through and parse the function DIE stil...
678 if (containing_decl_die->Contains (die))
679 break; // DIE has been parsed, we are done
680 }
681 // Fall through...
682
683 default:
684 // Parse the function prototype as a type that can then be added to concrete function instance
685 ParseTypes (sc, dwarf_cu, die, false, false);
686 break;
Greg Claytonb433a3d2010-10-01 20:48:32 +0000687 }
688
Chris Lattner24943d22010-06-08 16:52:24 +0000689 //FixupTypes();
690
691 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
692 {
693 // Union of all ranges in the function DIE (if the function is discontiguous)
694 AddressRange func_range;
695 lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
696 lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
697 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
698 {
699 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
700 if (func_range.GetBaseAddress().IsValid())
701 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
702 }
703
704 if (func_range.GetBaseAddress().IsValid())
705 {
706 Mangled func_name;
707 if (mangled)
708 func_name.SetValue(mangled, true);
709 else if (name)
710 func_name.SetValue(name, false);
711
712 FunctionSP func_sp;
713 std::auto_ptr<Declaration> decl_ap;
714 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytonfeb6e562010-11-14 00:22:48 +0000715 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
716 decl_line,
717 decl_column));
Chris Lattner24943d22010-06-08 16:52:24 +0000718
Greg Clayton4fb400f2010-09-27 21:07:38 +0000719 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner24943d22010-06-08 16:52:24 +0000720
721 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
722
723 func_range.GetBaseAddress().ResolveLinkedAddress();
724
725 func_sp.reset(new Function (sc.comp_unit,
726 die->GetOffset(), // UserID is the DIE offset
727 die->GetOffset(),
728 func_name,
729 func_type,
730 func_range)); // first address range
731
732 if (func_sp.get() != NULL)
733 {
734 func_sp->GetFrameBaseExpression() = frame_base;
735 sc.comp_unit->AddFunction(func_sp);
736 return func_sp.get();
737 }
738 }
739 }
740 return NULL;
741}
742
743size_t
744SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
745{
746 assert (sc.comp_unit);
747 size_t functions_added = 0;
Greg Clayton1d8173f2010-09-24 05:15:53 +0000748 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +0000749 if (dwarf_cu)
750 {
751 DWARFDIECollection function_dies;
752 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
753 size_t func_idx;
754 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
755 {
756 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
757 if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
758 {
759 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
760 ++functions_added;
761 }
762 }
763 //FixupTypes();
764 }
765 return functions_added;
766}
767
768bool
769SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
770{
771 assert (sc.comp_unit);
Greg Claytond7cb26e2010-11-10 23:42:09 +0000772 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
773 assert (curr_cu);
774 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner24943d22010-06-08 16:52:24 +0000775
776 if (cu_die)
777 {
Greg Claytond7cb26e2010-11-10 23:42:09 +0000778 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
779 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner24943d22010-06-08 16:52:24 +0000780
781 // All file indexes in DWARF are one based and a file of index zero is
782 // supposed to be the compile unit itself.
783 support_files.Append (*sc.comp_unit);
784
785 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
786 }
787 return false;
788}
789
790struct ParseDWARFLineTableCallbackInfo
791{
792 LineTable* line_table;
793 const SectionList *section_list;
794 lldb::addr_t prev_sect_file_base_addr;
795 lldb::addr_t curr_sect_file_base_addr;
796 bool is_oso_for_debug_map;
797 bool prev_in_final_executable;
798 DWARFDebugLine::Row prev_row;
799 SectionSP prev_section_sp;
800 SectionSP curr_section_sp;
801};
802
803//----------------------------------------------------------------------
804// ParseStatementTableCallback
805//----------------------------------------------------------------------
806static void
807ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
808{
809 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
810 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
811 {
812 // Just started parsing the line table
813 }
814 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
815 {
816 // Done parsing line table, nothing to do for the cleanup
817 }
818 else
819 {
820 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
821 // We have a new row, lets append it
822
823 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
824 {
825 info->prev_section_sp = info->curr_section_sp;
826 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
827 // If this is an end sequence entry, then we subtract one from the
828 // address to make sure we get an address that is not the end of
829 // a section.
830 if (state.end_sequence && state.address != 0)
831 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
832 else
833 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
834
835 if (info->curr_section_sp.get())
836 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
837 else
838 info->curr_sect_file_base_addr = 0;
839 }
840 if (info->curr_section_sp.get())
841 {
842 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
843 // Check for the fancy section magic to determine if we
844
845 if (info->is_oso_for_debug_map)
846 {
847 // When this is a debug map object file that contains DWARF
848 // (referenced from an N_OSO debug map nlist entry) we will have
849 // a file address in the file range for our section from the
850 // original .o file, and a load address in the executable that
851 // contains the debug map.
852 //
853 // If the sections for the file range and load range are
854 // different, we have a remapped section for the function and
855 // this address is resolved. If they are the same, then the
856 // function for this address didn't make it into the final
857 // executable.
858 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
859
860 // If we are doing DWARF with debug map, then we need to carefully
861 // add each line table entry as there may be gaps as functions
862 // get moved around or removed.
863 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
864 {
865 if (info->prev_in_final_executable)
866 {
867 bool terminate_previous_entry = false;
868 if (!curr_in_final_executable)
869 {
870 // Check for the case where the previous line entry
871 // in a function made it into the final executable,
872 // yet the current line entry falls in a function
873 // that didn't. The line table used to be contiguous
874 // through this address range but now it isn't. We
875 // need to terminate the previous line entry so
876 // that we can reconstruct the line range correctly
877 // for it and to keep the line table correct.
878 terminate_previous_entry = true;
879 }
880 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
881 {
882 // Check for cases where the line entries used to be
883 // contiguous address ranges, but now they aren't.
884 // This can happen when order files specify the
885 // ordering of the functions.
886 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
887 Section *curr_sect = info->curr_section_sp.get();
888 Section *prev_sect = info->prev_section_sp.get();
889 assert (curr_sect->GetLinkedSection());
890 assert (prev_sect->GetLinkedSection());
891 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
892 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
893 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
894 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
895 if (object_file_addr_delta != linked_file_addr_delta)
896 terminate_previous_entry = true;
897 }
898
899 if (terminate_previous_entry)
900 {
901 line_table->InsertLineEntry (info->prev_section_sp,
902 state.address - info->prev_sect_file_base_addr,
903 info->prev_row.line,
904 info->prev_row.column,
905 info->prev_row.file,
906 false, // is_stmt
907 false, // basic_block
908 false, // state.prologue_end
909 false, // state.epilogue_begin
910 true); // end_sequence);
911 }
912 }
913 }
914
915 if (curr_in_final_executable)
916 {
917 line_table->InsertLineEntry (info->curr_section_sp,
918 curr_line_section_offset,
919 state.line,
920 state.column,
921 state.file,
922 state.is_stmt,
923 state.basic_block,
924 state.prologue_end,
925 state.epilogue_begin,
926 state.end_sequence);
927 info->prev_section_sp = info->curr_section_sp;
928 }
929 else
930 {
931 // If the current address didn't make it into the final
932 // executable, the current section will be the __text
933 // segment in the .o file, so we need to clear this so
934 // we can catch the next function that did make it into
935 // the final executable.
936 info->prev_section_sp.reset();
937 info->curr_section_sp.reset();
938 }
939
940 info->prev_in_final_executable = curr_in_final_executable;
941 }
942 else
943 {
944 // We are not in an object file that contains DWARF for an
945 // N_OSO, this is just a normal DWARF file. The DWARF spec
946 // guarantees that the addresses will be in increasing order
947 // so, since we store line tables in file address order, we
948 // can always just append the line entry without needing to
949 // search for the correct insertion point (we don't need to
950 // use LineEntry::InsertLineEntry()).
951 line_table->AppendLineEntry (info->curr_section_sp,
952 curr_line_section_offset,
953 state.line,
954 state.column,
955 state.file,
956 state.is_stmt,
957 state.basic_block,
958 state.prologue_end,
959 state.epilogue_begin,
960 state.end_sequence);
961 }
962 }
963
964 info->prev_row = state;
965 }
966}
967
968bool
969SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
970{
971 assert (sc.comp_unit);
972 if (sc.comp_unit->GetLineTable() != NULL)
973 return true;
974
975 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
976 if (dwarf_cu)
977 {
978 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
979 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
980 if (cu_line_offset != DW_INVALID_OFFSET)
981 {
982 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
983 if (line_table_ap.get())
984 {
Greg Claytonad60bf42010-10-12 02:24:53 +0000985 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
Chris Lattner24943d22010-06-08 16:52:24 +0000986 uint32_t offset = cu_line_offset;
987 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
988 sc.comp_unit->SetLineTable(line_table_ap.release());
989 return true;
990 }
991 }
992 }
993 return false;
994}
995
996size_t
997SymbolFileDWARF::ParseFunctionBlocks
998(
999 const SymbolContext& sc,
Greg Clayton75ccf502010-08-21 02:22:51 +00001000 Block *parent_block,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001001 DWARFCompileUnit* dwarf_cu,
Chris Lattner24943d22010-06-08 16:52:24 +00001002 const DWARFDebugInfoEntry *die,
1003 addr_t subprogram_low_pc,
Greg Clayton2e45b0c2011-08-12 17:54:33 +00001004 uint32_t depth
Chris Lattner24943d22010-06-08 16:52:24 +00001005)
1006{
1007 size_t blocks_added = 0;
1008 while (die != NULL)
1009 {
1010 dw_tag_t tag = die->Tag();
1011
1012 switch (tag)
1013 {
Chris Lattner24943d22010-06-08 16:52:24 +00001014 case DW_TAG_inlined_subroutine:
Greg Clayton11afe6a2011-08-12 16:22:48 +00001015 case DW_TAG_subprogram:
Chris Lattner24943d22010-06-08 16:52:24 +00001016 case DW_TAG_lexical_block:
1017 {
Greg Clayton75ccf502010-08-21 02:22:51 +00001018 Block *block = NULL;
Greg Clayton2e45b0c2011-08-12 17:54:33 +00001019 if (tag == DW_TAG_subprogram)
1020 {
1021 // Skip any DW_TAG_subprogram DIEs that are inside
1022 // of a normal or inlined functions. These will be
1023 // parsed on their own as separate entities.
1024
1025 if (depth > 0)
1026 break;
1027
1028 block = parent_block;
1029 }
1030 else
Greg Clayton75ccf502010-08-21 02:22:51 +00001031 {
1032 BlockSP block_sp(new Block (die->GetOffset()));
1033 parent_block->AddChild(block_sp);
1034 block = block_sp.get();
1035 }
Greg Clayton2e45b0c2011-08-12 17:54:33 +00001036 DWARFDebugRanges::RangeList ranges;
1037 const char *name = NULL;
1038 const char *mangled_name = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001039
Chris Lattner24943d22010-06-08 16:52:24 +00001040 int decl_file = 0;
1041 int decl_line = 0;
1042 int decl_column = 0;
1043 int call_file = 0;
1044 int call_line = 0;
1045 int call_column = 0;
Greg Clayton75ccf502010-08-21 02:22:51 +00001046 if (die->GetDIENamesAndRanges (this,
1047 dwarf_cu,
1048 name,
1049 mangled_name,
1050 ranges,
1051 decl_file, decl_line, decl_column,
1052 call_file, call_line, call_column))
Chris Lattner24943d22010-06-08 16:52:24 +00001053 {
1054 if (tag == DW_TAG_subprogram)
1055 {
1056 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1057 subprogram_low_pc = ranges.LowestAddress(0);
1058 }
Jim Ingham0007dff2010-08-12 01:20:14 +00001059 else if (tag == DW_TAG_inlined_subroutine)
1060 {
1061 // We get called here for inlined subroutines in two ways.
1062 // The first time is when we are making the Function object
1063 // for this inlined concrete instance. Since we're creating a top level block at
1064 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1065 // adjust the containing address.
1066 // The second time is when we are parsing the blocks inside the function that contains
1067 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1068 // function the offset will be for that function.
1069 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1070 {
1071 subprogram_low_pc = ranges.LowestAddress(0);
1072 }
1073 }
1074
Greg Clayton75ccf502010-08-21 02:22:51 +00001075 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner24943d22010-06-08 16:52:24 +00001076
1077 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1078 {
1079 std::auto_ptr<Declaration> decl_ap;
1080 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Ingham0007dff2010-08-12 01:20:14 +00001081 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1082 decl_line, decl_column));
Chris Lattner24943d22010-06-08 16:52:24 +00001083
1084 std::auto_ptr<Declaration> call_ap;
1085 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Ingham0007dff2010-08-12 01:20:14 +00001086 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1087 call_line, call_column));
Chris Lattner24943d22010-06-08 16:52:24 +00001088
Greg Clayton75ccf502010-08-21 02:22:51 +00001089 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner24943d22010-06-08 16:52:24 +00001090 }
1091
1092 ++blocks_added;
1093
Greg Clayton2e45b0c2011-08-12 17:54:33 +00001094 if (die->HasChildren())
Chris Lattner24943d22010-06-08 16:52:24 +00001095 {
Greg Clayton75ccf502010-08-21 02:22:51 +00001096 blocks_added += ParseFunctionBlocks (sc,
1097 block,
1098 dwarf_cu,
1099 die->GetFirstChild(),
1100 subprogram_low_pc,
Greg Clayton2e45b0c2011-08-12 17:54:33 +00001101 depth + 1);
Chris Lattner24943d22010-06-08 16:52:24 +00001102 }
1103 }
1104 }
1105 break;
1106 default:
1107 break;
1108 }
1109
Greg Clayton2e45b0c2011-08-12 17:54:33 +00001110 // Only parse siblings of the block if we are not at depth zero. A depth
1111 // of zero indicates we are currently parsing the top level
1112 // DW_TAG_subprogram DIE
1113
1114 if (depth == 0)
Chris Lattner24943d22010-06-08 16:52:24 +00001115 die = NULL;
Greg Clayton2e45b0c2011-08-12 17:54:33 +00001116 else
1117 die = die->GetSibling();
Chris Lattner24943d22010-06-08 16:52:24 +00001118 }
1119 return blocks_added;
1120}
1121
1122size_t
1123SymbolFileDWARF::ParseChildMembers
1124(
1125 const SymbolContext& sc,
Greg Clayton1d8173f2010-09-24 05:15:53 +00001126 DWARFCompileUnit* dwarf_cu,
Chris Lattner24943d22010-06-08 16:52:24 +00001127 const DWARFDebugInfoEntry *parent_die,
Greg Clayton462d4142010-09-29 01:12:09 +00001128 clang_type_t class_clang_type,
Greg Clayton9488b742010-07-28 02:04:09 +00001129 const LanguageType class_language,
Chris Lattner24943d22010-06-08 16:52:24 +00001130 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1131 std::vector<int>& member_accessibilities,
Greg Claytonb433a3d2010-10-01 20:48:32 +00001132 DWARFDIECollection& member_function_dies,
Sean Callanan70a4f922010-08-06 00:32:49 +00001133 AccessType& default_accessibility,
Chris Lattner24943d22010-06-08 16:52:24 +00001134 bool &is_a_class
1135)
1136{
1137 if (parent_die == NULL)
1138 return 0;
1139
Chris Lattner24943d22010-06-08 16:52:24 +00001140 size_t count = 0;
1141 const DWARFDebugInfoEntry *die;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00001142 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Claytonb01000f2011-01-17 03:46:26 +00001143 uint32_t member_idx = 0;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00001144
Chris Lattner24943d22010-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 Claytone4b9df02010-11-13 22:57:37 +00001154 const size_t num_attributes = die->GetAttributes (this,
1155 dwarf_cu,
1156 fixed_form_sizes,
1157 attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00001158 if (num_attributes > 0)
1159 {
1160 Declaration decl;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001161 //DWARFExpression location;
Chris Lattner24943d22010-06-08 16:52:24 +00001162 const char *name = NULL;
Greg Claytonfb7c51c2010-10-13 03:15:28 +00001163 bool is_artificial = false;
Chris Lattner24943d22010-06-08 16:52:24 +00001164 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callanan70a4f922010-08-06 00:32:49 +00001165 AccessType accessibility = eAccessNone;
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001166 //off_t member_offset = 0;
Chris Lattner24943d22010-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 Claytonfb7c51c2010-10-13 03:15:28 +00001171 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner24943d22010-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 Claytonf3d0b0c2010-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 Lattner24943d22010-06-08 16:52:24 +00001200 break;
1201
Greg Clayton84f80752010-07-22 18:30:50 +00001202 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Claytonfb7c51c2010-10-13 03:15:28 +00001203 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner24943d22010-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 Callanan4ee40ac2010-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 Claytonb01000f2011-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 Lattner24943d22010-06-08 16:52:24 +00001231
Greg Claytonfb7c51c2010-10-13 03:15:28 +00001232 if (is_artificial == false)
1233 {
1234 Type *member_type = ResolveTypeUID(encoding_uid);
Greg Clayton7dd98df2011-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 Lattner24943d22010-06-08 16:52:24 +00001240
Greg Clayton7dd98df2011-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 Claytonfb7c51c2010-10-13 03:15:28 +00001259 }
Chris Lattner24943d22010-06-08 16:52:24 +00001260 }
Greg Claytonb01000f2011-01-17 03:46:26 +00001261 ++member_idx;
Chris Lattner24943d22010-06-08 16:52:24 +00001262 }
1263 break;
1264
1265 case DW_TAG_subprogram:
Greg Claytonb433a3d2010-10-01 20:48:32 +00001266 // Let the type parsing code handle this one for us.
1267 member_function_dies.Append (die);
Chris Lattner24943d22010-06-08 16:52:24 +00001268 break;
1269
1270 case DW_TAG_inheritance:
1271 {
1272 is_a_class = true;
Sean Callanan70a4f922010-08-06 00:32:49 +00001273 if (default_accessibility == eAccessNone)
1274 default_accessibility = eAccessPrivate;
Chris Lattner24943d22010-06-08 16:52:24 +00001275 // TODO: implement DW_TAG_inheritance type parsing
1276 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytone4b9df02010-11-13 22:57:37 +00001277 const size_t num_attributes = die->GetAttributes (this,
1278 dwarf_cu,
1279 fixed_form_sizes,
1280 attributes);
Chris Lattner24943d22010-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 Callanan70a4f922010-08-06 00:32:49 +00001286 AccessType accessibility = default_accessibility;
Chris Lattner24943d22010-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 Claytone4b9df02010-11-13 22:57:37 +00001311 if (DWARFExpression::Evaluate (NULL,
1312 NULL,
Greg Claytone4b9df02010-11-13 22:57:37 +00001313 NULL,
1314 NULL,
Jason Molenda8e69de42010-11-20 01:28:30 +00001315 NULL,
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00001316 debug_info_data,
Greg Claytone4b9df02010-11-13 22:57:37 +00001317 block_offset,
1318 block_length,
1319 eRegisterKindDWARF,
1320 &initialValue,
1321 memberOffset,
1322 NULL))
Chris Lattner24943d22010-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 Clayton84f80752010-07-22 18:30:50 +00001330 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner24943d22010-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 Clayton6916e352010-11-13 03:52:47 +00001341 Type *base_class_type = ResolveTypeUID(encoding_uid);
1342 assert(base_class_type);
Greg Clayton9488b742010-07-28 02:04:09 +00001343
Greg Clayton04c9c7b2011-02-16 23:00:21 +00001344 clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1345 assert (base_class_clang_type);
Greg Clayton9488b742010-07-28 02:04:09 +00001346 if (class_language == eLanguageTypeObjC)
1347 {
Greg Clayton04c9c7b2011-02-16 23:00:21 +00001348 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
Greg Clayton9488b742010-07-28 02:04:09 +00001349 }
1350 else
1351 {
Greg Clayton04c9c7b2011-02-16 23:00:21 +00001352 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
Greg Claytone4b9df02010-11-13 22:57:37 +00001353 accessibility,
1354 is_virtual,
1355 is_base_of_class));
Greg Clayton9488b742010-07-28 02:04:09 +00001356 }
Chris Lattner24943d22010-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 Callananc617a4c2011-08-05 23:43:37 +00001370SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner24943d22010-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 Callananc617a4c2011-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 Lattner24943d22010-06-08 16:52:24 +00001393 }
1394 return NULL;
1395}
1396
1397Type*
Greg Clayton74124752010-09-15 04:15:46 +00001398SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner24943d22010-06-08 16:52:24 +00001399{
1400 DWARFDebugInfo* debug_info = DebugInfo();
1401 if (debug_info)
1402 {
Greg Clayton74124752010-09-15 04:15:46 +00001403 DWARFCompileUnitSP cu_sp;
1404 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
Chris Lattner24943d22010-06-08 16:52:24 +00001405 if (type_die != NULL)
Greg Clayton0d62dfd2011-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 Clayton4fb400f2010-09-27 21:07:38 +00001419 return ResolveType (cu_sp.get(), type_die);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00001420 }
Chris Lattner24943d22010-06-08 16:52:24 +00001421 }
1422 return NULL;
1423}
1424
Greg Claytonb01000f2011-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 Clayton462d4142010-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 Claytonb01000f2011-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 Clayton462d4142010-09-29 01:12:09 +00001443 if (die == NULL)
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001444 {
Greg Claytonb01000f2011-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 Claytonf3d0b0c2010-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 Claytonb01000f2011-01-17 03:46:26 +00001458 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Claytonf3d0b0c2010-10-27 03:32:59 +00001459
Greg Clayton462d4142010-09-29 01:12:09 +00001460
Greg Claytonad60bf42010-10-12 02:24:53 +00001461 DWARFDebugInfo* debug_info = DebugInfo();
1462
Greg Claytond7cb26e2010-11-10 23:42:09 +00001463 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton462d4142010-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 Claytone98ac252010-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 Clayton462d4142010-09-29 01:12:09 +00001472 assert (clang_type);
1473 DWARFDebugInfoEntry::Attributes attributes;
1474
Greg Claytone98ac252010-11-10 04:57:04 +00001475 ClangASTContext &ast = GetClangASTContext();
Greg Clayton462d4142010-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 Claytone98ac252010-11-10 04:57:04 +00001482 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonb433a3d2010-10-01 20:48:32 +00001483 if (die->HasChildren())
1484 {
1485 LanguageType class_language = eLanguageTypeUnknown;
Greg Claytonad60bf42010-10-12 02:24:53 +00001486 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1487 if (is_objc_class)
Greg Claytonb433a3d2010-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 Clayton462d4142010-09-29 01:12:09 +00001493 {
Greg Claytonb433a3d2010-10-01 20:48:32 +00001494 tag_decl_kind = clang::TTK_Struct;
1495 default_accessibility = eAccessPublic;
Greg Clayton462d4142010-09-29 01:12:09 +00001496 }
Greg Claytonb433a3d2010-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 Claytond7cb26e2010-11-10 23:42:09 +00001508 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonb433a3d2010-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 Claytond7cb26e2010-11-10 23:42:09 +00001516 curr_cu,
Greg Claytonb433a3d2010-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 Claytond7cb26e2010-11-10 23:42:09 +00001532 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonb433a3d2010-10-01 20:48:32 +00001533 }
1534 }
1535
Greg Claytonad60bf42010-10-12 02:24:53 +00001536 if (class_language == eLanguageTypeObjC)
1537 {
Greg Claytonb302b2f2011-06-30 02:28:26 +00001538 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
Greg Claytonad60bf42010-10-12 02:24:53 +00001539 if (!class_str.empty())
1540 {
1541
1542 ConstString class_name (class_str.c_str());
Greg Clayton144188b2011-09-12 23:21:58 +00001543 DIEArray method_die_offsets;
1544 if (m_objc_class_selectors_index.Find (class_name, method_die_offsets))
Greg Claytonad60bf42010-10-12 02:24:53 +00001545 {
Greg Clayton144188b2011-09-12 23:21:58 +00001546 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytonad60bf42010-10-12 02:24:53 +00001547
Greg Clayton144188b2011-09-12 23:21:58 +00001548 DWARFCompileUnit* method_cu = NULL;
1549 const size_t num_matches = method_die_offsets.size();
1550 for (size_t i=0; i<num_matches; ++i)
1551 {
1552 const dw_offset_t die_offset = method_die_offsets[i];
1553 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
Greg Claytonad60bf42010-10-12 02:24:53 +00001554
1555 ResolveType (method_cu, method_die);
1556 }
1557 }
1558 }
1559 }
1560
Greg Claytonb433a3d2010-10-01 20:48:32 +00001561 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1562 // need to tell the clang type it is actually a class.
1563 if (class_language != eLanguageTypeObjC)
1564 {
1565 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Claytone98ac252010-11-10 04:57:04 +00001566 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonb433a3d2010-10-01 20:48:32 +00001567 }
1568
1569 // Since DW_TAG_structure_type gets used for both classes
1570 // and structures, we may need to set any DW_TAG_member
1571 // fields to have a "private" access if none was specified.
1572 // When we parsed the child members we tracked that actual
1573 // accessibility value for each DW_TAG_member in the
1574 // "member_accessibilities" array. If the value for the
1575 // member is zero, then it was set to the "default_accessibility"
1576 // which for structs was "public". Below we correct this
1577 // by setting any fields to "private" that weren't correctly
1578 // set.
1579 if (is_a_class && !member_accessibilities.empty())
1580 {
1581 // This is a class and all members that didn't have
1582 // their access specified are private.
Greg Claytone98ac252010-11-10 04:57:04 +00001583 ast.SetDefaultAccessForRecordFields (clang_type,
1584 eAccessPrivate,
1585 &member_accessibilities.front(),
1586 member_accessibilities.size());
Greg Claytonb433a3d2010-10-01 20:48:32 +00001587 }
1588
1589 if (!base_classes.empty())
1590 {
Greg Claytone98ac252010-11-10 04:57:04 +00001591 ast.SetBaseClassesForClassType (clang_type,
1592 &base_classes.front(),
1593 base_classes.size());
Greg Claytonb433a3d2010-10-01 20:48:32 +00001594
1595 // Clang will copy each CXXBaseSpecifier in "base_classes"
1596 // so we have to free them all.
Greg Claytone98ac252010-11-10 04:57:04 +00001597 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1598 base_classes.size());
Greg Claytonb433a3d2010-10-01 20:48:32 +00001599 }
1600
1601 }
Greg Claytone98ac252010-11-10 04:57:04 +00001602 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonb433a3d2010-10-01 20:48:32 +00001603 return clang_type;
Greg Clayton462d4142010-09-29 01:12:09 +00001604
1605 case DW_TAG_enumeration_type:
Greg Claytone98ac252010-11-10 04:57:04 +00001606 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton462d4142010-09-29 01:12:09 +00001607 if (die->HasChildren())
1608 {
Greg Claytond7cb26e2010-11-10 23:42:09 +00001609 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1610 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton462d4142010-09-29 01:12:09 +00001611 }
Greg Claytone98ac252010-11-10 04:57:04 +00001612 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton462d4142010-09-29 01:12:09 +00001613 return clang_type;
1614
1615 default:
1616 assert(false && "not a forward clang type decl!");
1617 break;
1618 }
1619 return NULL;
1620}
1621
Greg Clayton74124752010-09-15 04:15:46 +00001622Type*
Greg Claytond7cb26e2010-11-10 23:42:09 +00001623SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Clayton74124752010-09-15 04:15:46 +00001624{
1625 if (type_die != NULL)
1626 {
Greg Clayton4fb400f2010-09-27 21:07:38 +00001627 Type *type = m_die_to_type.lookup (type_die);
Greg Clayton74124752010-09-15 04:15:46 +00001628 if (type == NULL)
Greg Claytond7cb26e2010-11-10 23:42:09 +00001629 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Claytonfb7c51c2010-10-13 03:15:28 +00001630 if (assert_not_being_parsed)
1631 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton4fb400f2010-09-27 21:07:38 +00001632 return type;
Greg Clayton74124752010-09-15 04:15:46 +00001633 }
1634 return NULL;
1635}
1636
Chris Lattner24943d22010-06-08 16:52:24 +00001637CompileUnit*
Greg Claytond7cb26e2010-11-10 23:42:09 +00001638SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner24943d22010-06-08 16:52:24 +00001639{
1640 // Check if the symbol vendor already knows about this compile unit?
Greg Claytond7cb26e2010-11-10 23:42:09 +00001641 if (curr_cu->GetUserData() == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001642 {
1643 // The symbol vendor doesn't know about this compile unit, we
1644 // need to parse and add it to the symbol vendor object.
1645 CompUnitSP dc_cu;
Greg Claytond7cb26e2010-11-10 23:42:09 +00001646 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner24943d22010-06-08 16:52:24 +00001647 if (dc_cu.get())
1648 {
1649 // Figure out the compile unit index if we weren't given one
Greg Clayton178710c2010-09-14 02:20:48 +00001650 if (cu_idx == UINT32_MAX)
Greg Claytond7cb26e2010-11-10 23:42:09 +00001651 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001652
1653 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Claytonad60bf42010-10-12 02:24:53 +00001654
1655 if (m_debug_map_symfile)
1656 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner24943d22010-06-08 16:52:24 +00001657 }
1658 }
Greg Claytond7cb26e2010-11-10 23:42:09 +00001659 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner24943d22010-06-08 16:52:24 +00001660}
1661
1662bool
Greg Claytond7cb26e2010-11-10 23:42:09 +00001663SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner24943d22010-06-08 16:52:24 +00001664{
1665 sc.Clear();
1666 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton02e210c2011-09-17 07:23:18 +00001667 sc.module_sp = m_obj_file->GetModule();
Greg Claytond7cb26e2010-11-10 23:42:09 +00001668 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner24943d22010-06-08 16:52:24 +00001669
1670 sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1671 if (sc.function == NULL)
Greg Claytond7cb26e2010-11-10 23:42:09 +00001672 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Chris Lattner24943d22010-06-08 16:52:24 +00001673
1674 return sc.function != NULL;
1675}
1676
1677uint32_t
1678SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1679{
1680 Timer scoped_timer(__PRETTY_FUNCTION__,
1681 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1682 so_addr.GetSection(),
1683 so_addr.GetOffset(),
1684 resolve_scope);
1685 uint32_t resolved = 0;
1686 if (resolve_scope & ( eSymbolContextCompUnit |
1687 eSymbolContextFunction |
1688 eSymbolContextBlock |
1689 eSymbolContextLineEntry))
1690 {
1691 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1692
Chris Lattner24943d22010-06-08 16:52:24 +00001693 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton144188b2011-09-12 23:21:58 +00001694 if (debug_info)
Chris Lattner24943d22010-06-08 16:52:24 +00001695 {
Greg Clayton144188b2011-09-12 23:21:58 +00001696 dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Chris Lattner24943d22010-06-08 16:52:24 +00001697 if (cu_offset != DW_INVALID_OFFSET)
1698 {
1699 uint32_t cu_idx;
Greg Claytond7cb26e2010-11-10 23:42:09 +00001700 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1701 if (curr_cu)
Chris Lattner24943d22010-06-08 16:52:24 +00001702 {
Greg Claytond7cb26e2010-11-10 23:42:09 +00001703 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001704 assert(sc.comp_unit != NULL);
1705 resolved |= eSymbolContextCompUnit;
1706
1707 if (resolve_scope & eSymbolContextLineEntry)
1708 {
1709 LineTable *line_table = sc.comp_unit->GetLineTable();
1710 if (line_table == NULL)
1711 {
1712 if (ParseCompileUnitLineTable(sc))
1713 line_table = sc.comp_unit->GetLineTable();
1714 }
1715 if (line_table != NULL)
1716 {
1717 if (so_addr.IsLinkedAddress())
1718 {
1719 Address linked_addr (so_addr);
1720 linked_addr.ResolveLinkedAddress();
1721 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1722 {
1723 resolved |= eSymbolContextLineEntry;
1724 }
1725 }
1726 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1727 {
1728 resolved |= eSymbolContextLineEntry;
1729 }
1730 }
1731 }
1732
1733 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1734 {
1735 DWARFDebugInfoEntry *function_die = NULL;
1736 DWARFDebugInfoEntry *block_die = NULL;
1737 if (resolve_scope & eSymbolContextBlock)
1738 {
Greg Claytond7cb26e2010-11-10 23:42:09 +00001739 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner24943d22010-06-08 16:52:24 +00001740 }
1741 else
1742 {
Greg Claytond7cb26e2010-11-10 23:42:09 +00001743 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +00001744 }
1745
1746 if (function_die != NULL)
1747 {
1748 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1749 if (sc.function == NULL)
Greg Claytond7cb26e2010-11-10 23:42:09 +00001750 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner24943d22010-06-08 16:52:24 +00001751 }
1752
1753 if (sc.function != NULL)
1754 {
1755 resolved |= eSymbolContextFunction;
1756
1757 if (resolve_scope & eSymbolContextBlock)
1758 {
Greg Clayton75ccf502010-08-21 02:22:51 +00001759 Block& block = sc.function->GetBlock (true);
Chris Lattner24943d22010-06-08 16:52:24 +00001760
1761 if (block_die != NULL)
Greg Clayton75ccf502010-08-21 02:22:51 +00001762 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner24943d22010-06-08 16:52:24 +00001763 else
Greg Clayton75ccf502010-08-21 02:22:51 +00001764 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner24943d22010-06-08 16:52:24 +00001765 if (sc.block)
1766 resolved |= eSymbolContextBlock;
1767 }
1768 }
1769 }
1770 }
1771 }
1772 }
1773 }
1774 return resolved;
1775}
1776
1777
1778
1779uint32_t
1780SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1781{
1782 const uint32_t prev_size = sc_list.GetSize();
1783 if (resolve_scope & eSymbolContextCompUnit)
1784 {
1785 DWARFDebugInfo* debug_info = DebugInfo();
1786 if (debug_info)
1787 {
1788 uint32_t cu_idx;
Greg Claytond7cb26e2010-11-10 23:42:09 +00001789 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001790
Greg Claytond7cb26e2010-11-10 23:42:09 +00001791 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner24943d22010-06-08 16:52:24 +00001792 {
Greg Claytond7cb26e2010-11-10 23:42:09 +00001793 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001794 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1795 if (check_inlines || file_spec_matches_cu_file_spec)
1796 {
1797 SymbolContext sc (m_obj_file->GetModule());
Greg Claytond7cb26e2010-11-10 23:42:09 +00001798 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001799 assert(sc.comp_unit != NULL);
1800
1801 uint32_t file_idx = UINT32_MAX;
1802
1803 // If we are looking for inline functions only and we don't
1804 // find it in the support files, we are done.
1805 if (check_inlines)
1806 {
Jim Inghamd6d47972011-09-23 00:54:11 +00001807 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner24943d22010-06-08 16:52:24 +00001808 if (file_idx == UINT32_MAX)
1809 continue;
1810 }
1811
1812 if (line != 0)
1813 {
1814 LineTable *line_table = sc.comp_unit->GetLineTable();
1815
1816 if (line_table != NULL && line != 0)
1817 {
1818 // We will have already looked up the file index if
1819 // we are searching for inline entries.
1820 if (!check_inlines)
Jim Inghamd6d47972011-09-23 00:54:11 +00001821 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner24943d22010-06-08 16:52:24 +00001822
1823 if (file_idx != UINT32_MAX)
1824 {
1825 uint32_t found_line;
1826 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1827 found_line = sc.line_entry.line;
1828
Greg Clayton178710c2010-09-14 02:20:48 +00001829 while (line_idx != UINT32_MAX)
Chris Lattner24943d22010-06-08 16:52:24 +00001830 {
1831 sc.function = NULL;
1832 sc.block = NULL;
1833 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1834 {
1835 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1836 if (file_vm_addr != LLDB_INVALID_ADDRESS)
1837 {
1838 DWARFDebugInfoEntry *function_die = NULL;
1839 DWARFDebugInfoEntry *block_die = NULL;
Greg Claytond7cb26e2010-11-10 23:42:09 +00001840 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner24943d22010-06-08 16:52:24 +00001841
1842 if (function_die != NULL)
1843 {
1844 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1845 if (sc.function == NULL)
Greg Claytond7cb26e2010-11-10 23:42:09 +00001846 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner24943d22010-06-08 16:52:24 +00001847 }
1848
1849 if (sc.function != NULL)
1850 {
Greg Clayton75ccf502010-08-21 02:22:51 +00001851 Block& block = sc.function->GetBlock (true);
Chris Lattner24943d22010-06-08 16:52:24 +00001852
1853 if (block_die != NULL)
Greg Clayton75ccf502010-08-21 02:22:51 +00001854 sc.block = block.FindBlockByID (block_die->GetOffset());
Chris Lattner24943d22010-06-08 16:52:24 +00001855 else
Greg Clayton75ccf502010-08-21 02:22:51 +00001856 sc.block = block.FindBlockByID (function_die->GetOffset());
Chris Lattner24943d22010-06-08 16:52:24 +00001857 }
1858 }
1859 }
1860
1861 sc_list.Append(sc);
1862 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1863 }
1864 }
1865 }
1866 else if (file_spec_matches_cu_file_spec && !check_inlines)
1867 {
1868 // only append the context if we aren't looking for inline call sites
1869 // by file and line and if the file spec matches that of the compile unit
1870 sc_list.Append(sc);
1871 }
1872 }
1873 else if (file_spec_matches_cu_file_spec && !check_inlines)
1874 {
1875 // only append the context if we aren't looking for inline call sites
1876 // by file and line and if the file spec matches that of the compile unit
1877 sc_list.Append(sc);
1878 }
1879
1880 if (!check_inlines)
1881 break;
1882 }
1883 }
1884 }
1885 }
1886 return sc_list.GetSize() - prev_size;
1887}
1888
1889void
1890SymbolFileDWARF::Index ()
1891{
1892 if (m_indexed)
1893 return;
1894 m_indexed = true;
1895 Timer scoped_timer (__PRETTY_FUNCTION__,
1896 "SymbolFileDWARF::Index (%s)",
1897 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1898
1899 DWARFDebugInfo* debug_info = DebugInfo();
1900 if (debug_info)
1901 {
1902 uint32_t cu_idx = 0;
1903 const uint32_t num_compile_units = GetNumCompileUnits();
1904 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1905 {
Greg Claytond7cb26e2010-11-10 23:42:09 +00001906 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner24943d22010-06-08 16:52:24 +00001907
Greg Claytond7cb26e2010-11-10 23:42:09 +00001908 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner24943d22010-06-08 16:52:24 +00001909
Greg Claytond7cb26e2010-11-10 23:42:09 +00001910 curr_cu->Index (cu_idx,
Greg Clayton3bc52d02010-11-14 22:13:40 +00001911 m_function_basename_index,
1912 m_function_fullname_index,
1913 m_function_method_index,
1914 m_function_selector_index,
1915 m_objc_class_selectors_index,
1916 m_global_index,
1917 m_type_index,
Greg Clayton144188b2011-09-12 23:21:58 +00001918 m_namespace_index);
Chris Lattner24943d22010-06-08 16:52:24 +00001919
1920 // Keep memory down by clearing DIEs if this generate function
1921 // caused them to be parsed
1922 if (clear_dies)
Greg Claytond7cb26e2010-11-10 23:42:09 +00001923 curr_cu->ClearDIEs (true);
Chris Lattner24943d22010-06-08 16:52:24 +00001924 }
1925
Greg Clayton144188b2011-09-12 23:21:58 +00001926 m_function_basename_index.Finalize();
1927 m_function_fullname_index.Finalize();
1928 m_function_method_index.Finalize();
1929 m_function_selector_index.Finalize();
1930 m_objc_class_selectors_index.Finalize();
1931 m_global_index.Finalize();
1932 m_type_index.Finalize();
1933 m_namespace_index.Finalize();
Greg Clayton74124752010-09-15 04:15:46 +00001934
Greg Claytonfb7c51c2010-10-13 03:15:28 +00001935#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bb069b2011-02-09 23:39:34 +00001936 StreamFile s(stdout, false);
Greg Claytonc8cf5e22011-09-01 23:16:13 +00001937 s.Printf ("DWARF index for '%s/%s':",
Greg Claytonfb7c51c2010-10-13 03:15:28 +00001938 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1939 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytone4b9df02010-11-13 22:57:37 +00001940 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
1941 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
1942 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
1943 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
1944 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
1945 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Claytonfcf06fb2010-10-15 02:03:22 +00001946 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytone4b9df02010-11-13 22:57:37 +00001947 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Clayton74124752010-09-15 04:15:46 +00001948#endif
Chris Lattner24943d22010-06-08 16:52:24 +00001949 }
1950}
1951
1952uint32_t
1953SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1954{
Greg Clayton74124752010-09-15 04:15:46 +00001955 DWARFDebugInfo* info = DebugInfo();
1956 if (info == NULL)
1957 return 0;
Chris Lattner24943d22010-06-08 16:52:24 +00001958
1959 // If we aren't appending the results to this list, then clear the list
1960 if (!append)
1961 variables.Clear();
1962
1963 // Remember how many variables are in the list before we search in case
1964 // we are appending the results to a variable list.
1965 const uint32_t original_size = variables.GetSize();
1966
1967 // Index the DWARF if we haven't already
1968 if (!m_indexed)
1969 Index ();
1970
Greg Clayton74124752010-09-15 04:15:46 +00001971 SymbolContext sc;
Greg Clayton02e210c2011-09-17 07:23:18 +00001972 sc.module_sp = m_obj_file->GetModule();
Greg Clayton74124752010-09-15 04:15:46 +00001973 assert (sc.module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +00001974
Greg Clayton144188b2011-09-12 23:21:58 +00001975 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton74124752010-09-15 04:15:46 +00001976 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton144188b2011-09-12 23:21:58 +00001977 DIEArray die_offsets;
1978 const size_t num_matches = m_global_index.Find (name, die_offsets);
1979 if (num_matches)
Chris Lattner24943d22010-06-08 16:52:24 +00001980 {
Greg Clayton144188b2011-09-12 23:21:58 +00001981 DWARFDebugInfo* debug_info = DebugInfo();
1982 for (size_t i=0; i<num_matches; ++i)
1983 {
1984 const dw_offset_t die_offset = die_offsets[i];
1985 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Chris Lattner24943d22010-06-08 16:52:24 +00001986
Greg Clayton144188b2011-09-12 23:21:58 +00001987 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
1988 assert(sc.comp_unit != NULL);
Chris Lattner24943d22010-06-08 16:52:24 +00001989
Greg Clayton144188b2011-09-12 23:21:58 +00001990 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner24943d22010-06-08 16:52:24 +00001991
Greg Clayton144188b2011-09-12 23:21:58 +00001992 if (variables.GetSize() - original_size >= max_matches)
1993 break;
1994 }
Chris Lattner24943d22010-06-08 16:52:24 +00001995 }
1996
1997 // Return the number of variable that were appended to the list
1998 return variables.GetSize() - original_size;
1999}
2000
2001uint32_t
2002SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2003{
Greg Clayton74124752010-09-15 04:15:46 +00002004 DWARFDebugInfo* info = DebugInfo();
2005 if (info == NULL)
2006 return 0;
Chris Lattner24943d22010-06-08 16:52:24 +00002007
2008 // If we aren't appending the results to this list, then clear the list
2009 if (!append)
2010 variables.Clear();
2011
2012 // Remember how many variables are in the list before we search in case
2013 // we are appending the results to a variable list.
2014 const uint32_t original_size = variables.GetSize();
2015
2016 // Index the DWARF if we haven't already
2017 if (!m_indexed)
2018 Index ();
2019
Greg Clayton74124752010-09-15 04:15:46 +00002020 SymbolContext sc;
Greg Clayton02e210c2011-09-17 07:23:18 +00002021 sc.module_sp = m_obj_file->GetModule();
Greg Clayton74124752010-09-15 04:15:46 +00002022 assert (sc.module_sp);
2023
Greg Clayton144188b2011-09-12 23:21:58 +00002024 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton74124752010-09-15 04:15:46 +00002025 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton144188b2011-09-12 23:21:58 +00002026 DIEArray die_offsets;
2027 const size_t num_matches = m_global_index.Find (regex, die_offsets);
2028 if (num_matches)
Chris Lattner24943d22010-06-08 16:52:24 +00002029 {
Greg Clayton144188b2011-09-12 23:21:58 +00002030 DWARFDebugInfo* debug_info = DebugInfo();
2031 for (size_t i=0; i<num_matches; ++i)
2032 {
2033 const dw_offset_t die_offset = die_offsets[i];
2034 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2035 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2036 assert(sc.comp_unit != NULL);
Chris Lattner24943d22010-06-08 16:52:24 +00002037
Greg Clayton144188b2011-09-12 23:21:58 +00002038 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner24943d22010-06-08 16:52:24 +00002039
Greg Clayton144188b2011-09-12 23:21:58 +00002040 if (variables.GetSize() - original_size >= max_matches)
2041 break;
2042 }
Chris Lattner24943d22010-06-08 16:52:24 +00002043 }
2044
2045 // Return the number of variable that were appended to the list
2046 return variables.GetSize() - original_size;
2047}
2048
2049
Greg Claytond74270e2011-09-02 04:03:59 +00002050uint32_t
2051SymbolFileDWARF::ResolveFunctions (const DIEArray &die_offsets,
2052 SymbolContextList& sc_list)
2053{
2054 DWARFDebugInfo* info = DebugInfo();
2055 if (info == NULL)
2056 return 0;
2057
2058 const uint32_t sc_list_initial_size = sc_list.GetSize();
2059 SymbolContext sc;
Greg Clayton02e210c2011-09-17 07:23:18 +00002060 sc.module_sp = m_obj_file->GetModule();
Greg Claytond74270e2011-09-02 04:03:59 +00002061 assert (sc.module_sp);
2062
2063 DWARFCompileUnit* dwarf_cu = NULL;
2064 const size_t num_matches = die_offsets.size();
2065 for (size_t i=0; i<num_matches; ++i)
2066 {
2067 const dw_offset_t die_offset = die_offsets[i];
2068 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2069
2070 const DWARFDebugInfoEntry* inlined_die = NULL;
2071 if (die->Tag() == DW_TAG_inlined_subroutine)
2072 {
2073 inlined_die = die;
2074
2075 while ((die = die->GetParent()) != NULL)
2076 {
2077 if (die->Tag() == DW_TAG_subprogram)
2078 break;
2079 }
2080 }
2081 assert (die->Tag() == DW_TAG_subprogram);
2082 if (GetFunction (dwarf_cu, die, sc))
2083 {
2084 Address addr;
2085 // Parse all blocks if needed
2086 if (inlined_die)
2087 {
2088 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2089 assert (sc.block != NULL);
2090 if (sc.block->GetStartAddress (addr) == false)
2091 addr.Clear();
2092 }
2093 else
2094 {
2095 sc.block = NULL;
2096 addr = sc.function->GetAddressRange().GetBaseAddress();
2097 }
2098
2099 if (addr.IsValid())
2100 {
2101
2102 // We found the function, so we should find the line table
2103 // and line table entry as well
2104 LineTable *line_table = sc.comp_unit->GetLineTable();
2105 if (line_table == NULL)
2106 {
2107 if (ParseCompileUnitLineTable(sc))
2108 line_table = sc.comp_unit->GetLineTable();
2109 }
2110 if (line_table != NULL)
2111 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2112
2113 sc_list.Append(sc);
2114 }
2115 }
2116 }
2117 return sc_list.GetSize() - sc_list_initial_size;
2118}
2119
Greg Clayton12bec712010-06-28 21:30:43 +00002120void
2121SymbolFileDWARF::FindFunctions
2122(
2123 const ConstString &name,
Greg Clayton74124752010-09-15 04:15:46 +00002124 const NameToDIE &name_to_die,
Greg Clayton12bec712010-06-28 21:30:43 +00002125 SymbolContextList& sc_list
2126)
Chris Lattner24943d22010-06-08 16:52:24 +00002127{
Greg Clayton74124752010-09-15 04:15:46 +00002128 DWARFDebugInfo* info = DebugInfo();
2129 if (info == NULL)
2130 return;
Chris Lattner24943d22010-06-08 16:52:24 +00002131
Greg Clayton74124752010-09-15 04:15:46 +00002132 SymbolContext sc;
Greg Clayton02e210c2011-09-17 07:23:18 +00002133 sc.module_sp = m_obj_file->GetModule();
Greg Clayton74124752010-09-15 04:15:46 +00002134 assert (sc.module_sp);
2135
Greg Clayton144188b2011-09-12 23:21:58 +00002136 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton74124752010-09-15 04:15:46 +00002137 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton144188b2011-09-12 23:21:58 +00002138 DIEArray die_offsets;
2139 const size_t num_matches = name_to_die.Find (name, die_offsets);
2140 if (num_matches)
Greg Clayton74124752010-09-15 04:15:46 +00002141 {
Greg Clayton144188b2011-09-12 23:21:58 +00002142 DWARFDebugInfo* debug_info = DebugInfo();
2143 for (size_t i=0; i<num_matches; ++i)
Greg Claytonfeb6e562010-11-14 00:22:48 +00002144 {
Greg Clayton144188b2011-09-12 23:21:58 +00002145 const dw_offset_t die_offset = die_offsets[i];
2146 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2147 const DWARFDebugInfoEntry* inlined_die = NULL;
2148 if (die->Tag() == DW_TAG_inlined_subroutine)
Greg Claytonfeb6e562010-11-14 00:22:48 +00002149 {
Greg Clayton144188b2011-09-12 23:21:58 +00002150 inlined_die = die;
2151
2152 while ((die = die->GetParent()) != NULL)
Greg Claytonfeb6e562010-11-14 00:22:48 +00002153 {
Greg Clayton144188b2011-09-12 23:21:58 +00002154 if (die->Tag() == DW_TAG_subprogram)
2155 break;
Greg Claytonfeb6e562010-11-14 00:22:48 +00002156 }
Greg Clayton144188b2011-09-12 23:21:58 +00002157 }
2158 assert (die->Tag() == DW_TAG_subprogram);
2159 if (GetFunction (dwarf_cu, die, sc))
2160 {
2161 Address addr;
2162 // Parse all blocks if needed
2163 if (inlined_die)
2164 {
2165 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2166 assert (sc.block != NULL);
2167 if (sc.block->GetStartAddress (addr) == false)
2168 addr.Clear();
2169 }
2170 else
2171 {
2172 sc.block = NULL;
2173 addr = sc.function->GetAddressRange().GetBaseAddress();
2174 }
Greg Claytonfeb6e562010-11-14 00:22:48 +00002175
Greg Clayton144188b2011-09-12 23:21:58 +00002176 if (addr.IsValid())
2177 {
2178
2179 // We found the function, so we should find the line table
2180 // and line table entry as well
2181 LineTable *line_table = sc.comp_unit->GetLineTable();
2182 if (line_table == NULL)
2183 {
2184 if (ParseCompileUnitLineTable(sc))
2185 line_table = sc.comp_unit->GetLineTable();
2186 }
2187 if (line_table != NULL)
2188 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2189
2190 sc_list.Append(sc);
2191 }
Greg Claytonfeb6e562010-11-14 00:22:48 +00002192 }
Chris Lattner24943d22010-06-08 16:52:24 +00002193 }
2194 }
Greg Clayton74124752010-09-15 04:15:46 +00002195}
Chris Lattner24943d22010-06-08 16:52:24 +00002196
Greg Clayton74124752010-09-15 04:15:46 +00002197
2198void
2199SymbolFileDWARF::FindFunctions
2200(
2201 const RegularExpression &regex,
2202 const NameToDIE &name_to_die,
2203 SymbolContextList& sc_list
2204)
2205{
2206 DWARFDebugInfo* info = DebugInfo();
2207 if (info == NULL)
2208 return;
2209
2210 SymbolContext sc;
Greg Clayton02e210c2011-09-17 07:23:18 +00002211 sc.module_sp = m_obj_file->GetModule();
Greg Clayton74124752010-09-15 04:15:46 +00002212 assert (sc.module_sp);
2213
Greg Clayton144188b2011-09-12 23:21:58 +00002214 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton74124752010-09-15 04:15:46 +00002215 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton144188b2011-09-12 23:21:58 +00002216 DIEArray die_offsets;
2217 const size_t num_matches = name_to_die.Find (regex, die_offsets);
2218 if (num_matches)
Greg Clayton74124752010-09-15 04:15:46 +00002219 {
Greg Clayton144188b2011-09-12 23:21:58 +00002220 DWARFDebugInfo* debug_info = DebugInfo();
2221 for (size_t i=0; i<num_matches; ++i)
Greg Clayton1cee7ab2010-12-03 17:49:14 +00002222 {
Greg Clayton144188b2011-09-12 23:21:58 +00002223 const dw_offset_t die_offset = die_offsets[i];
2224 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2225
2226 const DWARFDebugInfoEntry* inlined_die = NULL;
2227 if (die->Tag() == DW_TAG_inlined_subroutine)
Greg Clayton1cee7ab2010-12-03 17:49:14 +00002228 {
Greg Clayton144188b2011-09-12 23:21:58 +00002229 inlined_die = die;
2230
2231 while ((die = die->GetParent()) != NULL)
Greg Clayton1cee7ab2010-12-03 17:49:14 +00002232 {
Greg Clayton144188b2011-09-12 23:21:58 +00002233 if (die->Tag() == DW_TAG_subprogram)
2234 break;
Greg Clayton1cee7ab2010-12-03 17:49:14 +00002235 }
Greg Clayton144188b2011-09-12 23:21:58 +00002236 }
2237 assert (die->Tag() == DW_TAG_subprogram);
2238 if (GetFunction (dwarf_cu, die, sc))
2239 {
2240 Address addr;
2241 // Parse all blocks if needed
2242 if (inlined_die)
2243 {
2244 sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2245 assert (sc.block != NULL);
2246 if (sc.block->GetStartAddress (addr) == false)
2247 addr.Clear();
2248 }
2249 else
2250 {
2251 sc.block = NULL;
2252 addr = sc.function->GetAddressRange().GetBaseAddress();
2253 }
Greg Clayton1cee7ab2010-12-03 17:49:14 +00002254
Greg Clayton144188b2011-09-12 23:21:58 +00002255 if (addr.IsValid())
2256 {
2257
2258 // We found the function, so we should find the line table
2259 // and line table entry as well
2260 LineTable *line_table = sc.comp_unit->GetLineTable();
2261 if (line_table == NULL)
2262 {
2263 if (ParseCompileUnitLineTable(sc))
2264 line_table = sc.comp_unit->GetLineTable();
2265 }
2266 if (line_table != NULL)
2267 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2268
2269 sc_list.Append(sc);
2270 }
Greg Clayton1cee7ab2010-12-03 17:49:14 +00002271 }
Greg Clayton74124752010-09-15 04:15:46 +00002272 }
2273 }
Greg Clayton12bec712010-06-28 21:30:43 +00002274}
2275
2276uint32_t
2277SymbolFileDWARF::FindFunctions
2278(
2279 const ConstString &name,
2280 uint32_t name_type_mask,
2281 bool append,
2282 SymbolContextList& sc_list
2283)
2284{
2285 Timer scoped_timer (__PRETTY_FUNCTION__,
2286 "SymbolFileDWARF::FindFunctions (name = '%s')",
2287 name.AsCString());
2288
Greg Clayton12bec712010-06-28 21:30:43 +00002289 // If we aren't appending the results to this list, then clear the list
2290 if (!append)
2291 sc_list.Clear();
2292
2293 // Remember how many sc_list are in the list before we search in case
2294 // we are appending the results to a variable list.
Greg Claytond74270e2011-09-02 04:03:59 +00002295
Greg Claytonf6e3de22011-09-28 17:06:40 +00002296 if (m_apple_names.IsValid())
Greg Claytond74270e2011-09-02 04:03:59 +00002297 {
2298 DIEArray die_offsets;
Greg Claytonf6e3de22011-09-28 17:06:40 +00002299 const uint32_t num_matches = m_apple_names.Find(name.GetCString(), die_offsets);
Greg Claytond74270e2011-09-02 04:03:59 +00002300 if (num_matches > 0)
2301 {
2302 return ResolveFunctions (die_offsets, sc_list);
2303 }
2304 return 0;
2305 }
2306
2307 const uint32_t original_size = sc_list.GetSize();
Greg Clayton12bec712010-06-28 21:30:43 +00002308
2309 // Index the DWARF if we haven't already
2310 if (!m_indexed)
2311 Index ();
2312
2313 if (name_type_mask & eFunctionNameTypeBase)
Greg Clayton74124752010-09-15 04:15:46 +00002314 FindFunctions (name, m_function_basename_index, sc_list);
Greg Clayton12bec712010-06-28 21:30:43 +00002315
2316 if (name_type_mask & eFunctionNameTypeFull)
Greg Clayton74124752010-09-15 04:15:46 +00002317 FindFunctions (name, m_function_fullname_index, sc_list);
Greg Clayton12bec712010-06-28 21:30:43 +00002318
2319 if (name_type_mask & eFunctionNameTypeMethod)
Greg Clayton74124752010-09-15 04:15:46 +00002320 FindFunctions (name, m_function_method_index, sc_list);
Greg Clayton12bec712010-06-28 21:30:43 +00002321
2322 if (name_type_mask & eFunctionNameTypeSelector)
Greg Clayton74124752010-09-15 04:15:46 +00002323 FindFunctions (name, m_function_selector_index, sc_list);
Greg Clayton12bec712010-06-28 21:30:43 +00002324
Chris Lattner24943d22010-06-08 16:52:24 +00002325 // Return the number of variable that were appended to the list
2326 return sc_list.GetSize() - original_size;
2327}
2328
2329
2330uint32_t
2331SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2332{
2333 Timer scoped_timer (__PRETTY_FUNCTION__,
2334 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2335 regex.GetText());
2336
Chris Lattner24943d22010-06-08 16:52:24 +00002337 // If we aren't appending the results to this list, then clear the list
2338 if (!append)
2339 sc_list.Clear();
2340
2341 // Remember how many sc_list are in the list before we search in case
2342 // we are appending the results to a variable list.
2343 uint32_t original_size = sc_list.GetSize();
2344
2345 // Index the DWARF if we haven't already
2346 if (!m_indexed)
2347 Index ();
2348
Greg Clayton74124752010-09-15 04:15:46 +00002349 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +00002350
Greg Clayton74124752010-09-15 04:15:46 +00002351 FindFunctions (regex, m_function_fullname_index, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +00002352
2353 // Return the number of variable that were appended to the list
2354 return sc_list.GetSize() - original_size;
2355}
Jim Ingham54548922011-08-26 19:44:13 +00002356
Greg Clayton7dd98df2011-07-12 17:06:17 +00002357void
2358SymbolFileDWARF::ReportError (const char *format, ...)
2359{
2360 ::fprintf (stderr,
2361 "error: %s/%s ",
2362 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2363 m_obj_file->GetFileSpec().GetFilename().GetCString());
2364
2365 va_list args;
2366 va_start (args, format);
2367 vfprintf (stderr, format, args);
2368 va_end (args);
2369}
Chris Lattner24943d22010-06-08 16:52:24 +00002370
Chris Lattner24943d22010-06-08 16:52:24 +00002371uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +00002372SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner24943d22010-06-08 16:52:24 +00002373{
Greg Clayton74124752010-09-15 04:15:46 +00002374 DWARFDebugInfo* info = DebugInfo();
2375 if (info == NULL)
2376 return 0;
2377
Chris Lattner24943d22010-06-08 16:52:24 +00002378 // If we aren't appending the results to this list, then clear the list
2379 if (!append)
2380 types.Clear();
2381
Greg Clayton1924e242010-09-15 05:51:24 +00002382 // Index if we already haven't to make sure the compile units
2383 // get indexed and make their global DIE index list
2384 if (!m_indexed)
2385 Index ();
Greg Clayton960d6a42010-08-03 00:35:52 +00002386
Greg Clayton74124752010-09-15 04:15:46 +00002387 const uint32_t initial_types_size = types.GetSize();
Greg Clayton144188b2011-09-12 23:21:58 +00002388 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton74124752010-09-15 04:15:46 +00002389 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton144188b2011-09-12 23:21:58 +00002390 DIEArray die_offsets;
2391 const size_t num_matches = m_type_index.Find (name, die_offsets);
2392 if (num_matches)
Chris Lattner24943d22010-06-08 16:52:24 +00002393 {
Greg Clayton144188b2011-09-12 23:21:58 +00002394 DWARFDebugInfo* debug_info = DebugInfo();
2395 for (size_t i=0; i<num_matches; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00002396 {
Greg Clayton144188b2011-09-12 23:21:58 +00002397 const dw_offset_t die_offset = die_offsets[i];
2398 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2399
2400 Type *matching_type = ResolveType (dwarf_cu, die);
2401 if (matching_type)
Greg Clayton63afdb02011-06-17 01:22:15 +00002402 {
Greg Clayton144188b2011-09-12 23:21:58 +00002403 // We found a type pointer, now find the shared pointer form our type list
2404 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
2405 if (type_sp)
2406 {
2407 types.InsertUnique (type_sp);
2408 if (types.GetSize() >= max_matches)
2409 break;
2410 }
2411 else
2412 {
2413 fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID());
2414 }
Greg Clayton63afdb02011-06-17 01:22:15 +00002415 }
Chris Lattner24943d22010-06-08 16:52:24 +00002416 }
Chris Lattner24943d22010-06-08 16:52:24 +00002417 }
Greg Clayton74124752010-09-15 04:15:46 +00002418 return types.GetSize() - initial_types_size;
Chris Lattner24943d22010-06-08 16:52:24 +00002419}
2420
2421
Greg Clayton6916e352010-11-13 03:52:47 +00002422ClangNamespaceDecl
Greg Claytond7cb26e2010-11-10 23:42:09 +00002423SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2424 const ConstString &name)
2425{
Greg Clayton6916e352010-11-13 03:52:47 +00002426 ClangNamespaceDecl namespace_decl;
Greg Claytond7cb26e2010-11-10 23:42:09 +00002427 DWARFDebugInfo* info = DebugInfo();
Greg Clayton6916e352010-11-13 03:52:47 +00002428 if (info)
Greg Claytond7cb26e2010-11-10 23:42:09 +00002429 {
Greg Clayton6916e352010-11-13 03:52:47 +00002430 // Index if we already haven't to make sure the compile units
2431 // get indexed and make their global DIE index list
2432 if (!m_indexed)
2433 Index ();
Greg Claytond7cb26e2010-11-10 23:42:09 +00002434
Greg Clayton144188b2011-09-12 23:21:58 +00002435
2436 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton6916e352010-11-13 03:52:47 +00002437 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton144188b2011-09-12 23:21:58 +00002438 DIEArray die_offsets;
2439 const size_t num_matches = m_namespace_index.Find (name, die_offsets);
2440 if (num_matches)
Greg Clayton6916e352010-11-13 03:52:47 +00002441 {
Greg Clayton144188b2011-09-12 23:21:58 +00002442 DWARFDebugInfo* debug_info = DebugInfo();
2443 for (size_t i=0; i<num_matches; ++i)
Greg Clayton6916e352010-11-13 03:52:47 +00002444 {
Greg Clayton144188b2011-09-12 23:21:58 +00002445 const dw_offset_t die_offset = die_offsets[i];
2446 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2447
2448 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
2449 if (clang_namespace_decl)
2450 {
2451 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2452 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2453 }
Greg Clayton6916e352010-11-13 03:52:47 +00002454 }
2455 }
Greg Claytond7cb26e2010-11-10 23:42:09 +00002456 }
Greg Clayton6916e352010-11-13 03:52:47 +00002457 return namespace_decl;
Greg Claytond7cb26e2010-11-10 23:42:09 +00002458}
2459
Chris Lattner24943d22010-06-08 16:52:24 +00002460uint32_t
Greg Clayton960d6a42010-08-03 00:35:52 +00002461SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner24943d22010-06-08 16:52:24 +00002462{
2463 // Remember how many sc_list are in the list before we search in case
2464 // we are appending the results to a variable list.
Greg Clayton960d6a42010-08-03 00:35:52 +00002465 uint32_t original_size = types.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +00002466
2467 const uint32_t num_die_offsets = die_offsets.size();
2468 // Parse all of the types we found from the pubtypes matches
2469 uint32_t i;
2470 uint32_t num_matches = 0;
2471 for (i = 0; i < num_die_offsets; ++i)
2472 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002473 Type *matching_type = ResolveTypeUID (die_offsets[i]);
2474 if (matching_type)
Chris Lattner24943d22010-06-08 16:52:24 +00002475 {
Greg Clayton960d6a42010-08-03 00:35:52 +00002476 // We found a type pointer, now find the shared pointer form our type list
Greg Claytone98ac252010-11-10 04:57:04 +00002477 TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
Greg Clayton960d6a42010-08-03 00:35:52 +00002478 assert (type_sp.get() != NULL);
2479 types.InsertUnique (type_sp);
2480 ++num_matches;
2481 if (num_matches >= max_matches)
2482 break;
Chris Lattner24943d22010-06-08 16:52:24 +00002483 }
2484 }
2485
2486 // Return the number of variable that were appended to the list
Greg Clayton960d6a42010-08-03 00:35:52 +00002487 return types.GetSize() - original_size;
Chris Lattner24943d22010-06-08 16:52:24 +00002488}
2489
Chris Lattner24943d22010-06-08 16:52:24 +00002490
2491size_t
Greg Claytonc5dca6c2011-08-12 06:47:54 +00002492SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
2493 clang::DeclContext *containing_decl_ctx,
2494 TypeSP& type_sp,
2495 DWARFCompileUnit* dwarf_cu,
2496 const DWARFDebugInfoEntry *parent_die,
2497 bool skip_artificial,
2498 bool &is_static,
2499 TypeList* type_list,
2500 std::vector<clang_type_t>& function_param_types,
2501 std::vector<clang::ParmVarDecl*>& function_param_decls,
2502 unsigned &type_quals)
Chris Lattner24943d22010-06-08 16:52:24 +00002503{
2504 if (parent_die == NULL)
2505 return 0;
2506
Greg Clayton5fcff9a2010-09-15 08:33:30 +00002507 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2508
Greg Clayton2403b5e2010-11-16 02:10:54 +00002509 size_t arg_idx = 0;
Chris Lattner24943d22010-06-08 16:52:24 +00002510 const DWARFDebugInfoEntry *die;
2511 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2512 {
2513 dw_tag_t tag = die->Tag();
2514 switch (tag)
2515 {
2516 case DW_TAG_formal_parameter:
2517 {
2518 DWARFDebugInfoEntry::Attributes attributes;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00002519 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00002520 if (num_attributes > 0)
2521 {
2522 const char *name = NULL;
2523 Declaration decl;
2524 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Clayton412440a2010-09-23 01:09:21 +00002525 bool is_artificial = false;
Chris Lattner24943d22010-06-08 16:52:24 +00002526 // one of None, Auto, Register, Extern, Static, PrivateExtern
2527
Sean Callanan47a5c4c2010-09-23 03:01:22 +00002528 clang::StorageClass storage = clang::SC_None;
Chris Lattner24943d22010-06-08 16:52:24 +00002529 uint32_t i;
2530 for (i=0; i<num_attributes; ++i)
2531 {
2532 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2533 DWARFFormValue form_value;
2534 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2535 {
2536 switch (attr)
2537 {
2538 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2539 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2540 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2541 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
2542 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton412440a2010-09-23 01:09:21 +00002543 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner24943d22010-06-08 16:52:24 +00002544 case DW_AT_location:
2545 // if (form_value.BlockData())
2546 // {
2547 // const DataExtractor& debug_info_data = debug_info();
2548 // uint32_t block_length = form_value.Unsigned();
2549 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2550 // }
2551 // else
2552 // {
2553 // }
2554 // break;
Chris Lattner24943d22010-06-08 16:52:24 +00002555 case DW_AT_const_value:
2556 case DW_AT_default_value:
2557 case DW_AT_description:
2558 case DW_AT_endianity:
2559 case DW_AT_is_optional:
2560 case DW_AT_segment:
2561 case DW_AT_variable_parameter:
2562 default:
2563 case DW_AT_abstract_origin:
2564 case DW_AT_sibling:
2565 break;
2566 }
2567 }
2568 }
Greg Clayton412440a2010-09-23 01:09:21 +00002569
Greg Clayton1d8173f2010-09-24 05:15:53 +00002570 bool skip = false;
2571 if (skip_artificial)
Chris Lattner24943d22010-06-08 16:52:24 +00002572 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00002573 if (is_artificial)
Greg Clayton2403b5e2010-11-16 02:10:54 +00002574 {
2575 // In order to determine if a C++ member function is
2576 // "const" we have to look at the const-ness of "this"...
2577 // Ugly, but that
2578 if (arg_idx == 0)
2579 {
Greg Claytonc5dca6c2011-08-12 06:47:54 +00002580 if (containing_decl_ctx->getDeclKind() == clang::Decl::CXXRecord)
Sean Callanan99309902011-08-02 22:21:50 +00002581 {
Greg Claytonc5dca6c2011-08-12 06:47:54 +00002582 // Often times compilers omit the "this" name for the
2583 // specification DIEs, so we can't rely upon the name
2584 // being in the formal parameter DIE...
2585 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton2403b5e2010-11-16 02:10:54 +00002586 {
Greg Claytonc5dca6c2011-08-12 06:47:54 +00002587 Type *this_type = ResolveTypeUID (param_type_die_offset);
2588 if (this_type)
2589 {
2590 uint32_t encoding_mask = this_type->GetEncodingMask();
2591 if (encoding_mask & Type::eEncodingIsPointerUID)
2592 {
2593 is_static = false;
2594
2595 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
2596 type_quals |= clang::Qualifiers::Const;
2597 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
2598 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton2403b5e2010-11-16 02:10:54 +00002599 }
2600 }
2601 }
2602 }
2603 }
Greg Clayton1d8173f2010-09-24 05:15:53 +00002604 skip = true;
Greg Clayton2403b5e2010-11-16 02:10:54 +00002605 }
Greg Clayton1d8173f2010-09-24 05:15:53 +00002606 else
2607 {
Chris Lattner24943d22010-06-08 16:52:24 +00002608
Greg Clayton1d8173f2010-09-24 05:15:53 +00002609 // HACK: Objective C formal parameters "self" and "_cmd"
2610 // are not marked as artificial in the DWARF...
Greg Claytond7cb26e2010-11-10 23:42:09 +00002611 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2612 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton1d8173f2010-09-24 05:15:53 +00002613 {
2614 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2615 skip = true;
2616 }
2617 }
2618 }
2619
2620 if (!skip)
2621 {
2622 Type *type = ResolveTypeUID(param_type_die_offset);
2623 if (type)
2624 {
Greg Claytonb433a3d2010-10-01 20:48:32 +00002625 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton1d8173f2010-09-24 05:15:53 +00002626
Greg Claytone98ac252010-11-10 04:57:04 +00002627 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton1d8173f2010-09-24 05:15:53 +00002628 assert(param_var_decl);
2629 function_param_decls.push_back(param_var_decl);
2630 }
Chris Lattner24943d22010-06-08 16:52:24 +00002631 }
2632 }
Greg Clayton2403b5e2010-11-16 02:10:54 +00002633 arg_idx++;
Chris Lattner24943d22010-06-08 16:52:24 +00002634 }
2635 break;
2636
2637 default:
2638 break;
2639 }
2640 }
Greg Clayton2403b5e2010-11-16 02:10:54 +00002641 return arg_idx;
Chris Lattner24943d22010-06-08 16:52:24 +00002642}
2643
2644size_t
2645SymbolFileDWARF::ParseChildEnumerators
2646(
2647 const SymbolContext& sc,
Greg Clayton462d4142010-09-29 01:12:09 +00002648 clang_type_t enumerator_clang_type,
Chris Lattner24943d22010-06-08 16:52:24 +00002649 uint32_t enumerator_byte_size,
Greg Clayton1d8173f2010-09-24 05:15:53 +00002650 DWARFCompileUnit* dwarf_cu,
Chris Lattner24943d22010-06-08 16:52:24 +00002651 const DWARFDebugInfoEntry *parent_die
2652)
2653{
2654 if (parent_die == NULL)
2655 return 0;
2656
2657 size_t enumerators_added = 0;
2658 const DWARFDebugInfoEntry *die;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00002659 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2660
Chris Lattner24943d22010-06-08 16:52:24 +00002661 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2662 {
2663 const dw_tag_t tag = die->Tag();
2664 if (tag == DW_TAG_enumerator)
2665 {
2666 DWARFDebugInfoEntry::Attributes attributes;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00002667 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00002668 if (num_child_attributes > 0)
2669 {
2670 const char *name = NULL;
2671 bool got_value = false;
2672 int64_t enum_value = 0;
2673 Declaration decl;
2674
2675 uint32_t i;
2676 for (i=0; i<num_child_attributes; ++i)
2677 {
2678 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2679 DWARFFormValue form_value;
2680 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2681 {
2682 switch (attr)
2683 {
2684 case DW_AT_const_value:
2685 got_value = true;
2686 enum_value = form_value.Unsigned();
2687 break;
2688
2689 case DW_AT_name:
2690 name = form_value.AsCString(&get_debug_str_data());
2691 break;
2692
2693 case DW_AT_description:
2694 default:
2695 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2696 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
2697 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2698 case DW_AT_sibling:
2699 break;
2700 }
2701 }
2702 }
2703
2704 if (name && name[0] && got_value)
2705 {
Greg Claytone98ac252010-11-10 04:57:04 +00002706 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2707 enumerator_clang_type,
2708 decl,
2709 name,
2710 enum_value,
2711 enumerator_byte_size * 8);
Chris Lattner24943d22010-06-08 16:52:24 +00002712 ++enumerators_added;
2713 }
2714 }
2715 }
2716 }
2717 return enumerators_added;
2718}
2719
2720void
2721SymbolFileDWARF::ParseChildArrayInfo
2722(
2723 const SymbolContext& sc,
Greg Clayton1d8173f2010-09-24 05:15:53 +00002724 DWARFCompileUnit* dwarf_cu,
Chris Lattner24943d22010-06-08 16:52:24 +00002725 const DWARFDebugInfoEntry *parent_die,
2726 int64_t& first_index,
2727 std::vector<uint64_t>& element_orders,
2728 uint32_t& byte_stride,
2729 uint32_t& bit_stride
2730)
2731{
2732 if (parent_die == NULL)
2733 return;
2734
2735 const DWARFDebugInfoEntry *die;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00002736 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +00002737 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2738 {
2739 const dw_tag_t tag = die->Tag();
2740 switch (tag)
2741 {
2742 case DW_TAG_enumerator:
2743 {
2744 DWARFDebugInfoEntry::Attributes attributes;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00002745 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00002746 if (num_child_attributes > 0)
2747 {
2748 const char *name = NULL;
2749 bool got_value = false;
2750 int64_t enum_value = 0;
2751
2752 uint32_t i;
2753 for (i=0; i<num_child_attributes; ++i)
2754 {
2755 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2756 DWARFFormValue form_value;
2757 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2758 {
2759 switch (attr)
2760 {
2761 case DW_AT_const_value:
2762 got_value = true;
2763 enum_value = form_value.Unsigned();
2764 break;
2765
2766 case DW_AT_name:
2767 name = form_value.AsCString(&get_debug_str_data());
2768 break;
2769
2770 case DW_AT_description:
2771 default:
2772 case DW_AT_decl_file:
2773 case DW_AT_decl_line:
2774 case DW_AT_decl_column:
2775 case DW_AT_sibling:
2776 break;
2777 }
2778 }
2779 }
2780 }
2781 }
2782 break;
2783
2784 case DW_TAG_subrange_type:
2785 {
2786 DWARFDebugInfoEntry::Attributes attributes;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00002787 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00002788 if (num_child_attributes > 0)
2789 {
2790 const char *name = NULL;
2791 bool got_value = false;
2792 uint64_t byte_size = 0;
2793 int64_t enum_value = 0;
2794 uint64_t num_elements = 0;
2795 uint64_t lower_bound = 0;
2796 uint64_t upper_bound = 0;
2797 uint32_t i;
2798 for (i=0; i<num_child_attributes; ++i)
2799 {
2800 const dw_attr_t attr = attributes.AttributeAtIndex(i);
2801 DWARFFormValue form_value;
2802 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2803 {
2804 switch (attr)
2805 {
2806 case DW_AT_const_value:
2807 got_value = true;
2808 enum_value = form_value.Unsigned();
2809 break;
2810
2811 case DW_AT_name:
2812 name = form_value.AsCString(&get_debug_str_data());
2813 break;
2814
2815 case DW_AT_count:
2816 num_elements = form_value.Unsigned();
2817 break;
2818
2819 case DW_AT_bit_stride:
2820 bit_stride = form_value.Unsigned();
2821 break;
2822
2823 case DW_AT_byte_stride:
2824 byte_stride = form_value.Unsigned();
2825 break;
2826
2827 case DW_AT_byte_size:
2828 byte_size = form_value.Unsigned();
2829 break;
2830
2831 case DW_AT_lower_bound:
2832 lower_bound = form_value.Unsigned();
2833 break;
2834
2835 case DW_AT_upper_bound:
2836 upper_bound = form_value.Unsigned();
2837 break;
2838
2839 default:
Chris Lattner24943d22010-06-08 16:52:24 +00002840 case DW_AT_abstract_origin:
2841 case DW_AT_accessibility:
2842 case DW_AT_allocated:
2843 case DW_AT_associated:
2844 case DW_AT_data_location:
2845 case DW_AT_declaration:
2846 case DW_AT_description:
2847 case DW_AT_sibling:
2848 case DW_AT_threads_scaled:
2849 case DW_AT_type:
2850 case DW_AT_visibility:
2851 break;
2852 }
2853 }
2854 }
2855
2856 if (upper_bound > lower_bound)
2857 num_elements = upper_bound - lower_bound + 1;
2858
2859 if (num_elements > 0)
2860 element_orders.push_back (num_elements);
2861 }
2862 }
2863 break;
2864 }
2865 }
2866}
2867
Chris Lattner24943d22010-06-08 16:52:24 +00002868TypeSP
Greg Claytond7cb26e2010-11-10 23:42:09 +00002869SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner24943d22010-06-08 16:52:24 +00002870{
2871 TypeSP type_sp;
2872 if (die != NULL)
2873 {
Greg Claytond7cb26e2010-11-10 23:42:09 +00002874 assert(curr_cu != NULL);
Greg Clayton4fb400f2010-09-27 21:07:38 +00002875 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner24943d22010-06-08 16:52:24 +00002876 if (type_ptr == NULL)
2877 {
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002878 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
2879 assert (lldb_cu);
2880 SymbolContext sc(lldb_cu);
Greg Claytond7cb26e2010-11-10 23:42:09 +00002881 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +00002882 }
2883 else if (type_ptr != DIE_IS_BEING_PARSED)
2884 {
2885 // Grab the existing type from the master types lists
Greg Claytone98ac252010-11-10 04:57:04 +00002886 type_sp = GetTypeList()->FindType(type_ptr->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00002887 }
2888
2889 }
2890 return type_sp;
2891}
2892
2893clang::DeclContext *
Sean Callananc617a4c2011-08-05 23:43:37 +00002894SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner24943d22010-06-08 16:52:24 +00002895{
2896 if (die_offset != DW_INVALID_OFFSET)
2897 {
2898 DWARFCompileUnitSP cu_sp;
2899 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Sean Callananc617a4c2011-08-05 23:43:37 +00002900 return GetClangDeclContextContainingDIE (cu_sp.get(), die);
Chris Lattner24943d22010-06-08 16:52:24 +00002901 }
2902 return NULL;
2903}
2904
Sean Callananc617a4c2011-08-05 23:43:37 +00002905clang::DeclContext *
2906SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
2907{
2908 if (die_offset != DW_INVALID_OFFSET)
2909 {
2910 DWARFCompileUnitSP cu_sp;
2911 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2912 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
2913 }
2914 return NULL;
2915}
Chris Lattner24943d22010-06-08 16:52:24 +00002916
Greg Claytond7cb26e2010-11-10 23:42:09 +00002917clang::NamespaceDecl *
2918SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2919{
2920 if (die->Tag() == DW_TAG_namespace)
2921 {
2922 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2923 if (namespace_name)
2924 {
2925 Declaration decl; // TODO: fill in the decl object
Sean Callananc617a4c2011-08-05 23:43:37 +00002926 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die->GetParent()));
Greg Claytond7cb26e2010-11-10 23:42:09 +00002927 if (namespace_decl)
Greg Claytone6d72ca2011-06-25 00:44:06 +00002928 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Claytond7cb26e2010-11-10 23:42:09 +00002929 return namespace_decl;
2930 }
2931 }
2932 return NULL;
2933}
Chris Lattner24943d22010-06-08 16:52:24 +00002934
2935clang::DeclContext *
Sean Callananc617a4c2011-08-05 23:43:37 +00002936SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2937{
2938 // If this DIE has a specification, or an abstract origin, then trace to those.
2939
2940 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
2941 if (die_offset != DW_INVALID_OFFSET)
2942 return GetClangDeclContextForDIEOffset (sc, die_offset);
2943
2944 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
2945 if (die_offset != DW_INVALID_OFFSET)
2946 return GetClangDeclContextForDIEOffset (sc, die_offset);
2947
2948 // This is the DIE we want. Parse it, then query our map.
2949
2950 ParseType(sc, curr_cu, die, NULL);
2951
2952 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2953 if (pos != m_die_to_decl_ctx.end())
2954 return pos->second;
2955 else
2956 return NULL;
2957}
2958
2959clang::DeclContext *
2960SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
Chris Lattner24943d22010-06-08 16:52:24 +00002961{
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002962 if (m_clang_tu_decl == NULL)
2963 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner24943d22010-06-08 16:52:24 +00002964
Sean Callananc617a4c2011-08-05 23:43:37 +00002965 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x )\n", die->GetOffset());
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002966 const DWARFDebugInfoEntry * const decl_die = die;
Greg Clayton78bce002011-01-25 06:17:32 +00002967 clang::DeclContext *decl_ctx = NULL;
2968
Chris Lattner24943d22010-06-08 16:52:24 +00002969 while (die != NULL)
2970 {
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002971 // If this is the original DIE that we are searching for a declaration
2972 // for, then don't look in the cache as we don't want our own decl
2973 // context to be our decl context...
2974 if (decl_die != die)
Chris Lattner24943d22010-06-08 16:52:24 +00002975 {
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002976 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2977 if (pos != m_die_to_decl_ctx.end())
Chris Lattner24943d22010-06-08 16:52:24 +00002978 {
Sean Callananc617a4c2011-08-05 23:43:37 +00002979 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002980 return pos->second;
Chris Lattner24943d22010-06-08 16:52:24 +00002981 }
Chris Lattner24943d22010-06-08 16:52:24 +00002982
Sean Callananc617a4c2011-08-05 23:43:37 +00002983 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002984
2985 switch (die->Tag())
2986 {
2987 case DW_TAG_namespace:
2988 {
2989 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2990 if (namespace_name)
2991 {
2992 Declaration decl; // TODO: fill in the decl object
Sean Callananc617a4c2011-08-05 23:43:37 +00002993 clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextContainingDIE (curr_cu, die));
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002994 if (namespace_decl)
2995 {
Sean Callananc617a4c2011-08-05 23:43:37 +00002996 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Claytone6d72ca2011-06-25 00:44:06 +00002997 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00002998 }
2999 return namespace_decl;
3000 }
3001 }
3002 break;
3003
3004 case DW_TAG_structure_type:
3005 case DW_TAG_union_type:
3006 case DW_TAG_class_type:
3007 {
Greg Clayton78bce002011-01-25 06:17:32 +00003008 Type* type = ResolveType (curr_cu, die);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003009 pos = m_die_to_decl_ctx.find(die);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003010 if (pos != m_die_to_decl_ctx.end())
3011 {
Sean Callananc617a4c2011-08-05 23:43:37 +00003012 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003013 return pos->second;
3014 }
Greg Clayton78bce002011-01-25 06:17:32 +00003015 else
3016 {
3017 if (type)
3018 {
3019 decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
Enrico Granata35bcafb2011-08-12 18:43:16 +00003020 LinkDeclContextToDIE (decl_ctx, die);
Greg Clayton78bce002011-01-25 06:17:32 +00003021 if (decl_ctx)
3022 return decl_ctx;
3023 }
3024 }
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003025 }
3026 break;
3027
3028 default:
3029 break;
3030 }
Chris Lattner24943d22010-06-08 16:52:24 +00003031 }
Chris Lattner24943d22010-06-08 16:52:24 +00003032
Greg Claytonb01000f2011-01-17 03:46:26 +00003033 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003034 if (die_offset != DW_INVALID_OFFSET)
3035 {
Sean Callananc617a4c2011-08-05 23:43:37 +00003036 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
3037 decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003038 if (decl_ctx != m_clang_tu_decl)
3039 return decl_ctx;
3040 }
3041
Greg Claytonb01000f2011-01-17 03:46:26 +00003042 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003043 if (die_offset != DW_INVALID_OFFSET)
3044 {
Sean Callananc617a4c2011-08-05 23:43:37 +00003045 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
3046 decl_ctx = GetClangDeclContextContainingDIEOffset (die_offset);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003047 if (decl_ctx != m_clang_tu_decl)
3048 return decl_ctx;
3049 }
Chris Lattner24943d22010-06-08 16:52:24 +00003050
3051 die = die->GetParent();
3052 }
Greg Claytone5748d82010-11-09 23:46:37 +00003053 // Right now we have only one translation unit per module...
Sean Callananc617a4c2011-08-05 23:43:37 +00003054 //printf ("SymbolFileDWARF::GetClangDeclContextContainingDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset());
Greg Claytone5748d82010-11-09 23:46:37 +00003055 return m_clang_tu_decl;
Chris Lattner24943d22010-06-08 16:52:24 +00003056}
3057
Greg Clayton95e33b72010-11-07 21:02:03 +00003058// This function can be used when a DIE is found that is a forward declaration
3059// DIE and we want to try and find a type that has the complete definition.
3060TypeSP
3061SymbolFileDWARF::FindDefinitionTypeForDIE (
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00003062 DWARFCompileUnit* cu,
Greg Clayton95e33b72010-11-07 21:02:03 +00003063 const DWARFDebugInfoEntry *die,
3064 const ConstString &type_name
3065)
3066{
3067 TypeSP type_sp;
3068
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00003069 if (cu == NULL || die == NULL || !type_name)
Greg Clayton95e33b72010-11-07 21:02:03 +00003070 return type_sp;
3071
Greg Clayton539d9452010-12-03 21:42:06 +00003072 if (!m_indexed)
3073 Index ();
3074
Greg Clayton95e33b72010-11-07 21:02:03 +00003075 const dw_tag_t type_tag = die->Tag();
Greg Clayton144188b2011-09-12 23:21:58 +00003076
3077 DWARFCompileUnit* type_cu = NULL;
3078 const DWARFDebugInfoEntry* type_die = NULL;
3079 DIEArray die_offsets;
3080 const size_t num_matches = m_type_index.Find (type_name, die_offsets);
3081 if (num_matches)
Greg Clayton95e33b72010-11-07 21:02:03 +00003082 {
Greg Clayton144188b2011-09-12 23:21:58 +00003083 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton95e33b72010-11-07 21:02:03 +00003084 for (size_t i=0; i<num_matches; ++i)
3085 {
Greg Clayton144188b2011-09-12 23:21:58 +00003086 const dw_offset_t die_offset = die_offsets[i];
3087 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
Greg Clayton95e33b72010-11-07 21:02:03 +00003088
3089 if (type_die != die && type_die->Tag() == type_tag)
3090 {
3091 // Hold off on comparing parent DIE tags until
3092 // we know what happens with stuff in namespaces
3093 // for gcc and clang...
3094 //DWARFDebugInfoEntry *parent_die = die->GetParent();
3095 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
3096 //if (parent_die->Tag() == parent_type_die->Tag())
3097 {
3098 Type *resolved_type = ResolveType (type_cu, type_die, false);
3099 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3100 {
3101 DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
3102 die->GetOffset(),
Greg Claytond7cb26e2010-11-10 23:42:09 +00003103 curr_cu->GetOffset(),
Greg Clayton95e33b72010-11-07 21:02:03 +00003104 m_obj_file->GetFileSpec().GetFilename().AsCString(),
3105 type_die->GetOffset(),
3106 type_cu->GetOffset());
3107
3108 m_die_to_type[die] = resolved_type;
Greg Claytone98ac252010-11-10 04:57:04 +00003109 type_sp = GetTypeList()->FindType(resolved_type->GetID());
Greg Claytoncc6f7cc2010-11-08 02:05:08 +00003110 if (!type_sp)
3111 {
3112 DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
3113 }
Greg Clayton95e33b72010-11-07 21:02:03 +00003114 break;
3115 }
3116 }
3117 }
3118 }
3119 }
3120 return type_sp;
3121}
3122
Chris Lattner24943d22010-06-08 16:52:24 +00003123TypeSP
Greg Clayton462d4142010-09-29 01:12:09 +00003124SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +00003125{
3126 TypeSP type_sp;
3127
Greg Clayton462d4142010-09-29 01:12:09 +00003128 if (type_is_new_ptr)
3129 *type_is_new_ptr = false;
3130
Sean Callanan70a4f922010-08-06 00:32:49 +00003131 AccessType accessibility = eAccessNone;
Chris Lattner24943d22010-06-08 16:52:24 +00003132 if (die != NULL)
3133 {
Jim Ingham9ecdaac2011-08-25 23:21:43 +00003134 Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
3135 if (log && dwarf_cu)
3136 {
Jim Ingham54548922011-08-26 19:44:13 +00003137 StreamString s;
Jim Ingham169c5fb2011-08-27 01:24:54 +00003138 die->DumpLocation (this, dwarf_cu, s);
Jim Ingham54548922011-08-26 19:44:13 +00003139 log->Printf ("SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
3140
Jim Ingham9ecdaac2011-08-25 23:21:43 +00003141 }
3142
Greg Clayton4fb400f2010-09-27 21:07:38 +00003143 Type *type_ptr = m_die_to_type.lookup (die);
Greg Claytone98ac252010-11-10 04:57:04 +00003144 TypeList* type_list = GetTypeList();
Greg Clayton4fb400f2010-09-27 21:07:38 +00003145 if (type_ptr == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00003146 {
Greg Claytone98ac252010-11-10 04:57:04 +00003147 ClangASTContext &ast = GetClangASTContext();
Greg Clayton462d4142010-09-29 01:12:09 +00003148 if (type_is_new_ptr)
3149 *type_is_new_ptr = true;
Chris Lattner24943d22010-06-08 16:52:24 +00003150
Greg Clayton4fb400f2010-09-27 21:07:38 +00003151 const dw_tag_t tag = die->Tag();
3152
Chris Lattner24943d22010-06-08 16:52:24 +00003153 bool is_forward_declaration = false;
3154 DWARFDebugInfoEntry::Attributes attributes;
3155 const char *type_name_cstr = NULL;
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003156 ConstString type_name_const_str;
Greg Clayton6916e352010-11-13 03:52:47 +00003157 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3158 size_t byte_size = 0;
Greg Claytonf1b73af2011-03-15 04:38:20 +00003159 bool byte_size_valid = false;
Greg Clayton6916e352010-11-13 03:52:47 +00003160 Declaration decl;
3161
Greg Clayton4b407112010-09-30 21:49:03 +00003162 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton462d4142010-09-29 01:12:09 +00003163 clang_type_t clang_type = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00003164
Chris Lattner24943d22010-06-08 16:52:24 +00003165 dw_attr_t attr;
3166
3167 switch (tag)
3168 {
3169 case DW_TAG_base_type:
3170 case DW_TAG_pointer_type:
3171 case DW_TAG_reference_type:
3172 case DW_TAG_typedef:
3173 case DW_TAG_const_type:
3174 case DW_TAG_restrict_type:
3175 case DW_TAG_volatile_type:
3176 {
Chris Lattner24943d22010-06-08 16:52:24 +00003177 // Set a bit that lets us know that we are currently parsing this
Greg Clayton4fb400f2010-09-27 21:07:38 +00003178 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner24943d22010-06-08 16:52:24 +00003179
Greg Clayton5fcff9a2010-09-15 08:33:30 +00003180 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00003181 uint32_t encoding = 0;
Chris Lattner24943d22010-06-08 16:52:24 +00003182 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3183
3184 if (num_attributes > 0)
3185 {
3186 uint32_t i;
3187 for (i=0; i<num_attributes; ++i)
3188 {
3189 attr = attributes.AttributeAtIndex(i);
3190 DWARFFormValue form_value;
3191 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3192 {
3193 switch (attr)
3194 {
3195 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3196 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3197 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3198 case DW_AT_name:
Jim Ingham87a58ce2011-04-15 23:41:23 +00003199
Chris Lattner24943d22010-06-08 16:52:24 +00003200 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham87a58ce2011-04-15 23:41:23 +00003201 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3202 // include the "&"...
3203 if (tag == DW_TAG_reference_type)
3204 {
3205 if (strchr (type_name_cstr, '&') == NULL)
3206 type_name_cstr = NULL;
3207 }
3208 if (type_name_cstr)
3209 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00003210 break;
Greg Claytonf1b73af2011-03-15 04:38:20 +00003211 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner24943d22010-06-08 16:52:24 +00003212 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3213 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3214 default:
3215 case DW_AT_sibling:
3216 break;
3217 }
3218 }
3219 }
3220 }
3221
Greg Claytonb433a3d2010-10-01 20:48:32 +00003222 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);
3223
Chris Lattner24943d22010-06-08 16:52:24 +00003224 switch (tag)
3225 {
3226 default:
Greg Clayton6916e352010-11-13 03:52:47 +00003227 break;
3228
Chris Lattner24943d22010-06-08 16:52:24 +00003229 case DW_TAG_base_type:
Greg Clayton6916e352010-11-13 03:52:47 +00003230 resolve_state = Type::eResolveStateFull;
Greg Claytone98ac252010-11-10 04:57:04 +00003231 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3232 encoding,
3233 byte_size * 8);
Chris Lattner24943d22010-06-08 16:52:24 +00003234 break;
3235
Greg Clayton6916e352010-11-13 03:52:47 +00003236 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3237 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3238 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3239 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3240 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3241 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner24943d22010-06-08 16:52:24 +00003242 }
3243
Greg Clayton960d6a42010-08-03 00:35:52 +00003244 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3245 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3246 {
3247 static ConstString g_objc_type_name_id("id");
3248 static ConstString g_objc_type_name_Class("Class");
3249 static ConstString g_objc_type_name_selector("SEL");
3250
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003251 if (type_name_const_str == g_objc_type_name_id)
Greg Clayton960d6a42010-08-03 00:35:52 +00003252 {
Greg Claytone98ac252010-11-10 04:57:04 +00003253 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton6916e352010-11-13 03:52:47 +00003254 resolve_state = Type::eResolveStateFull;
3255
Greg Clayton960d6a42010-08-03 00:35:52 +00003256 }
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003257 else if (type_name_const_str == g_objc_type_name_Class)
Greg Clayton960d6a42010-08-03 00:35:52 +00003258 {
Greg Claytone98ac252010-11-10 04:57:04 +00003259 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton6916e352010-11-13 03:52:47 +00003260 resolve_state = Type::eResolveStateFull;
Greg Clayton960d6a42010-08-03 00:35:52 +00003261 }
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003262 else if (type_name_const_str == g_objc_type_name_selector)
Greg Clayton960d6a42010-08-03 00:35:52 +00003263 {
Sean Callananc4217a62010-12-06 23:53:20 +00003264 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton6916e352010-11-13 03:52:47 +00003265 resolve_state = Type::eResolveStateFull;
Greg Clayton960d6a42010-08-03 00:35:52 +00003266 }
3267 }
3268
Greg Claytone98ac252010-11-10 04:57:04 +00003269 type_sp.reset( new Type (die->GetOffset(),
3270 this,
3271 type_name_const_str,
3272 byte_size,
3273 NULL,
3274 encoding_uid,
3275 encoding_data_type,
3276 &decl,
3277 clang_type,
Greg Clayton6916e352010-11-13 03:52:47 +00003278 resolve_state));
Greg Claytone98ac252010-11-10 04:57:04 +00003279
Greg Clayton4fb400f2010-09-27 21:07:38 +00003280 m_die_to_type[die] = type_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +00003281
3282// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3283// if (encoding_type != NULL)
3284// {
3285// if (encoding_type != DIE_IS_BEING_PARSED)
3286// type_sp->SetEncodingType(encoding_type);
3287// else
3288// m_indirect_fixups.push_back(type_sp.get());
3289// }
3290 }
3291 break;
3292
3293 case DW_TAG_structure_type:
3294 case DW_TAG_union_type:
3295 case DW_TAG_class_type:
3296 {
Chris Lattner24943d22010-06-08 16:52:24 +00003297 // Set a bit that lets us know that we are currently parsing this
Greg Clayton4fb400f2010-09-27 21:07:38 +00003298 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner24943d22010-06-08 16:52:24 +00003299
Greg Clayton9488b742010-07-28 02:04:09 +00003300 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner24943d22010-06-08 16:52:24 +00003301 //bool struct_is_class = false;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00003302 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00003303 if (num_attributes > 0)
3304 {
3305 uint32_t i;
3306 for (i=0; i<num_attributes; ++i)
3307 {
3308 attr = attributes.AttributeAtIndex(i);
3309 DWARFFormValue form_value;
3310 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3311 {
3312 switch (attr)
3313 {
Greg Clayton9488b742010-07-28 02:04:09 +00003314 case DW_AT_decl_file:
3315 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3316 break;
3317
3318 case DW_AT_decl_line:
3319 decl.SetLine(form_value.Unsigned());
3320 break;
3321
3322 case DW_AT_decl_column:
3323 decl.SetColumn(form_value.Unsigned());
3324 break;
3325
Chris Lattner24943d22010-06-08 16:52:24 +00003326 case DW_AT_name:
3327 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003328 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00003329 break;
Greg Clayton9488b742010-07-28 02:04:09 +00003330
3331 case DW_AT_byte_size:
3332 byte_size = form_value.Unsigned();
Greg Claytonf1b73af2011-03-15 04:38:20 +00003333 byte_size_valid = true;
Greg Clayton9488b742010-07-28 02:04:09 +00003334 break;
3335
3336 case DW_AT_accessibility:
3337 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3338 break;
3339
3340 case DW_AT_declaration:
Greg Claytone5748d82010-11-09 23:46:37 +00003341 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9488b742010-07-28 02:04:09 +00003342 break;
3343
3344 case DW_AT_APPLE_runtime_class:
3345 class_language = (LanguageType)form_value.Signed();
3346 break;
3347
Chris Lattner24943d22010-06-08 16:52:24 +00003348 case DW_AT_allocated:
3349 case DW_AT_associated:
3350 case DW_AT_data_location:
3351 case DW_AT_description:
3352 case DW_AT_start_scope:
3353 case DW_AT_visibility:
3354 default:
3355 case DW_AT_sibling:
3356 break;
3357 }
3358 }
3359 }
3360 }
3361
Greg Claytona8d42412011-02-09 19:06:17 +00003362 UniqueDWARFASTType unique_ast_entry;
3363 if (decl.IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +00003364 {
Greg Claytonc3c46612011-02-15 00:19:15 +00003365 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Greg Claytonf1b73af2011-03-15 04:38:20 +00003366 this,
3367 dwarf_cu,
Greg Claytonc3c46612011-02-15 00:19:15 +00003368 die,
3369 decl,
Greg Claytonf1b73af2011-03-15 04:38:20 +00003370 byte_size_valid ? byte_size : -1,
Greg Claytonc3c46612011-02-15 00:19:15 +00003371 unique_ast_entry))
Greg Clayton57452832010-11-09 04:42:43 +00003372 {
Greg Claytona8d42412011-02-09 19:06:17 +00003373 // We have already parsed this type or from another
3374 // compile unit. GCC loves to use the "one definition
3375 // rule" which can result in multiple definitions
3376 // of the same class over and over in each compile
3377 // unit.
3378 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton52fd9842011-02-02 02:24:04 +00003379 if (type_sp)
3380 {
Greg Clayton52fd9842011-02-02 02:24:04 +00003381 m_die_to_type[die] = type_sp.get();
3382 return type_sp;
3383 }
3384 }
Greg Claytona8d42412011-02-09 19:06:17 +00003385 }
3386
3387 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3388
3389 int tag_decl_kind = -1;
3390 AccessType default_accessibility = eAccessNone;
3391 if (tag == DW_TAG_structure_type)
3392 {
3393 tag_decl_kind = clang::TTK_Struct;
3394 default_accessibility = eAccessPublic;
3395 }
3396 else if (tag == DW_TAG_union_type)
3397 {
3398 tag_decl_kind = clang::TTK_Union;
3399 default_accessibility = eAccessPublic;
3400 }
3401 else if (tag == DW_TAG_class_type)
3402 {
3403 tag_decl_kind = clang::TTK_Class;
3404 default_accessibility = eAccessPrivate;
3405 }
3406
3407
3408 if (is_forward_declaration)
3409 {
3410 // We have a forward declaration to a type and we need
3411 // to try and find a full declaration. We look in the
3412 // current type index just in case we have a forward
3413 // declaration followed by an actual declarations in the
3414 // DWARF. If this fails, we need to look elsewhere...
3415
3416 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3417
3418 if (!type_sp && m_debug_map_symfile)
Greg Clayton52fd9842011-02-02 02:24:04 +00003419 {
Greg Claytona8d42412011-02-09 19:06:17 +00003420 // We weren't able to find a full declaration in
3421 // this DWARF, see if we have a declaration anywhere
3422 // else...
3423 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton52fd9842011-02-02 02:24:04 +00003424 }
3425
Greg Claytona8d42412011-02-09 19:06:17 +00003426 if (type_sp)
Greg Clayton52fd9842011-02-02 02:24:04 +00003427 {
Greg Claytona8d42412011-02-09 19:06:17 +00003428 // We found a real definition for this type elsewhere
3429 // so lets use it and cache the fact that we found
3430 // a complete type for this die
3431 m_die_to_type[die] = type_sp.get();
3432 return type_sp;
Greg Clayton52fd9842011-02-02 02:24:04 +00003433 }
Greg Claytona8d42412011-02-09 19:06:17 +00003434 }
3435 assert (tag_decl_kind != -1);
3436 bool clang_type_was_created = false;
3437 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3438 if (clang_type == NULL)
3439 {
3440 clang_type_was_created = true;
3441 clang_type = ast.CreateRecordType (type_name_cstr,
3442 tag_decl_kind,
Sean Callananc617a4c2011-08-05 23:43:37 +00003443 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Claytona8d42412011-02-09 19:06:17 +00003444 class_language);
3445 }
3446
3447 // Store a forward declaration to this class type in case any
3448 // parameters in any class methods need it for the clang
Greg Claytone6d72ca2011-06-25 00:44:06 +00003449 // types for function prototypes.
3450 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
Greg Claytona8d42412011-02-09 19:06:17 +00003451 type_sp.reset (new Type (die->GetOffset(),
3452 this,
3453 type_name_const_str,
3454 byte_size,
3455 NULL,
3456 LLDB_INVALID_UID,
3457 Type::eEncodingIsUID,
3458 &decl,
3459 clang_type,
3460 Type::eResolveStateForward));
3461
3462
3463 // Add our type to the unique type map so we don't
3464 // end up creating many copies of the same type over
3465 // and over in the ASTContext for our module
3466 unique_ast_entry.m_type_sp = type_sp;
Greg Claytonf1b73af2011-03-15 04:38:20 +00003467 unique_ast_entry.m_symfile = this;
3468 unique_ast_entry.m_cu = dwarf_cu;
Greg Claytona8d42412011-02-09 19:06:17 +00003469 unique_ast_entry.m_die = die;
3470 unique_ast_entry.m_declaration = decl;
Greg Claytonc3c46612011-02-15 00:19:15 +00003471 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
3472 unique_ast_entry);
Greg Claytona8d42412011-02-09 19:06:17 +00003473
3474 if (die->HasChildren() == false && is_forward_declaration == false)
3475 {
3476 // No children for this struct/union/class, lets finish it
3477 ast.StartTagDeclarationDefinition (clang_type);
3478 ast.CompleteTagDeclarationDefinition (clang_type);
3479 }
3480 else if (clang_type_was_created)
3481 {
3482 // Leave this as a forward declaration until we need
3483 // to know the details of the type. lldb_private::Type
3484 // will automatically call the SymbolFile virtual function
3485 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3486 // When the definition needs to be defined.
3487 m_forward_decl_die_to_clang_type[die] = clang_type;
3488 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3489 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Clayton57452832010-11-09 04:42:43 +00003490 }
Chris Lattner24943d22010-06-08 16:52:24 +00003491 }
3492 break;
3493
3494 case DW_TAG_enumeration_type:
3495 {
Chris Lattner24943d22010-06-08 16:52:24 +00003496 // Set a bit that lets us know that we are currently parsing this
Greg Clayton4fb400f2010-09-27 21:07:38 +00003497 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner24943d22010-06-08 16:52:24 +00003498
Chris Lattner24943d22010-06-08 16:52:24 +00003499 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner24943d22010-06-08 16:52:24 +00003500
Greg Clayton5fcff9a2010-09-15 08:33:30 +00003501 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00003502 if (num_attributes > 0)
3503 {
3504 uint32_t i;
3505
3506 for (i=0; i<num_attributes; ++i)
3507 {
3508 attr = attributes.AttributeAtIndex(i);
3509 DWARFFormValue form_value;
3510 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3511 {
3512 switch (attr)
3513 {
Greg Claytone5748d82010-11-09 23:46:37 +00003514 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3515 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3516 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner24943d22010-06-08 16:52:24 +00003517 case DW_AT_name:
3518 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003519 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00003520 break;
Greg Claytone5748d82010-11-09 23:46:37 +00003521 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
Greg Claytonf1b73af2011-03-15 04:38:20 +00003522 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Greg Claytone5748d82010-11-09 23:46:37 +00003523 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3524 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner24943d22010-06-08 16:52:24 +00003525 case DW_AT_allocated:
3526 case DW_AT_associated:
3527 case DW_AT_bit_stride:
3528 case DW_AT_byte_stride:
3529 case DW_AT_data_location:
3530 case DW_AT_description:
3531 case DW_AT_start_scope:
3532 case DW_AT_visibility:
3533 case DW_AT_specification:
3534 case DW_AT_abstract_origin:
3535 case DW_AT_sibling:
3536 break;
3537 }
3538 }
3539 }
3540
Greg Claytonb433a3d2010-10-01 20:48:32 +00003541 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3542
Greg Clayton462d4142010-09-29 01:12:09 +00003543 clang_type_t enumerator_clang_type = NULL;
3544 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3545 if (clang_type == NULL)
3546 {
Greg Claytone98ac252010-11-10 04:57:04 +00003547 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3548 DW_ATE_signed,
3549 byte_size * 8);
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003550 clang_type = ast.CreateEnumerationType (type_name_cstr,
Sean Callananc617a4c2011-08-05 23:43:37 +00003551 GetClangDeclContextContainingDIE (dwarf_cu, die),
Greg Clayton0d62dfd2011-01-14 04:54:56 +00003552 decl,
Greg Claytone98ac252010-11-10 04:57:04 +00003553 enumerator_clang_type);
Greg Clayton462d4142010-09-29 01:12:09 +00003554 }
3555 else
3556 {
3557 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3558 assert (enumerator_clang_type != NULL);
3559 }
3560
Greg Claytone6d72ca2011-06-25 00:44:06 +00003561 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
3562
Greg Claytone98ac252010-11-10 04:57:04 +00003563 type_sp.reset( new Type (die->GetOffset(),
3564 this,
3565 type_name_const_str,
3566 byte_size,
3567 NULL,
3568 encoding_uid,
3569 Type::eEncodingIsUID,
3570 &decl,
3571 clang_type,
Greg Clayton6916e352010-11-13 03:52:47 +00003572 Type::eResolveStateForward));
Chris Lattner24943d22010-06-08 16:52:24 +00003573
Greg Claytonb01000f2011-01-17 03:46:26 +00003574#if LEAVE_ENUMS_FORWARD_DECLARED
Greg Clayton462d4142010-09-29 01:12:09 +00003575 // Leave this as a forward declaration until we need
3576 // to know the details of the type. lldb_private::Type
3577 // will automatically call the SymbolFile virtual function
3578 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3579 // When the definition needs to be defined.
3580 m_forward_decl_die_to_clang_type[die] = clang_type;
Greg Claytonb433a3d2010-10-01 20:48:32 +00003581 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
Greg Claytonb01000f2011-01-17 03:46:26 +00003582 ClangASTContext::SetHasExternalStorage (clang_type, true);
3583#else
3584 ast.StartTagDeclarationDefinition (clang_type);
3585 if (die->HasChildren())
3586 {
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00003587 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3588 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Claytonb01000f2011-01-17 03:46:26 +00003589 }
3590 ast.CompleteTagDeclarationDefinition (clang_type);
3591#endif
Chris Lattner24943d22010-06-08 16:52:24 +00003592 }
3593 }
3594 break;
3595
Jim Ingham0007dff2010-08-12 01:20:14 +00003596 case DW_TAG_inlined_subroutine:
Chris Lattner24943d22010-06-08 16:52:24 +00003597 case DW_TAG_subprogram:
3598 case DW_TAG_subroutine_type:
3599 {
Chris Lattner24943d22010-06-08 16:52:24 +00003600 // Set a bit that lets us know that we are currently parsing this
Greg Clayton4fb400f2010-09-27 21:07:38 +00003601 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner24943d22010-06-08 16:52:24 +00003602
3603 const char *mangled = NULL;
3604 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Clayton412440a2010-09-23 01:09:21 +00003605 bool is_variadic = false;
Chris Lattner24943d22010-06-08 16:52:24 +00003606 bool is_inline = false;
Greg Clayton1d8173f2010-09-24 05:15:53 +00003607 bool is_static = false;
3608 bool is_virtual = false;
Greg Clayton30449d52010-10-01 02:31:07 +00003609 bool is_explicit = false;
Greg Clayton6c3e4af2011-08-16 18:40:23 +00003610 dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
3611 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
Greg Clayton1d8173f2010-09-24 05:15:53 +00003612
Chris Lattner24943d22010-06-08 16:52:24 +00003613 unsigned type_quals = 0;
Sean Callanan47a5c4c2010-09-23 03:01:22 +00003614 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner24943d22010-06-08 16:52:24 +00003615
3616
Greg Clayton5fcff9a2010-09-15 08:33:30 +00003617 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00003618 if (num_attributes > 0)
3619 {
3620 uint32_t i;
3621 for (i=0; i<num_attributes; ++i)
3622 {
Greg Claytonbdcb6ab2011-01-25 23:55:37 +00003623 attr = attributes.AttributeAtIndex(i);
Chris Lattner24943d22010-06-08 16:52:24 +00003624 DWARFFormValue form_value;
3625 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3626 {
3627 switch (attr)
3628 {
3629 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3630 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3631 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3632 case DW_AT_name:
3633 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003634 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00003635 break;
3636
3637 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3638 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton84f80752010-07-22 18:30:50 +00003639 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Claytone5748d82010-11-09 23:46:37 +00003640 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton1d8173f2010-09-24 05:15:53 +00003641 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
3642 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Clayton30449d52010-10-01 02:31:07 +00003643 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
3644
Chris Lattner24943d22010-06-08 16:52:24 +00003645 case DW_AT_external:
3646 if (form_value.Unsigned())
3647 {
Sean Callanan47a5c4c2010-09-23 03:01:22 +00003648 if (storage == clang::SC_None)
3649 storage = clang::SC_Extern;
Chris Lattner24943d22010-06-08 16:52:24 +00003650 else
Sean Callanan47a5c4c2010-09-23 03:01:22 +00003651 storage = clang::SC_PrivateExtern;
Chris Lattner24943d22010-06-08 16:52:24 +00003652 }
3653 break;
Chris Lattner24943d22010-06-08 16:52:24 +00003654
Greg Clayton6c3e4af2011-08-16 18:40:23 +00003655 case DW_AT_specification:
3656 specification_die_offset = form_value.Reference(dwarf_cu);
3657 break;
3658
3659 case DW_AT_abstract_origin:
3660 abstract_origin_die_offset = form_value.Reference(dwarf_cu);
3661 break;
3662
3663
Chris Lattner24943d22010-06-08 16:52:24 +00003664 case DW_AT_allocated:
3665 case DW_AT_associated:
3666 case DW_AT_address_class:
3667 case DW_AT_artificial:
3668 case DW_AT_calling_convention:
3669 case DW_AT_data_location:
3670 case DW_AT_elemental:
3671 case DW_AT_entry_pc:
Chris Lattner24943d22010-06-08 16:52:24 +00003672 case DW_AT_frame_base:
3673 case DW_AT_high_pc:
3674 case DW_AT_low_pc:
3675 case DW_AT_object_pointer:
3676 case DW_AT_prototyped:
3677 case DW_AT_pure:
3678 case DW_AT_ranges:
3679 case DW_AT_recursive:
3680 case DW_AT_return_addr:
3681 case DW_AT_segment:
Chris Lattner24943d22010-06-08 16:52:24 +00003682 case DW_AT_start_scope:
3683 case DW_AT_static_link:
3684 case DW_AT_trampoline:
3685 case DW_AT_visibility:
Chris Lattner24943d22010-06-08 16:52:24 +00003686 case DW_AT_vtable_elem_location:
Chris Lattner24943d22010-06-08 16:52:24 +00003687 case DW_AT_description:
3688 case DW_AT_sibling:
3689 break;
3690 }
3691 }
3692 }
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003693 }
Chris Lattner24943d22010-06-08 16:52:24 +00003694
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003695 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonb433a3d2010-10-01 20:48:32 +00003696
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003697 clang_type_t return_clang_type = NULL;
3698 Type *func_type = NULL;
3699
3700 if (type_die_offset != DW_INVALID_OFFSET)
3701 func_type = ResolveTypeUID(type_die_offset);
Greg Clayton30449d52010-10-01 02:31:07 +00003702
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003703 if (func_type)
Greg Clayton6916e352010-11-13 03:52:47 +00003704 return_clang_type = func_type->GetClangLayoutType();
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003705 else
Greg Claytone98ac252010-11-10 04:57:04 +00003706 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner24943d22010-06-08 16:52:24 +00003707
Greg Clayton30449d52010-10-01 02:31:07 +00003708
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003709 std::vector<clang_type_t> function_param_types;
3710 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner24943d22010-06-08 16:52:24 +00003711
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003712 // Parse the function children for the parameters
Sean Callanan99309902011-08-02 22:21:50 +00003713
Greg Claytonc5dca6c2011-08-12 06:47:54 +00003714 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die);
3715 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
3716
3717 const bool is_cxx_method = containing_decl_kind == clang::Decl::CXXRecord;
3718 // Start off static. This will be set to false in ParseChildParameters(...)
3719 // if we find a "this" paramters as the first parameter
3720 if (is_cxx_method)
Sean Callanan99309902011-08-02 22:21:50 +00003721 is_static = true;
3722
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003723 if (die->HasChildren())
3724 {
Greg Clayton1d8173f2010-09-24 05:15:53 +00003725 bool skip_artificial = true;
Greg Claytone98ac252010-11-10 04:57:04 +00003726 ParseChildParameters (sc,
Greg Claytonc5dca6c2011-08-12 06:47:54 +00003727 containing_decl_ctx,
Greg Claytone98ac252010-11-10 04:57:04 +00003728 type_sp,
3729 dwarf_cu,
3730 die,
Sean Callanan99309902011-08-02 22:21:50 +00003731 skip_artificial,
3732 is_static,
Greg Claytone98ac252010-11-10 04:57:04 +00003733 type_list,
3734 function_param_types,
Greg Clayton2403b5e2010-11-16 02:10:54 +00003735 function_param_decls,
3736 type_quals);
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003737 }
Chris Lattner24943d22010-06-08 16:52:24 +00003738
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003739 // clang_type will get the function prototype clang type after this call
Greg Claytone98ac252010-11-10 04:57:04 +00003740 clang_type = ast.CreateFunctionType (return_clang_type,
3741 &function_param_types[0],
3742 function_param_types.size(),
3743 is_variadic,
3744 type_quals);
3745
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003746 if (type_name_cstr)
3747 {
3748 bool type_handled = false;
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003749 if (tag == DW_TAG_subprogram)
Chris Lattner24943d22010-06-08 16:52:24 +00003750 {
Jim Inghamfdf24ef2011-09-08 22:13:49 +00003751 if (ObjCLanguageRuntime::IsPossibleObjCMethodName (type_name_cstr))
Greg Clayton1d8173f2010-09-24 05:15:53 +00003752 {
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003753 // We need to find the DW_TAG_class_type or
3754 // DW_TAG_struct_type by name so we can add this
3755 // as a member function of the class.
3756 const char *class_name_start = type_name_cstr + 2;
3757 const char *class_name_end = ::strchr (class_name_start, ' ');
3758 SymbolContext empty_sc;
3759 clang_type_t class_opaque_type = NULL;
3760 if (class_name_start < class_name_end)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003761 {
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003762 ConstString class_name (class_name_start, class_name_end - class_name_start);
3763 TypeList types;
3764 const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3765 if (match_count > 0)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003766 {
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003767 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003768 {
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003769 Type *type = types.GetTypeAtIndex (i).get();
3770 clang_type_t type_clang_forward_type = type->GetClangForwardType();
3771 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton1d8173f2010-09-24 05:15:53 +00003772 {
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003773 class_opaque_type = type_clang_forward_type;
3774 break;
Greg Clayton1d8173f2010-09-24 05:15:53 +00003775 }
3776 }
3777 }
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003778 }
Greg Clayton1d8173f2010-09-24 05:15:53 +00003779
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003780 if (class_opaque_type)
3781 {
3782 // If accessibility isn't set to anything valid, assume public for
3783 // now...
3784 if (accessibility == eAccessNone)
3785 accessibility = eAccessPublic;
3786
3787 clang::ObjCMethodDecl *objc_method_decl;
Greg Claytone98ac252010-11-10 04:57:04 +00003788 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3789 type_name_cstr,
3790 clang_type,
3791 accessibility);
Greg Claytona83f8772011-08-04 21:02:57 +00003792 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003793 type_handled = objc_method_decl != NULL;
3794 }
3795 }
Greg Claytonc5dca6c2011-08-12 06:47:54 +00003796 else if (is_cxx_method)
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003797 {
3798 // Look at the parent of this DIE and see if is is
3799 // a class or struct and see if this is actually a
3800 // C++ method
Greg Claytonc5dca6c2011-08-12 06:47:54 +00003801 Type *class_type = ResolveType (dwarf_cu, m_decl_ctx_to_die[containing_decl_ctx]);
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003802 if (class_type)
3803 {
Greg Clayton6c3e4af2011-08-16 18:40:23 +00003804 if (specification_die_offset != DW_INVALID_OFFSET)
Greg Clayton1d8173f2010-09-24 05:15:53 +00003805 {
Greg Clayton6c3e4af2011-08-16 18:40:23 +00003806 // If we have a specification, then the function type should have been
3807 // made with the specification and not with this die.
3808 DWARFCompileUnitSP spec_cu_sp;
3809 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
3810 if (m_die_to_decl_ctx[spec_die] == NULL)
3811 fprintf (stderr,"warning: 0x%8.8x: DW_AT_specification(0x%8.8x) has no decl\n", die->GetOffset(), specification_die_offset);
3812 type_handled = true;
3813 }
3814 else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
3815 {
3816 DWARFCompileUnitSP abs_cu_sp;
3817 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
3818 if (m_die_to_decl_ctx[abs_die] == NULL)
3819 fprintf (stderr,"warning: 0x%8.8x: DW_AT_abstract_origin(0x%8.8x) has no decl\n", die->GetOffset(), abstract_origin_die_offset);
3820 type_handled = true;
3821 }
3822 else
3823 {
3824 clang_type_t class_opaque_type = class_type->GetClangForwardType();
3825 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton28d5fcc2011-01-27 06:44:37 +00003826 {
Greg Clayton6c3e4af2011-08-16 18:40:23 +00003827 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3828 // in the DWARF for C++ methods... Default to public for now...
3829 if (accessibility == eAccessNone)
3830 accessibility = eAccessPublic;
3831
3832 if (!is_static && !die->HasChildren())
3833 {
3834 // We have a C++ member function with no children (this pointer!)
3835 // and clang will get mad if we try and make a function that isn't
3836 // well formed in the DWARF, so we will just skip it...
3837 type_handled = true;
3838 }
3839 else
3840 {
3841 clang::CXXMethodDecl *cxx_method_decl;
3842 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3843 type_name_cstr,
3844 clang_type,
3845 accessibility,
3846 is_virtual,
3847 is_static,
3848 is_inline,
3849 is_explicit);
3850 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
Greg Claytona83f8772011-08-04 21:02:57 +00003851
Greg Clayton6c3e4af2011-08-16 18:40:23 +00003852 type_handled = cxx_method_decl != NULL;
3853 }
Greg Clayton28d5fcc2011-01-27 06:44:37 +00003854 }
Greg Clayton1d8173f2010-09-24 05:15:53 +00003855 }
3856 }
Greg Clayton1d8173f2010-09-24 05:15:53 +00003857 }
Chris Lattner24943d22010-06-08 16:52:24 +00003858 }
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003859
3860 if (!type_handled)
3861 {
3862 // We just have a function that isn't part of a class
Greg Claytone98ac252010-11-10 04:57:04 +00003863 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3864 clang_type,
3865 storage,
3866 is_inline);
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003867
3868 // Add the decl to our DIE to decl context map
3869 assert (function_decl);
Greg Claytone6d72ca2011-06-25 00:44:06 +00003870 LinkDeclContextToDIE(function_decl, die);
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003871 if (!function_param_decls.empty())
Greg Claytone98ac252010-11-10 04:57:04 +00003872 ast.SetFunctionParameters (function_decl,
3873 &function_param_decls.front(),
3874 function_param_decls.size());
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003875 }
Chris Lattner24943d22010-06-08 16:52:24 +00003876 }
Greg Claytone98ac252010-11-10 04:57:04 +00003877 type_sp.reset( new Type (die->GetOffset(),
3878 this,
3879 type_name_const_str,
3880 0,
3881 NULL,
3882 LLDB_INVALID_UID,
3883 Type::eEncodingIsUID,
3884 &decl,
3885 clang_type,
Greg Claytona8d42412011-02-09 19:06:17 +00003886 Type::eResolveStateFull));
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003887 assert(type_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +00003888 }
3889 break;
3890
3891 case DW_TAG_array_type:
3892 {
Chris Lattner24943d22010-06-08 16:52:24 +00003893 // Set a bit that lets us know that we are currently parsing this
Greg Clayton4fb400f2010-09-27 21:07:38 +00003894 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner24943d22010-06-08 16:52:24 +00003895
Chris Lattner24943d22010-06-08 16:52:24 +00003896 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner24943d22010-06-08 16:52:24 +00003897 int64_t first_index = 0;
3898 uint32_t byte_stride = 0;
3899 uint32_t bit_stride = 0;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00003900 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00003901
3902 if (num_attributes > 0)
3903 {
3904 uint32_t i;
3905 for (i=0; i<num_attributes; ++i)
3906 {
3907 attr = attributes.AttributeAtIndex(i);
3908 DWARFFormValue form_value;
3909 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3910 {
3911 switch (attr)
3912 {
3913 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3914 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3915 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3916 case DW_AT_name:
3917 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Claytonfb7c51c2010-10-13 03:15:28 +00003918 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +00003919 break;
3920
3921 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytonf1b73af2011-03-15 04:38:20 +00003922 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner24943d22010-06-08 16:52:24 +00003923 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
3924 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton84f80752010-07-22 18:30:50 +00003925 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Claytone5748d82010-11-09 23:46:37 +00003926 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner24943d22010-06-08 16:52:24 +00003927 case DW_AT_allocated:
3928 case DW_AT_associated:
3929 case DW_AT_data_location:
3930 case DW_AT_description:
3931 case DW_AT_ordering:
3932 case DW_AT_start_scope:
3933 case DW_AT_visibility:
3934 case DW_AT_specification:
3935 case DW_AT_abstract_origin:
3936 case DW_AT_sibling:
3937 break;
3938 }
3939 }
3940 }
3941
Greg Claytonb433a3d2010-10-01 20:48:32 +00003942 DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3943
Chris Lattner24943d22010-06-08 16:52:24 +00003944 Type *element_type = ResolveTypeUID(type_die_offset);
3945
3946 if (element_type)
3947 {
3948 std::vector<uint64_t> element_orders;
3949 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytonaed58812010-09-13 02:37:44 +00003950 // We have an array that claims to have no members, lets give it at least one member...
3951 if (element_orders.empty())
3952 element_orders.push_back (1);
Chris Lattner24943d22010-06-08 16:52:24 +00003953 if (byte_stride == 0 && bit_stride == 0)
3954 byte_stride = element_type->GetByteSize();
Greg Clayton04c9c7b2011-02-16 23:00:21 +00003955 clang_type_t array_element_type = element_type->GetClangFullType();
Chris Lattner24943d22010-06-08 16:52:24 +00003956 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3957 uint64_t num_elements = 0;
3958 std::vector<uint64_t>::const_reverse_iterator pos;
3959 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3960 for (pos = element_orders.rbegin(); pos != end; ++pos)
3961 {
3962 num_elements = *pos;
Greg Claytone98ac252010-11-10 04:57:04 +00003963 clang_type = ast.CreateArrayType (array_element_type,
3964 num_elements,
3965 num_elements * array_element_bit_stride);
Chris Lattner24943d22010-06-08 16:52:24 +00003966 array_element_type = clang_type;
3967 array_element_bit_stride = array_element_bit_stride * num_elements;
3968 }
3969 ConstString empty_name;
Greg Claytone98ac252010-11-10 04:57:04 +00003970 type_sp.reset( new Type (die->GetOffset(),
3971 this,
3972 empty_name,
3973 array_element_bit_stride / 8,
3974 NULL,
Greg Clayton6916e352010-11-13 03:52:47 +00003975 type_die_offset,
Greg Claytone98ac252010-11-10 04:57:04 +00003976 Type::eEncodingIsUID,
3977 &decl,
3978 clang_type,
Greg Clayton6916e352010-11-13 03:52:47 +00003979 Type::eResolveStateFull));
3980 type_sp->SetEncodingType (element_type);
Chris Lattner24943d22010-06-08 16:52:24 +00003981 }
3982 }
3983 }
3984 break;
3985
Greg Claytonfa970692010-06-12 01:20:30 +00003986 case DW_TAG_ptr_to_member_type:
3987 {
3988 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3989 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3990
Greg Clayton5fcff9a2010-09-15 08:33:30 +00003991 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Claytonfa970692010-06-12 01:20:30 +00003992
3993 if (num_attributes > 0) {
3994 uint32_t i;
3995 for (i=0; i<num_attributes; ++i)
3996 {
3997 attr = attributes.AttributeAtIndex(i);
3998 DWARFFormValue form_value;
3999 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4000 {
4001 switch (attr)
4002 {
4003 case DW_AT_type:
4004 type_die_offset = form_value.Reference(dwarf_cu); break;
4005 case DW_AT_containing_type:
4006 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
4007 }
4008 }
4009 }
4010
4011 Type *pointee_type = ResolveTypeUID(type_die_offset);
4012 Type *class_type = ResolveTypeUID(containing_type_die_offset);
4013
Greg Clayton6916e352010-11-13 03:52:47 +00004014 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
4015 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Claytonfa970692010-06-12 01:20:30 +00004016
Greg Claytone98ac252010-11-10 04:57:04 +00004017 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
4018 class_clang_type);
Greg Claytonfa970692010-06-12 01:20:30 +00004019
Greg Clayton6916e352010-11-13 03:52:47 +00004020 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
4021 clang_type) / 8;
Greg Claytonfa970692010-06-12 01:20:30 +00004022
Greg Claytone98ac252010-11-10 04:57:04 +00004023 type_sp.reset( new Type (die->GetOffset(),
4024 this,
4025 type_name_const_str,
4026 byte_size,
4027 NULL,
4028 LLDB_INVALID_UID,
4029 Type::eEncodingIsUID,
4030 NULL,
4031 clang_type,
Greg Clayton6916e352010-11-13 03:52:47 +00004032 Type::eResolveStateForward));
Greg Claytonfa970692010-06-12 01:20:30 +00004033 }
4034
4035 break;
4036 }
Chris Lattner24943d22010-06-08 16:52:24 +00004037 default:
Greg Claytonfa970692010-06-12 01:20:30 +00004038 assert(false && "Unhandled type tag!");
Chris Lattner24943d22010-06-08 16:52:24 +00004039 break;
4040 }
4041
4042 if (type_sp.get())
4043 {
4044 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4045 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4046
4047 SymbolContextScope * symbol_context_scope = NULL;
4048 if (sc_parent_tag == DW_TAG_compile_unit)
4049 {
4050 symbol_context_scope = sc.comp_unit;
4051 }
4052 else if (sc.function != NULL)
4053 {
Greg Clayton75ccf502010-08-21 02:22:51 +00004054 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner24943d22010-06-08 16:52:24 +00004055 if (symbol_context_scope == NULL)
4056 symbol_context_scope = sc.function;
4057 }
4058
4059 if (symbol_context_scope != NULL)
4060 {
4061 type_sp->SetSymbolContextScope(symbol_context_scope);
4062 }
4063
Greg Claytona8d42412011-02-09 19:06:17 +00004064 // We are ready to put this type into the uniqued list up at the module level
4065 type_list->Insert (type_sp);
Greg Claytonad60bf42010-10-12 02:24:53 +00004066
Greg Claytona8d42412011-02-09 19:06:17 +00004067 m_die_to_type[die] = type_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +00004068 }
4069 }
Greg Clayton4fb400f2010-09-27 21:07:38 +00004070 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner24943d22010-06-08 16:52:24 +00004071 {
Greg Claytone98ac252010-11-10 04:57:04 +00004072 type_sp = type_list->FindType(type_ptr->GetID());
Chris Lattner24943d22010-06-08 16:52:24 +00004073 }
4074 }
4075 return type_sp;
4076}
4077
4078size_t
Greg Clayton462d4142010-09-29 01:12:09 +00004079SymbolFileDWARF::ParseTypes
4080(
4081 const SymbolContext& sc,
4082 DWARFCompileUnit* dwarf_cu,
4083 const DWARFDebugInfoEntry *die,
4084 bool parse_siblings,
4085 bool parse_children
4086)
Chris Lattner24943d22010-06-08 16:52:24 +00004087{
4088 size_t types_added = 0;
4089 while (die != NULL)
4090 {
4091 bool type_is_new = false;
Greg Clayton462d4142010-09-29 01:12:09 +00004092 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner24943d22010-06-08 16:52:24 +00004093 {
4094 if (type_is_new)
4095 ++types_added;
4096 }
4097
4098 if (parse_children && die->HasChildren())
4099 {
4100 if (die->Tag() == DW_TAG_subprogram)
4101 {
4102 SymbolContext child_sc(sc);
4103 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
4104 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
4105 }
4106 else
4107 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
4108 }
4109
4110 if (parse_siblings)
4111 die = die->GetSibling();
4112 else
4113 die = NULL;
4114 }
4115 return types_added;
4116}
4117
4118
4119size_t
4120SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
4121{
4122 assert(sc.comp_unit && sc.function);
4123 size_t functions_added = 0;
4124 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4125 if (dwarf_cu)
4126 {
4127 dw_offset_t function_die_offset = sc.function->GetID();
4128 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
4129 if (function_die)
4130 {
Greg Clayton2e45b0c2011-08-12 17:54:33 +00004131 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner24943d22010-06-08 16:52:24 +00004132 }
4133 }
4134
4135 return functions_added;
4136}
4137
4138
4139size_t
4140SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
4141{
4142 // At least a compile unit must be valid
4143 assert(sc.comp_unit);
4144 size_t types_added = 0;
4145 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4146 if (dwarf_cu)
4147 {
4148 if (sc.function)
4149 {
4150 dw_offset_t function_die_offset = sc.function->GetID();
4151 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
4152 if (func_die && func_die->HasChildren())
4153 {
4154 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
4155 }
4156 }
4157 else
4158 {
4159 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
4160 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
4161 {
4162 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
4163 }
4164 }
4165 }
4166
4167 return types_added;
4168}
4169
4170size_t
4171SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4172{
4173 if (sc.comp_unit != NULL)
4174 {
Greg Clayton9bcf31e2010-11-01 20:32:12 +00004175 DWARFDebugInfo* info = DebugInfo();
4176 if (info == NULL)
4177 return 0;
4178
4179 uint32_t cu_idx = UINT32_MAX;
4180 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner24943d22010-06-08 16:52:24 +00004181
4182 if (dwarf_cu == NULL)
4183 return 0;
4184
4185 if (sc.function)
4186 {
4187 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton178710c2010-09-14 02:20:48 +00004188
4189 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4190 assert (func_lo_pc != DW_INVALID_ADDRESS);
4191
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004192 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4193
4194 // Let all blocks know they have parse all their variables
4195 sc.function->GetBlock (false).SetDidParseVariables (true, true);
4196
4197 return num_variables;
Chris Lattner24943d22010-06-08 16:52:24 +00004198 }
4199 else if (sc.comp_unit)
4200 {
4201 uint32_t vars_added = 0;
4202 VariableListSP variables (sc.comp_unit->GetVariableList(false));
4203
4204 if (variables.get() == NULL)
4205 {
4206 variables.reset(new VariableList());
4207 sc.comp_unit->SetVariableList(variables);
4208
4209 // Index if we already haven't to make sure the compile units
4210 // get indexed and make their global DIE index list
4211 if (!m_indexed)
4212 Index ();
4213
Greg Clayton144188b2011-09-12 23:21:58 +00004214 DWARFCompileUnit* match_dwarf_cu = NULL;
4215 const DWARFDebugInfoEntry* die = NULL;
4216 DIEArray die_offsets;
4217 const size_t num_matches = m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
4218 dwarf_cu->GetNextCompileUnitOffset(),
4219 die_offsets);
4220 if (num_matches)
Chris Lattner24943d22010-06-08 16:52:24 +00004221 {
Greg Clayton144188b2011-09-12 23:21:58 +00004222 DWARFDebugInfo* debug_info = DebugInfo();
4223 for (size_t i=0; i<num_matches; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00004224 {
Greg Clayton144188b2011-09-12 23:21:58 +00004225 const dw_offset_t die_offset = die_offsets[i];
4226 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
4227 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
4228 if (var_sp)
4229 {
4230 variables->AddVariableIfUnique (var_sp);
4231 ++vars_added;
4232 }
Chris Lattner24943d22010-06-08 16:52:24 +00004233 }
4234 }
4235 }
4236 return vars_added;
4237 }
4238 }
4239 return 0;
4240}
4241
4242
4243VariableSP
4244SymbolFileDWARF::ParseVariableDIE
4245(
4246 const SymbolContext& sc,
Greg Clayton1d8173f2010-09-24 05:15:53 +00004247 DWARFCompileUnit* dwarf_cu,
Greg Clayton178710c2010-09-14 02:20:48 +00004248 const DWARFDebugInfoEntry *die,
4249 const lldb::addr_t func_low_pc
Chris Lattner24943d22010-06-08 16:52:24 +00004250)
4251{
4252
Greg Clayton3bc52d02010-11-14 22:13:40 +00004253 VariableSP var_sp (m_die_to_variable_sp[die]);
4254 if (var_sp)
4255 return var_sp; // Already been parsed!
Chris Lattner24943d22010-06-08 16:52:24 +00004256
4257 const dw_tag_t tag = die->Tag();
4258 DWARFDebugInfoEntry::Attributes attributes;
Greg Clayton5fcff9a2010-09-15 08:33:30 +00004259 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner24943d22010-06-08 16:52:24 +00004260 if (num_attributes > 0)
4261 {
4262 const char *name = NULL;
Greg Claytonaed58812010-09-13 02:37:44 +00004263 const char *mangled = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00004264 Declaration decl;
4265 uint32_t i;
Chris Lattner24943d22010-06-08 16:52:24 +00004266 Type *var_type = NULL;
4267 DWARFExpression location;
4268 bool is_external = false;
4269 bool is_artificial = false;
Greg Clayton82f07462011-05-30 00:49:24 +00004270 bool location_is_const_value_data = false;
Sean Callanan70a4f922010-08-06 00:32:49 +00004271 AccessType accessibility = eAccessNone;
Chris Lattner24943d22010-06-08 16:52:24 +00004272
4273 for (i=0; i<num_attributes; ++i)
4274 {
4275 dw_attr_t attr = attributes.AttributeAtIndex(i);
4276 DWARFFormValue form_value;
4277 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4278 {
4279 switch (attr)
4280 {
4281 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4282 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4283 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4284 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
Greg Claytonaed58812010-09-13 02:37:44 +00004285 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
Greg Clayton4fb400f2010-09-27 21:07:38 +00004286 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
Chris Lattner24943d22010-06-08 16:52:24 +00004287 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
Greg Clayton82f07462011-05-30 00:49:24 +00004288 case DW_AT_const_value:
4289 location_is_const_value_data = true;
4290 // Fall through...
Chris Lattner24943d22010-06-08 16:52:24 +00004291 case DW_AT_location:
4292 {
4293 if (form_value.BlockData())
4294 {
4295 const DataExtractor& debug_info_data = get_debug_info_data();
4296
4297 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4298 uint32_t block_length = form_value.Unsigned();
Greg Clayton178710c2010-09-14 02:20:48 +00004299 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
Chris Lattner24943d22010-06-08 16:52:24 +00004300 }
4301 else
4302 {
4303 const DataExtractor& debug_loc_data = get_debug_loc_data();
4304 const dw_offset_t debug_loc_offset = form_value.Unsigned();
4305
4306 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4307 if (loc_list_length > 0)
4308 {
Greg Clayton178710c2010-09-14 02:20:48 +00004309 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4310 assert (func_low_pc != LLDB_INVALID_ADDRESS);
4311 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
Chris Lattner24943d22010-06-08 16:52:24 +00004312 }
4313 }
4314 }
4315 break;
4316
4317 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Greg Clayton84f80752010-07-22 18:30:50 +00004318 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Chris Lattner24943d22010-06-08 16:52:24 +00004319 case DW_AT_declaration:
4320 case DW_AT_description:
4321 case DW_AT_endianity:
4322 case DW_AT_segment:
4323 case DW_AT_start_scope:
4324 case DW_AT_visibility:
4325 default:
4326 case DW_AT_abstract_origin:
4327 case DW_AT_sibling:
4328 case DW_AT_specification:
4329 break;
4330 }
4331 }
4332 }
4333
4334 if (location.IsValid())
4335 {
4336 assert(var_type != DIE_IS_BEING_PARSED);
4337
Chris Lattner24943d22010-06-08 16:52:24 +00004338 ValueType scope = eValueTypeInvalid;
4339
4340 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4341 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4342
4343 if (tag == DW_TAG_formal_parameter)
4344 scope = eValueTypeVariableArgument;
4345 else if (is_external || parent_tag == DW_TAG_compile_unit)
4346 scope = eValueTypeVariableGlobal;
4347 else
4348 scope = eValueTypeVariableLocal;
4349
4350 SymbolContextScope * symbol_context_scope = NULL;
4351 if (parent_tag == DW_TAG_compile_unit)
4352 {
4353 symbol_context_scope = sc.comp_unit;
4354 }
4355 else if (sc.function != NULL)
4356 {
Greg Clayton75ccf502010-08-21 02:22:51 +00004357 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
Chris Lattner24943d22010-06-08 16:52:24 +00004358 if (symbol_context_scope == NULL)
4359 symbol_context_scope = sc.function;
4360 }
4361
4362 assert(symbol_context_scope != NULL);
4363 var_sp.reset (new Variable(die->GetOffset(),
Greg Clayton3bc52d02010-11-14 22:13:40 +00004364 name,
4365 mangled,
Chris Lattner24943d22010-06-08 16:52:24 +00004366 var_type,
4367 scope,
4368 symbol_context_scope,
4369 &decl,
4370 location,
4371 is_external,
4372 is_artificial));
Greg Clayton4fb400f2010-09-27 21:07:38 +00004373
Greg Clayton82f07462011-05-30 00:49:24 +00004374 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
Chris Lattner24943d22010-06-08 16:52:24 +00004375 }
4376 }
Greg Clayton3bc52d02010-11-14 22:13:40 +00004377 // Cache var_sp even if NULL (the variable was just a specification or
4378 // was missing vital information to be able to be displayed in the debugger
4379 // (missing location due to optimization, etc)) so we don't re-parse
4380 // this DIE over and over later...
4381 m_die_to_variable_sp[die] = var_sp;
Chris Lattner24943d22010-06-08 16:52:24 +00004382 return var_sp;
4383}
4384
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004385
4386const DWARFDebugInfoEntry *
4387SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
4388 dw_offset_t spec_block_die_offset,
4389 DWARFCompileUnit **result_die_cu_handle)
4390{
4391 // Give the concrete function die specified by "func_die_offset", find the
4392 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4393 // to "spec_block_die_offset"
4394 DWARFDebugInfo* info = DebugInfo();
4395
4396 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
4397 if (die)
4398 {
4399 assert (*result_die_cu_handle);
4400 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
4401 }
4402 return NULL;
4403}
4404
4405
4406const DWARFDebugInfoEntry *
4407SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
4408 const DWARFDebugInfoEntry *die,
4409 dw_offset_t spec_block_die_offset,
4410 DWARFCompileUnit **result_die_cu_handle)
4411{
4412 if (die)
4413 {
4414 switch (die->Tag())
4415 {
4416 case DW_TAG_subprogram:
4417 case DW_TAG_inlined_subroutine:
4418 case DW_TAG_lexical_block:
4419 {
4420 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4421 {
4422 *result_die_cu_handle = dwarf_cu;
4423 return die;
4424 }
4425
4426 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4427 {
4428 *result_die_cu_handle = dwarf_cu;
4429 return die;
4430 }
4431 }
4432 break;
4433 }
4434
4435 // Give the concrete function die specified by "func_die_offset", find the
4436 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4437 // to "spec_block_die_offset"
4438 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
4439 {
4440 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
4441 child_die,
4442 spec_block_die_offset,
4443 result_die_cu_handle);
4444 if (result_die)
4445 return result_die;
4446 }
4447 }
4448
4449 *result_die_cu_handle = NULL;
4450 return NULL;
4451}
4452
Chris Lattner24943d22010-06-08 16:52:24 +00004453size_t
4454SymbolFileDWARF::ParseVariables
4455(
4456 const SymbolContext& sc,
Greg Clayton1d8173f2010-09-24 05:15:53 +00004457 DWARFCompileUnit* dwarf_cu,
Greg Clayton178710c2010-09-14 02:20:48 +00004458 const lldb::addr_t func_low_pc,
Chris Lattner24943d22010-06-08 16:52:24 +00004459 const DWARFDebugInfoEntry *orig_die,
4460 bool parse_siblings,
4461 bool parse_children,
4462 VariableList* cc_variable_list
4463)
4464{
4465 if (orig_die == NULL)
4466 return 0;
4467
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004468 VariableListSP variable_list_sp;
4469
4470 size_t vars_added = 0;
Chris Lattner24943d22010-06-08 16:52:24 +00004471 const DWARFDebugInfoEntry *die = orig_die;
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004472 while (die != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00004473 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004474 dw_tag_t tag = die->Tag();
4475
4476 // Check to see if we have already parsed this variable or constant?
4477 if (m_die_to_variable_sp[die])
Chris Lattner24943d22010-06-08 16:52:24 +00004478 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004479 if (cc_variable_list)
4480 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner24943d22010-06-08 16:52:24 +00004481 }
4482 else
4483 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004484 // We haven't already parsed it, lets do that now.
4485 if ((tag == DW_TAG_variable) ||
4486 (tag == DW_TAG_constant) ||
4487 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner24943d22010-06-08 16:52:24 +00004488 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004489 if (variable_list_sp.get() == NULL)
Greg Clayton63afdb02011-06-17 01:22:15 +00004490 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004491 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4492 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4493 switch (parent_tag)
4494 {
4495 case DW_TAG_compile_unit:
4496 if (sc.comp_unit != NULL)
4497 {
4498 variable_list_sp = sc.comp_unit->GetVariableList(false);
4499 if (variable_list_sp.get() == NULL)
4500 {
4501 variable_list_sp.reset(new VariableList());
4502 sc.comp_unit->SetVariableList(variable_list_sp);
4503 }
4504 }
4505 else
4506 {
4507 fprintf (stderr,
4508 "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
4509 sc_parent_die->GetOffset(),
4510 DW_TAG_value_to_name (parent_tag),
4511 orig_die->GetOffset(),
4512 DW_TAG_value_to_name (orig_die->Tag()));
4513 }
4514 break;
4515
4516 case DW_TAG_subprogram:
4517 case DW_TAG_inlined_subroutine:
4518 case DW_TAG_lexical_block:
4519 if (sc.function != NULL)
4520 {
4521 // Check to see if we already have parsed the variables for the given scope
4522
4523 Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4524 if (block == NULL)
4525 {
4526 // This must be a specification or abstract origin with
4527 // a concrete block couterpart in the current function. We need
4528 // to find the concrete block so we can correctly add the
4529 // variable to it
4530 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
4531 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
4532 sc_parent_die->GetOffset(),
4533 &concrete_block_die_cu);
4534 if (concrete_block_die)
4535 block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset());
4536 }
4537
4538 if (block != NULL)
4539 {
4540 const bool can_create = false;
4541 variable_list_sp = block->GetBlockVariableList (can_create);
4542 if (variable_list_sp.get() == NULL)
4543 {
4544 variable_list_sp.reset(new VariableList());
4545 block->SetVariableList(variable_list_sp);
4546 }
4547 }
4548 }
4549 break;
4550
4551 default:
4552 fprintf (stderr,
4553 "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
4554 orig_die->GetOffset(),
4555 DW_TAG_value_to_name (orig_die->Tag()));
4556 break;
4557 }
Greg Clayton63afdb02011-06-17 01:22:15 +00004558 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004559
4560 if (variable_list_sp)
Chris Lattner24943d22010-06-08 16:52:24 +00004561 {
Greg Clayton63afdb02011-06-17 01:22:15 +00004562 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
4563 if (var_sp)
4564 {
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004565 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton63afdb02011-06-17 01:22:15 +00004566 if (cc_variable_list)
4567 cc_variable_list->AddVariableIfUnique (var_sp);
4568 ++vars_added;
4569 }
Chris Lattner24943d22010-06-08 16:52:24 +00004570 }
4571 }
4572 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004573
4574 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4575
4576 if (!skip_children && parse_children && die->HasChildren())
4577 {
4578 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
4579 }
4580
4581 if (parse_siblings)
4582 die = die->GetSibling();
4583 else
4584 die = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00004585 }
Greg Clayton1bd2b2f2011-06-17 22:10:16 +00004586 return vars_added;
Chris Lattner24943d22010-06-08 16:52:24 +00004587}
4588
4589//------------------------------------------------------------------
4590// PluginInterface protocol
4591//------------------------------------------------------------------
4592const char *
4593SymbolFileDWARF::GetPluginName()
4594{
4595 return "SymbolFileDWARF";
4596}
4597
4598const char *
4599SymbolFileDWARF::GetShortPluginName()
4600{
4601 return GetPluginNameStatic();
4602}
4603
4604uint32_t
4605SymbolFileDWARF::GetPluginVersion()
4606{
4607 return 1;
4608}
4609
4610void
Greg Claytonb01000f2011-01-17 03:46:26 +00004611SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4612{
4613 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4614 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4615 if (clang_type)
4616 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4617}
4618
4619void
4620SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4621{
4622 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4623 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4624 if (clang_type)
4625 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4626}
4627
Greg Claytone6d72ca2011-06-25 00:44:06 +00004628void
Sean Callanan9b6898f2011-07-30 02:42:06 +00004629SymbolFileDWARF::DumpIndexes ()
4630{
4631 StreamFile s(stdout, false);
4632
4633 s.Printf ("DWARF index for (%s) '%s/%s':",
4634 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4635 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
4636 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
4637 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
4638 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
4639 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
4640 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
4641 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
4642 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
4643 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
4644 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
4645}
4646
4647void
4648SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
4649 const char *name,
4650 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytone6d72ca2011-06-25 00:44:06 +00004651{
Sean Callanan9b6898f2011-07-30 02:42:06 +00004652 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytone6d72ca2011-06-25 00:44:06 +00004653
4654 if (iter == m_decl_ctx_to_die.end())
4655 return;
4656
Sean Callanan9b6898f2011-07-30 02:42:06 +00004657 const DWARFDebugInfoEntry *context_die = iter->second;
Greg Claytone6d72ca2011-06-25 00:44:06 +00004658
4659 if (!results)
4660 return;
4661
4662 DWARFDebugInfo* info = DebugInfo();
4663
Greg Clayton144188b2011-09-12 23:21:58 +00004664 DIEArray die_offsets;
Greg Claytone6d72ca2011-06-25 00:44:06 +00004665
Greg Clayton144188b2011-09-12 23:21:58 +00004666 DWARFCompileUnit* dwarf_cu = NULL;
4667 const DWARFDebugInfoEntry* die = NULL;
4668 size_t num_matches = m_type_index.Find (ConstString(name), die_offsets);
Greg Claytone6d72ca2011-06-25 00:44:06 +00004669
4670 if (num_matches)
4671 {
Greg Clayton144188b2011-09-12 23:21:58 +00004672 for (size_t i = 0; i < num_matches; ++i)
Greg Claytone6d72ca2011-06-25 00:44:06 +00004673 {
Greg Clayton144188b2011-09-12 23:21:58 +00004674 const dw_offset_t die_offset = die_offsets[i];
4675 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
4676
Sean Callanan9b6898f2011-07-30 02:42:06 +00004677 if (die->GetParent() != context_die)
Greg Claytone6d72ca2011-06-25 00:44:06 +00004678 continue;
4679
Greg Clayton144188b2011-09-12 23:21:58 +00004680 Type *matching_type = ResolveType (dwarf_cu, die);
Greg Claytone6d72ca2011-06-25 00:44:06 +00004681
4682 lldb::clang_type_t type = matching_type->GetClangFullType();
4683 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
4684
Sean Callanan9b6898f2011-07-30 02:42:06 +00004685 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
Greg Claytone6d72ca2011-06-25 00:44:06 +00004686 {
4687 clang::TagDecl *tag_decl = tag_type->getDecl();
4688 results->push_back(tag_decl);
4689 }
Sean Callanan9b6898f2011-07-30 02:42:06 +00004690 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
Greg Claytone6d72ca2011-06-25 00:44:06 +00004691 {
4692 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
4693 results->push_back(typedef_decl);
4694 }
4695 }
4696 }
4697}
4698
4699void
4700SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
4701 const clang::DeclContext *DC,
4702 clang::DeclarationName Name,
4703 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
4704{
4705 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4706
Sean Callanan9b6898f2011-07-30 02:42:06 +00004707 symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results);
Greg Claytone6d72ca2011-06-25 00:44:06 +00004708}