blob: 52eb0913cb4f6679bf2c174cc746b553d37e70d3 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolFileDWARF.h"
11
12// Other libraries and framework includes
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclGroup.h"
17#include "clang/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
Greg Clayton7fedea22010-11-16 02:10:54 +000023#include "clang/Sema/DeclSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024
Sean Callanancc427fa2011-07-30 02:42:06 +000025#include "llvm/Support/Casting.h"
26
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/Module.h"
28#include "lldb/Core/PluginManager.h"
29#include "lldb/Core/RegularExpression.h"
30#include "lldb/Core/Scalar.h"
31#include "lldb/Core/Section.h"
Greg Claytonc685f8e2010-09-15 04:15:46 +000032#include "lldb/Core/StreamFile.h"
Jim Ingham318c9f22011-08-26 19:44:13 +000033#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Core/Timer.h"
35#include "lldb/Core/Value.h"
36
Greg Clayton20568dd2011-10-13 23:13:20 +000037#include "lldb/Host/Host.h"
38
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Symbol/Block.h"
Greg Clayton6beaaa62011-01-17 03:46:26 +000040#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041#include "lldb/Symbol/CompileUnit.h"
42#include "lldb/Symbol/LineTable.h"
43#include "lldb/Symbol/ObjectFile.h"
44#include "lldb/Symbol/SymbolVendor.h"
45#include "lldb/Symbol/VariableList.h"
46
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000047#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham4cda6e02011-10-07 22:23:45 +000048#include "lldb/Target/CPPLanguageRuntime.h"
Jim Inghamb7f6b2f2011-09-08 22:13:49 +000049
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050#include "DWARFCompileUnit.h"
51#include "DWARFDebugAbbrev.h"
52#include "DWARFDebugAranges.h"
53#include "DWARFDebugInfo.h"
54#include "DWARFDebugInfoEntry.h"
55#include "DWARFDebugLine.h"
56#include "DWARFDebugPubnames.h"
57#include "DWARFDebugRanges.h"
58#include "DWARFDIECollection.h"
59#include "DWARFFormValue.h"
60#include "DWARFLocationList.h"
61#include "LogChannelDWARF.h"
Greg Clayton450e3f32010-10-12 02:24:53 +000062#include "SymbolFileDWARFDebugMap.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063
64#include <map>
65
Greg Clayton62742b12010-11-11 01:09:45 +000066//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
Greg Claytonc93237c2010-10-01 20:48:32 +000067
68#ifdef ENABLE_DEBUG_PRINTF
69#include <stdio.h>
70#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
71#else
72#define DEBUG_PRINTF(fmt, ...)
73#endif
74
Greg Clayton594e5ed2010-09-27 21:07:38 +000075#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076
77using namespace lldb;
78using namespace lldb_private;
79
80
Sean Callananc7fbf732010-08-06 00:32:49 +000081static AccessType
Greg Clayton8cf05932010-07-22 18:30:50 +000082DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083{
84 switch (dwarf_accessibility)
85 {
Sean Callananc7fbf732010-08-06 00:32:49 +000086 case DW_ACCESS_public: return eAccessPublic;
87 case DW_ACCESS_private: return eAccessPrivate;
88 case DW_ACCESS_protected: return eAccessProtected;
Greg Clayton8cf05932010-07-22 18:30:50 +000089 default: break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090 }
Sean Callananc7fbf732010-08-06 00:32:49 +000091 return eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092}
93
94void
95SymbolFileDWARF::Initialize()
96{
97 LogChannelDWARF::Initialize();
98 PluginManager::RegisterPlugin (GetPluginNameStatic(),
99 GetPluginDescriptionStatic(),
100 CreateInstance);
101}
102
103void
104SymbolFileDWARF::Terminate()
105{
106 PluginManager::UnregisterPlugin (CreateInstance);
107 LogChannelDWARF::Initialize();
108}
109
110
111const char *
112SymbolFileDWARF::GetPluginNameStatic()
113{
Greg Claytond4a2b372011-09-12 23:21:58 +0000114 return "dwarf";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115}
116
117const char *
118SymbolFileDWARF::GetPluginDescriptionStatic()
119{
120 return "DWARF and DWARF3 debug symbol file reader.";
121}
122
123
124SymbolFile*
125SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
126{
127 return new SymbolFileDWARF(obj_file);
128}
129
Greg Clayton2d95dc9b2010-11-10 04:57:04 +0000130TypeList *
131SymbolFileDWARF::GetTypeList ()
132{
133 if (m_debug_map_symfile)
134 return m_debug_map_symfile->GetTypeList();
135 return m_obj_file->GetModule()->GetTypeList();
136
137}
138
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139//----------------------------------------------------------------------
140// Gets the first parent that is a lexical block, function or inlined
141// subroutine, or compile unit.
142//----------------------------------------------------------------------
143static const DWARFDebugInfoEntry *
144GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
145{
146 const DWARFDebugInfoEntry *die;
147 for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
148 {
149 dw_tag_t tag = die->Tag();
150
151 switch (tag)
152 {
153 case DW_TAG_compile_unit:
154 case DW_TAG_subprogram:
155 case DW_TAG_inlined_subroutine:
156 case DW_TAG_lexical_block:
157 return die;
158 }
159 }
160 return NULL;
161}
162
163
Greg Clayton450e3f32010-10-12 02:24:53 +0000164SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
165 SymbolFile (objfile),
Greg Clayton81c22f62011-10-19 18:09:39 +0000166 UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
Greg Clayton450e3f32010-10-12 02:24:53 +0000167 m_debug_map_symfile (NULL),
Greg Clayton7a345282010-11-09 23:46:37 +0000168 m_clang_tu_decl (NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169 m_flags(),
Greg Claytond4a2b372011-09-12 23:21:58 +0000170 m_data_debug_abbrev (),
171 m_data_debug_aranges (),
172 m_data_debug_frame (),
173 m_data_debug_info (),
174 m_data_debug_line (),
175 m_data_debug_loc (),
176 m_data_debug_ranges (),
177 m_data_debug_str (),
Greg Clayton17674402011-09-28 17:06:40 +0000178 m_data_apple_names (),
179 m_data_apple_types (),
Greg Clayton7f995132011-10-04 22:41:51 +0000180 m_data_apple_namespaces (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 m_abbr(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182 m_info(),
183 m_line(),
Greg Clayton7f995132011-10-04 22:41:51 +0000184 m_apple_names_ap (),
185 m_apple_types_ap (),
186 m_apple_namespaces_ap (),
Greg Clayton5009f9d2011-10-27 17:55:14 +0000187 m_apple_objc_ap (),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000188 m_function_basename_index(),
189 m_function_fullname_index(),
190 m_function_method_index(),
191 m_function_selector_index(),
Greg Clayton450e3f32010-10-12 02:24:53 +0000192 m_objc_class_selectors_index(),
Greg Claytonc685f8e2010-09-15 04:15:46 +0000193 m_global_index(),
Greg Clayton69b04882010-10-15 02:03:22 +0000194 m_type_index(),
195 m_namespace_index(),
Greg Clayton6beaaa62011-01-17 03:46:26 +0000196 m_indexed (false),
197 m_is_external_ast_source (false),
Greg Clayton97fbc342011-10-20 22:30:33 +0000198 m_using_apple_tables (false),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +0000199 m_ranges(),
200 m_unique_ast_type_map ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201{
202}
203
204SymbolFileDWARF::~SymbolFileDWARF()
205{
Greg Clayton6beaaa62011-01-17 03:46:26 +0000206 if (m_is_external_ast_source)
207 m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
208}
209
210static const ConstString &
211GetDWARFMachOSegmentName ()
212{
213 static ConstString g_dwarf_section_name ("__DWARF");
214 return g_dwarf_section_name;
215}
216
Greg Claytone576ab22011-02-15 00:19:15 +0000217UniqueDWARFASTTypeMap &
218SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
219{
220 if (m_debug_map_symfile)
221 return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
222 return m_unique_ast_type_map;
223}
224
Greg Clayton6beaaa62011-01-17 03:46:26 +0000225ClangASTContext &
226SymbolFileDWARF::GetClangASTContext ()
227{
228 if (m_debug_map_symfile)
229 return m_debug_map_symfile->GetClangASTContext ();
230
231 ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
232 if (!m_is_external_ast_source)
233 {
234 m_is_external_ast_source = true;
235 llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
236 new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
237 SymbolFileDWARF::CompleteObjCInterfaceDecl,
Greg Claytona2721472011-06-25 00:44:06 +0000238 SymbolFileDWARF::FindExternalVisibleDeclsByName,
Greg Clayton6beaaa62011-01-17 03:46:26 +0000239 this));
240
241 ast.SetExternalSource (ast_source_ap);
242 }
243 return ast;
244}
245
246void
247SymbolFileDWARF::InitializeObject()
248{
249 // Install our external AST source callbacks so we can complete Clang types.
250 Module *module = m_obj_file->GetModule();
251 if (module)
252 {
253 const SectionList *section_list = m_obj_file->GetSectionList();
254
255 const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
256
257 // Memory map the DWARF mach-o segment so we have everything mmap'ed
258 // to keep our heap memory usage down.
259 if (section)
260 section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
261 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000262 get_apple_names_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000263 if (m_data_apple_names.GetByteSize() > 0)
264 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000265 m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
266 if (m_apple_names_ap->IsValid())
267 m_using_apple_tables = true;
268 else
Greg Clayton7f995132011-10-04 22:41:51 +0000269 m_apple_names_ap.reset();
270 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000271 get_apple_types_data();
Greg Clayton7f995132011-10-04 22:41:51 +0000272 if (m_data_apple_types.GetByteSize() > 0)
273 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000274 m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
275 if (m_apple_types_ap->IsValid())
276 m_using_apple_tables = true;
277 else
Greg Clayton7f995132011-10-04 22:41:51 +0000278 m_apple_types_ap.reset();
279 }
280
281 get_apple_namespaces_data();
282 if (m_data_apple_namespaces.GetByteSize() > 0)
283 {
Greg Clayton97fbc342011-10-20 22:30:33 +0000284 m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
285 if (m_apple_namespaces_ap->IsValid())
286 m_using_apple_tables = true;
287 else
Greg Clayton7f995132011-10-04 22:41:51 +0000288 m_apple_namespaces_ap.reset();
289 }
Greg Clayton4d01ace2011-09-29 16:58:15 +0000290
Greg Clayton5009f9d2011-10-27 17:55:14 +0000291 get_apple_objc_data();
292 if (m_data_apple_objc.GetByteSize() > 0)
293 {
294 m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
295 if (m_apple_objc_ap->IsValid())
296 m_using_apple_tables = true;
297 else
298 m_apple_objc_ap.reset();
299 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300}
301
302bool
303SymbolFileDWARF::SupportedVersion(uint16_t version)
304{
305 return version == 2 || version == 3;
306}
307
308uint32_t
309SymbolFileDWARF::GetAbilities ()
310{
311 uint32_t abilities = 0;
312 if (m_obj_file != NULL)
313 {
314 const Section* section = NULL;
315 const SectionList *section_list = m_obj_file->GetSectionList();
316 if (section_list == NULL)
317 return 0;
318
319 uint64_t debug_abbrev_file_size = 0;
320 uint64_t debug_aranges_file_size = 0;
321 uint64_t debug_frame_file_size = 0;
322 uint64_t debug_info_file_size = 0;
323 uint64_t debug_line_file_size = 0;
324 uint64_t debug_loc_file_size = 0;
325 uint64_t debug_macinfo_file_size = 0;
326 uint64_t debug_pubnames_file_size = 0;
327 uint64_t debug_pubtypes_file_size = 0;
328 uint64_t debug_ranges_file_size = 0;
329 uint64_t debug_str_file_size = 0;
330
Greg Clayton6beaaa62011-01-17 03:46:26 +0000331 section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332
333 if (section)
Greg Clayton4ceb9982010-07-21 22:54:26 +0000334 section_list = &section->GetChildren ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335
Greg Clayton4ceb9982010-07-21 22:54:26 +0000336 section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 if (section != NULL)
338 {
339 debug_info_file_size = section->GetByteSize();
340
Greg Clayton4ceb9982010-07-21 22:54:26 +0000341 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 if (section)
343 debug_abbrev_file_size = section->GetByteSize();
344 else
345 m_flags.Set (flagsGotDebugAbbrevData);
346
Greg Clayton4ceb9982010-07-21 22:54:26 +0000347 section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348 if (section)
349 debug_aranges_file_size = section->GetByteSize();
350 else
351 m_flags.Set (flagsGotDebugArangesData);
352
Greg Clayton4ceb9982010-07-21 22:54:26 +0000353 section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000354 if (section)
355 debug_frame_file_size = section->GetByteSize();
356 else
357 m_flags.Set (flagsGotDebugFrameData);
358
Greg Clayton4ceb9982010-07-21 22:54:26 +0000359 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360 if (section)
361 debug_line_file_size = section->GetByteSize();
362 else
363 m_flags.Set (flagsGotDebugLineData);
364
Greg Clayton4ceb9982010-07-21 22:54:26 +0000365 section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 if (section)
367 debug_loc_file_size = section->GetByteSize();
368 else
369 m_flags.Set (flagsGotDebugLocData);
370
Greg Clayton4ceb9982010-07-21 22:54:26 +0000371 section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372 if (section)
373 debug_macinfo_file_size = section->GetByteSize();
374 else
375 m_flags.Set (flagsGotDebugMacInfoData);
376
Greg Clayton4ceb9982010-07-21 22:54:26 +0000377 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378 if (section)
379 debug_pubnames_file_size = section->GetByteSize();
380 else
381 m_flags.Set (flagsGotDebugPubNamesData);
382
Greg Clayton4ceb9982010-07-21 22:54:26 +0000383 section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 if (section)
385 debug_pubtypes_file_size = section->GetByteSize();
386 else
387 m_flags.Set (flagsGotDebugPubTypesData);
388
Greg Clayton4ceb9982010-07-21 22:54:26 +0000389 section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 if (section)
391 debug_ranges_file_size = section->GetByteSize();
392 else
393 m_flags.Set (flagsGotDebugRangesData);
394
Greg Clayton4ceb9982010-07-21 22:54:26 +0000395 section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396 if (section)
397 debug_str_file_size = section->GetByteSize();
398 else
399 m_flags.Set (flagsGotDebugStrData);
400 }
401
402 if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
403 abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
404
405 if (debug_line_file_size > 0)
406 abilities |= LineTables;
407
408 if (debug_aranges_file_size > 0)
409 abilities |= AddressAcceleratorTable;
410
411 if (debug_pubnames_file_size > 0)
412 abilities |= FunctionAcceleratorTable;
413
414 if (debug_pubtypes_file_size > 0)
415 abilities |= TypeAcceleratorTable;
416
417 if (debug_macinfo_file_size > 0)
418 abilities |= MacroInformation;
419
420 if (debug_frame_file_size > 0)
421 abilities |= CallFrameInformation;
422 }
423 return abilities;
424}
425
426const DataExtractor&
Greg Clayton4ceb9982010-07-21 22:54:26 +0000427SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000428{
429 if (m_flags.IsClear (got_flag))
430 {
431 m_flags.Set (got_flag);
432 const SectionList *section_list = m_obj_file->GetSectionList();
433 if (section_list)
434 {
Greg Clayton4ceb9982010-07-21 22:54:26 +0000435 Section *section = section_list->FindSectionByType(sect_type, true).get();
436 if (section)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437 {
438 // See if we memory mapped the DWARF segment?
439 if (m_dwarf_data.GetByteSize())
440 {
441 data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
442 }
443 else
444 {
445 if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
446 data.Clear();
447 }
448 }
449 }
450 }
451 return data;
452}
453
454const DataExtractor&
455SymbolFileDWARF::get_debug_abbrev_data()
456{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000457 return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458}
459
460const DataExtractor&
Greg Claytond4a2b372011-09-12 23:21:58 +0000461SymbolFileDWARF::get_debug_aranges_data()
462{
463 return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
464}
465
466const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467SymbolFileDWARF::get_debug_frame_data()
468{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000469 return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000470}
471
472const DataExtractor&
473SymbolFileDWARF::get_debug_info_data()
474{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000475 return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476}
477
478const DataExtractor&
479SymbolFileDWARF::get_debug_line_data()
480{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000481 return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482}
483
484const DataExtractor&
485SymbolFileDWARF::get_debug_loc_data()
486{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000487 return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488}
489
490const DataExtractor&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491SymbolFileDWARF::get_debug_ranges_data()
492{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000493 return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494}
495
496const DataExtractor&
497SymbolFileDWARF::get_debug_str_data()
498{
Greg Clayton4ceb9982010-07-21 22:54:26 +0000499 return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000500}
501
Greg Claytonf9eec202011-09-01 23:16:13 +0000502const DataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000503SymbolFileDWARF::get_apple_names_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000504{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000505 return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
Greg Claytonf9eec202011-09-01 23:16:13 +0000506}
507
508const DataExtractor&
Greg Clayton17674402011-09-28 17:06:40 +0000509SymbolFileDWARF::get_apple_types_data()
Greg Claytonf9eec202011-09-01 23:16:13 +0000510{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000511 return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
Greg Claytonf9eec202011-09-01 23:16:13 +0000512}
513
Greg Clayton7f995132011-10-04 22:41:51 +0000514const DataExtractor&
515SymbolFileDWARF::get_apple_namespaces_data()
516{
Greg Clayton5009f9d2011-10-27 17:55:14 +0000517 return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
518}
519
520const DataExtractor&
521SymbolFileDWARF::get_apple_objc_data()
522{
523 return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
Greg Clayton7f995132011-10-04 22:41:51 +0000524}
525
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526
527DWARFDebugAbbrev*
528SymbolFileDWARF::DebugAbbrev()
529{
530 if (m_abbr.get() == NULL)
531 {
532 const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
533 if (debug_abbrev_data.GetByteSize() > 0)
534 {
535 m_abbr.reset(new DWARFDebugAbbrev());
536 if (m_abbr.get())
537 m_abbr->Parse(debug_abbrev_data);
538 }
539 }
540 return m_abbr.get();
541}
542
543const DWARFDebugAbbrev*
544SymbolFileDWARF::DebugAbbrev() const
545{
546 return m_abbr.get();
547}
548
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000549
550DWARFDebugInfo*
551SymbolFileDWARF::DebugInfo()
552{
553 if (m_info.get() == NULL)
554 {
555 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
556 if (get_debug_info_data().GetByteSize() > 0)
557 {
558 m_info.reset(new DWARFDebugInfo());
559 if (m_info.get())
560 {
561 m_info->SetDwarfData(this);
562 }
563 }
564 }
565 return m_info.get();
566}
567
568const DWARFDebugInfo*
569SymbolFileDWARF::DebugInfo() const
570{
571 return m_info.get();
572}
573
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574DWARFCompileUnit*
575SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
576{
577 DWARFDebugInfo* info = DebugInfo();
Greg Clayton81c22f62011-10-19 18:09:39 +0000578 if (info && UserIDMatches(cu_uid))
579 return info->GetCompileUnit((dw_offset_t)cu_uid).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580 return NULL;
581}
582
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000583
584DWARFDebugRanges*
585SymbolFileDWARF::DebugRanges()
586{
587 if (m_ranges.get() == NULL)
588 {
589 Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
590 if (get_debug_ranges_data().GetByteSize() > 0)
591 {
592 m_ranges.reset(new DWARFDebugRanges());
593 if (m_ranges.get())
594 m_ranges->Extract(this);
595 }
596 }
597 return m_ranges.get();
598}
599
600const DWARFDebugRanges*
601SymbolFileDWARF::DebugRanges() const
602{
603 return m_ranges.get();
604}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605
606bool
Greg Clayton96d7d742010-11-10 23:42:09 +0000607SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000608{
Greg Clayton96d7d742010-11-10 23:42:09 +0000609 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000611 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612 if (cu_die)
613 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000614 const char * cu_die_name = cu_die->GetName(this, curr_cu);
615 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
Jim Ingham0f35ac22011-08-24 23:34:20 +0000616 LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000617 if (cu_die_name)
618 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000619 FileSpec cu_file_spec;
620
Greg Clayton7bd65b92011-02-09 23:39:34 +0000621 if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000622 {
Jim Ingham0909e5f2010-09-16 00:57:33 +0000623 // If we have a full path to the compile unit, we don't need to resolve
624 // the file. This can be expensive e.g. when the source files are NFS mounted.
625 cu_file_spec.SetFile (cu_die_name, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000626 }
627 else
628 {
629 std::string fullpath(cu_comp_dir);
630 if (*fullpath.rbegin() != '/')
631 fullpath += '/';
632 fullpath += cu_die_name;
Jim Ingham0909e5f2010-09-16 00:57:33 +0000633 cu_file_spec.SetFile (fullpath.c_str(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634 }
635
Greg Clayton81c22f62011-10-19 18:09:39 +0000636 compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
637 curr_cu,
638 cu_file_spec,
639 MakeUserID(curr_cu->GetOffset()),
640 cu_language));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 if (compile_unit_sp.get())
642 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000643 curr_cu->SetUserData(compile_unit_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644 return true;
645 }
646 }
647 }
648 }
649 return false;
650}
651
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652uint32_t
653SymbolFileDWARF::GetNumCompileUnits()
654{
655 DWARFDebugInfo* info = DebugInfo();
656 if (info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657 return info->GetNumCompileUnits();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000658 return 0;
659}
660
661CompUnitSP
662SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
663{
664 CompUnitSP comp_unit;
665 DWARFDebugInfo* info = DebugInfo();
666 if (info)
667 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000668 DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
669 if (curr_cu != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000670 {
671 // Our symbol vendor shouldn't be asking us to add a compile unit that
672 // has already been added to it, which this DWARF plug-in knows as it
673 // stores the lldb compile unit (CompileUnit) pointer in each
674 // DWARFCompileUnit object when it gets added.
Greg Clayton96d7d742010-11-10 23:42:09 +0000675 assert(curr_cu->GetUserData() == NULL);
676 ParseCompileUnit(curr_cu, comp_unit);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000677 }
678 }
679 return comp_unit;
680}
681
682static void
Greg Claytonea3e7d52011-10-08 00:49:15 +0000683AddRangesToBlock (Block& block,
684 DWARFDebugRanges::RangeList& ranges,
685 addr_t block_base_addr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000686{
Greg Claytonea3e7d52011-10-08 00:49:15 +0000687 const size_t num_ranges = ranges.GetSize();
688 for (size_t i = 0; i<num_ranges; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000689 {
Greg Claytonea3e7d52011-10-08 00:49:15 +0000690 const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
691 const addr_t range_base = range.GetRangeBase();
692 assert (range_base >= block_base_addr);
693 block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 }
Greg Claytonea3e7d52011-10-08 00:49:15 +0000695 block.FinalizeRanges ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696}
697
698
699Function *
Greg Clayton0fffff52010-09-24 05:15:53 +0000700SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701{
702 DWARFDebugRanges::RangeList func_ranges;
703 const char *name = NULL;
704 const char *mangled = NULL;
705 int decl_file = 0;
706 int decl_line = 0;
707 int decl_column = 0;
708 int call_file = 0;
709 int call_line = 0;
710 int call_column = 0;
711 DWARFExpression frame_base;
712
Greg Claytonc93237c2010-10-01 20:48:32 +0000713 assert (die->Tag() == DW_TAG_subprogram);
714
715 if (die->Tag() != DW_TAG_subprogram)
716 return NULL;
717
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
719 {
720 // Union of all ranges in the function DIE (if the function is discontiguous)
721 AddressRange func_range;
Greg Claytonea3e7d52011-10-08 00:49:15 +0000722 lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
723 lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724 if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
725 {
726 func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
727 if (func_range.GetBaseAddress().IsValid())
728 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
729 }
730
731 if (func_range.GetBaseAddress().IsValid())
732 {
733 Mangled func_name;
734 if (mangled)
735 func_name.SetValue(mangled, true);
736 else if (name)
737 func_name.SetValue(name, false);
738
739 FunctionSP func_sp;
740 std::auto_ptr<Declaration> decl_ap;
741 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Greg Claytond7e05462010-11-14 00:22:48 +0000742 decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
743 decl_line,
744 decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000745
Greg Clayton0bd4e1b2011-09-30 20:52:25 +0000746 // Supply the type _only_ if it has already been parsed
Greg Clayton594e5ed2010-09-27 21:07:38 +0000747 Type *func_type = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000748
749 assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
750
751 func_range.GetBaseAddress().ResolveLinkedAddress();
752
Greg Clayton81c22f62011-10-19 18:09:39 +0000753 const user_id_t func_user_id = MakeUserID(die->GetOffset());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000754 func_sp.reset(new Function (sc.comp_unit,
Greg Clayton81c22f62011-10-19 18:09:39 +0000755 func_user_id, // UserID is the DIE offset
756 func_user_id,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000757 func_name,
758 func_type,
759 func_range)); // first address range
760
761 if (func_sp.get() != NULL)
762 {
Greg Clayton0bd4e1b2011-09-30 20:52:25 +0000763 if (frame_base.IsValid())
764 func_sp->GetFrameBaseExpression() = frame_base;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000765 sc.comp_unit->AddFunction(func_sp);
766 return func_sp.get();
767 }
768 }
769 }
770 return NULL;
771}
772
773size_t
774SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
775{
776 assert (sc.comp_unit);
777 size_t functions_added = 0;
Greg Clayton0fffff52010-09-24 05:15:53 +0000778 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779 if (dwarf_cu)
780 {
781 DWARFDIECollection function_dies;
782 const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
783 size_t func_idx;
784 for (func_idx = 0; func_idx < num_funtions; ++func_idx)
785 {
786 const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
Greg Clayton81c22f62011-10-19 18:09:39 +0000787 if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000788 {
789 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
790 ++functions_added;
791 }
792 }
793 //FixupTypes();
794 }
795 return functions_added;
796}
797
798bool
799SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
800{
801 assert (sc.comp_unit);
Greg Clayton96d7d742010-11-10 23:42:09 +0000802 DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
803 assert (curr_cu);
804 const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000805
806 if (cu_die)
807 {
Greg Clayton96d7d742010-11-10 23:42:09 +0000808 const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
809 dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000810
811 // All file indexes in DWARF are one based and a file of index zero is
812 // supposed to be the compile unit itself.
813 support_files.Append (*sc.comp_unit);
814
815 return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
816 }
817 return false;
818}
819
820struct ParseDWARFLineTableCallbackInfo
821{
822 LineTable* line_table;
823 const SectionList *section_list;
824 lldb::addr_t prev_sect_file_base_addr;
825 lldb::addr_t curr_sect_file_base_addr;
826 bool is_oso_for_debug_map;
827 bool prev_in_final_executable;
828 DWARFDebugLine::Row prev_row;
829 SectionSP prev_section_sp;
830 SectionSP curr_section_sp;
831};
832
833//----------------------------------------------------------------------
834// ParseStatementTableCallback
835//----------------------------------------------------------------------
836static void
837ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
838{
839 LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
840 if (state.row == DWARFDebugLine::State::StartParsingLineTable)
841 {
842 // Just started parsing the line table
843 }
844 else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
845 {
846 // Done parsing line table, nothing to do for the cleanup
847 }
848 else
849 {
850 ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
851 // We have a new row, lets append it
852
853 if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
854 {
855 info->prev_section_sp = info->curr_section_sp;
856 info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
857 // If this is an end sequence entry, then we subtract one from the
858 // address to make sure we get an address that is not the end of
859 // a section.
860 if (state.end_sequence && state.address != 0)
861 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
862 else
863 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
864
865 if (info->curr_section_sp.get())
866 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
867 else
868 info->curr_sect_file_base_addr = 0;
869 }
870 if (info->curr_section_sp.get())
871 {
872 lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
873 // Check for the fancy section magic to determine if we
874
875 if (info->is_oso_for_debug_map)
876 {
877 // When this is a debug map object file that contains DWARF
878 // (referenced from an N_OSO debug map nlist entry) we will have
879 // a file address in the file range for our section from the
880 // original .o file, and a load address in the executable that
881 // contains the debug map.
882 //
883 // If the sections for the file range and load range are
884 // different, we have a remapped section for the function and
885 // this address is resolved. If they are the same, then the
886 // function for this address didn't make it into the final
887 // executable.
888 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
889
890 // If we are doing DWARF with debug map, then we need to carefully
891 // add each line table entry as there may be gaps as functions
892 // get moved around or removed.
893 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
894 {
895 if (info->prev_in_final_executable)
896 {
897 bool terminate_previous_entry = false;
898 if (!curr_in_final_executable)
899 {
900 // Check for the case where the previous line entry
901 // in a function made it into the final executable,
902 // yet the current line entry falls in a function
903 // that didn't. The line table used to be contiguous
904 // through this address range but now it isn't. We
905 // need to terminate the previous line entry so
906 // that we can reconstruct the line range correctly
907 // for it and to keep the line table correct.
908 terminate_previous_entry = true;
909 }
910 else if (info->curr_section_sp.get() != info->prev_section_sp.get())
911 {
912 // Check for cases where the line entries used to be
913 // contiguous address ranges, but now they aren't.
914 // This can happen when order files specify the
915 // ordering of the functions.
916 lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
917 Section *curr_sect = info->curr_section_sp.get();
918 Section *prev_sect = info->prev_section_sp.get();
919 assert (curr_sect->GetLinkedSection());
920 assert (prev_sect->GetLinkedSection());
921 lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
922 lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
923 lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
924 lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
925 if (object_file_addr_delta != linked_file_addr_delta)
926 terminate_previous_entry = true;
927 }
928
929 if (terminate_previous_entry)
930 {
931 line_table->InsertLineEntry (info->prev_section_sp,
932 state.address - info->prev_sect_file_base_addr,
933 info->prev_row.line,
934 info->prev_row.column,
935 info->prev_row.file,
936 false, // is_stmt
937 false, // basic_block
938 false, // state.prologue_end
939 false, // state.epilogue_begin
940 true); // end_sequence);
941 }
942 }
943 }
944
945 if (curr_in_final_executable)
946 {
947 line_table->InsertLineEntry (info->curr_section_sp,
948 curr_line_section_offset,
949 state.line,
950 state.column,
951 state.file,
952 state.is_stmt,
953 state.basic_block,
954 state.prologue_end,
955 state.epilogue_begin,
956 state.end_sequence);
957 info->prev_section_sp = info->curr_section_sp;
958 }
959 else
960 {
961 // If the current address didn't make it into the final
962 // executable, the current section will be the __text
963 // segment in the .o file, so we need to clear this so
964 // we can catch the next function that did make it into
965 // the final executable.
966 info->prev_section_sp.reset();
967 info->curr_section_sp.reset();
968 }
969
970 info->prev_in_final_executable = curr_in_final_executable;
971 }
972 else
973 {
974 // We are not in an object file that contains DWARF for an
975 // N_OSO, this is just a normal DWARF file. The DWARF spec
976 // guarantees that the addresses will be in increasing order
977 // so, since we store line tables in file address order, we
978 // can always just append the line entry without needing to
979 // search for the correct insertion point (we don't need to
980 // use LineEntry::InsertLineEntry()).
981 line_table->AppendLineEntry (info->curr_section_sp,
982 curr_line_section_offset,
983 state.line,
984 state.column,
985 state.file,
986 state.is_stmt,
987 state.basic_block,
988 state.prologue_end,
989 state.epilogue_begin,
990 state.end_sequence);
991 }
992 }
993
994 info->prev_row = state;
995 }
996}
997
998bool
999SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1000{
1001 assert (sc.comp_unit);
1002 if (sc.comp_unit->GetLineTable() != NULL)
1003 return true;
1004
1005 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
1006 if (dwarf_cu)
1007 {
1008 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1009 const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
1010 if (cu_line_offset != DW_INVALID_OFFSET)
1011 {
1012 std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
1013 if (line_table_ap.get())
1014 {
Greg Clayton450e3f32010-10-12 02:24:53 +00001015 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001016 uint32_t offset = cu_line_offset;
1017 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1018 sc.comp_unit->SetLineTable(line_table_ap.release());
1019 return true;
1020 }
1021 }
1022 }
1023 return false;
1024}
1025
1026size_t
1027SymbolFileDWARF::ParseFunctionBlocks
1028(
1029 const SymbolContext& sc,
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001030 Block *parent_block,
Greg Clayton0fffff52010-09-24 05:15:53 +00001031 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001032 const DWARFDebugInfoEntry *die,
1033 addr_t subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001034 uint32_t depth
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001035)
1036{
1037 size_t blocks_added = 0;
1038 while (die != NULL)
1039 {
1040 dw_tag_t tag = die->Tag();
1041
1042 switch (tag)
1043 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001044 case DW_TAG_inlined_subroutine:
Greg Claytonb4d37332011-08-12 16:22:48 +00001045 case DW_TAG_subprogram:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046 case DW_TAG_lexical_block:
1047 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001048 Block *block = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001049 if (tag == DW_TAG_subprogram)
1050 {
1051 // Skip any DW_TAG_subprogram DIEs that are inside
1052 // of a normal or inlined functions. These will be
1053 // parsed on their own as separate entities.
1054
1055 if (depth > 0)
1056 break;
1057
1058 block = parent_block;
1059 }
1060 else
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001061 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001062 BlockSP block_sp(new Block (MakeUserID(die->GetOffset())));
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001063 parent_block->AddChild(block_sp);
1064 block = block_sp.get();
1065 }
Greg Claytondd7feaf2011-08-12 17:54:33 +00001066 DWARFDebugRanges::RangeList ranges;
1067 const char *name = NULL;
1068 const char *mangled_name = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001069
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001070 int decl_file = 0;
1071 int decl_line = 0;
1072 int decl_column = 0;
1073 int call_file = 0;
1074 int call_line = 0;
1075 int call_column = 0;
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001076 if (die->GetDIENamesAndRanges (this,
1077 dwarf_cu,
1078 name,
1079 mangled_name,
1080 ranges,
1081 decl_file, decl_line, decl_column,
1082 call_file, call_line, call_column))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001083 {
1084 if (tag == DW_TAG_subprogram)
1085 {
1086 assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
Greg Claytonea3e7d52011-10-08 00:49:15 +00001087 subprogram_low_pc = ranges.GetMinRangeBase(0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001088 }
Jim Inghamb0be4422010-08-12 01:20:14 +00001089 else if (tag == DW_TAG_inlined_subroutine)
1090 {
1091 // We get called here for inlined subroutines in two ways.
1092 // The first time is when we are making the Function object
1093 // for this inlined concrete instance. Since we're creating a top level block at
1094 // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to
1095 // adjust the containing address.
1096 // The second time is when we are parsing the blocks inside the function that contains
1097 // the inlined concrete instance. Since these will be blocks inside the containing "real"
1098 // function the offset will be for that function.
1099 if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1100 {
Greg Claytonea3e7d52011-10-08 00:49:15 +00001101 subprogram_low_pc = ranges.GetMinRangeBase(0);
Jim Inghamb0be4422010-08-12 01:20:14 +00001102 }
1103 }
1104
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001105 AddRangesToBlock (*block, ranges, subprogram_low_pc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001106
1107 if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1108 {
1109 std::auto_ptr<Declaration> decl_ap;
1110 if (decl_file != 0 || decl_line != 0 || decl_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001111 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1112 decl_line, decl_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001113
1114 std::auto_ptr<Declaration> call_ap;
1115 if (call_file != 0 || call_line != 0 || call_column != 0)
Jim Inghamb0be4422010-08-12 01:20:14 +00001116 call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1117 call_line, call_column));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001118
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001119 block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001120 }
1121
1122 ++blocks_added;
1123
Greg Claytondd7feaf2011-08-12 17:54:33 +00001124 if (die->HasChildren())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001126 blocks_added += ParseFunctionBlocks (sc,
1127 block,
1128 dwarf_cu,
1129 die->GetFirstChild(),
1130 subprogram_low_pc,
Greg Claytondd7feaf2011-08-12 17:54:33 +00001131 depth + 1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001132 }
1133 }
1134 }
1135 break;
1136 default:
1137 break;
1138 }
1139
Greg Claytondd7feaf2011-08-12 17:54:33 +00001140 // Only parse siblings of the block if we are not at depth zero. A depth
1141 // of zero indicates we are currently parsing the top level
1142 // DW_TAG_subprogram DIE
1143
1144 if (depth == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145 die = NULL;
Greg Claytondd7feaf2011-08-12 17:54:33 +00001146 else
1147 die = die->GetSibling();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001148 }
1149 return blocks_added;
1150}
1151
Greg Claytonf0705c82011-10-22 03:33:13 +00001152bool
1153SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
1154 const DWARFDebugInfoEntry *parent_die,
1155 ClangASTContext::TemplateParameterInfos &template_param_infos)
1156{
1157
1158 if (parent_die == NULL)
1159 return NULL;
1160
1161 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1162
1163 Args template_parameter_names;
1164 for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild();
1165 die != NULL;
1166 die = die->GetSibling())
1167 {
1168 const dw_tag_t tag = die->Tag();
1169
1170 switch (tag)
1171 {
1172 case DW_TAG_template_type_parameter:
1173 case DW_TAG_template_value_parameter:
1174 {
1175 DWARFDebugInfoEntry::Attributes attributes;
1176 const size_t num_attributes = die->GetAttributes (this,
1177 dwarf_cu,
1178 fixed_form_sizes,
1179 attributes);
1180 const char *name = NULL;
1181 Type *lldb_type = NULL;
1182 clang_type_t clang_type = NULL;
1183 uint64_t uval64 = 0;
1184 bool uval64_valid = false;
1185 if (num_attributes > 0)
1186 {
1187 DWARFFormValue form_value;
1188 for (size_t i=0; i<num_attributes; ++i)
1189 {
1190 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1191
1192 switch (attr)
1193 {
1194 case DW_AT_name:
1195 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1196 name = form_value.AsCString(&get_debug_str_data());
1197 break;
1198
1199 case DW_AT_type:
1200 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1201 {
1202 const dw_offset_t type_die_offset = form_value.Reference(dwarf_cu);
1203 lldb_type = ResolveTypeUID(type_die_offset);
1204 if (lldb_type)
1205 clang_type = lldb_type->GetClangForwardType();
1206 }
1207 break;
1208
1209 case DW_AT_const_value:
1210 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1211 {
1212 uval64_valid = true;
1213 uval64 = form_value.Unsigned();
1214 }
1215 break;
1216 default:
1217 break;
1218 }
1219 }
1220
1221 if (name && lldb_type && clang_type)
1222 {
1223 bool is_signed = false;
1224 template_param_infos.names.push_back(name);
1225 clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type));
1226 if (tag == DW_TAG_template_value_parameter && ClangASTContext::IsIntegerType (clang_type, is_signed) && uval64_valid)
1227 {
1228 llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
1229 template_param_infos.args.push_back (clang::TemplateArgument (llvm::APSInt(apint), clang_qual_type));
1230 }
1231 else
1232 {
1233 template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type));
1234 }
1235 }
1236 else
1237 {
1238 return false;
1239 }
1240
1241 }
1242 }
1243 break;
1244
1245 default:
1246 break;
1247 }
1248 }
1249 if (template_param_infos.args.empty())
1250 return false;
1251 return template_param_infos.args.size() == template_param_infos.names.size();
1252}
1253
1254clang::ClassTemplateDecl *
1255SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00001256 lldb::AccessType access_type,
Greg Claytonf0705c82011-10-22 03:33:13 +00001257 const char *parent_name,
1258 int tag_decl_kind,
1259 const ClangASTContext::TemplateParameterInfos &template_param_infos)
1260{
1261 if (template_param_infos.IsValid())
1262 {
1263 std::string template_basename(parent_name);
1264 template_basename.erase (template_basename.find('<'));
1265 ClangASTContext &ast = GetClangASTContext();
1266
1267 return ast.CreateClassTemplateDecl (decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00001268 access_type,
Greg Claytonf0705c82011-10-22 03:33:13 +00001269 template_basename.c_str(),
1270 tag_decl_kind,
1271 template_param_infos);
1272 }
1273 return NULL;
1274}
1275
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001276size_t
1277SymbolFileDWARF::ParseChildMembers
1278(
1279 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00001280 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281 const DWARFDebugInfoEntry *parent_die,
Greg Clayton1be10fc2010-09-29 01:12:09 +00001282 clang_type_t class_clang_type,
Greg Clayton9e409562010-07-28 02:04:09 +00001283 const LanguageType class_language,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001284 std::vector<clang::CXXBaseSpecifier *>& base_classes,
1285 std::vector<int>& member_accessibilities,
Greg Claytonc93237c2010-10-01 20:48:32 +00001286 DWARFDIECollection& member_function_dies,
Sean Callananc7fbf732010-08-06 00:32:49 +00001287 AccessType& default_accessibility,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001288 bool &is_a_class
1289)
1290{
1291 if (parent_die == NULL)
1292 return 0;
1293
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001294 size_t count = 0;
1295 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00001296 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Greg Clayton6beaaa62011-01-17 03:46:26 +00001297 uint32_t member_idx = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00001298
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001299 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1300 {
1301 dw_tag_t tag = die->Tag();
1302
1303 switch (tag)
1304 {
1305 case DW_TAG_member:
1306 {
1307 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001308 const size_t num_attributes = die->GetAttributes (this,
1309 dwarf_cu,
1310 fixed_form_sizes,
1311 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001312 if (num_attributes > 0)
1313 {
1314 Declaration decl;
Greg Clayton73b472d2010-10-27 03:32:59 +00001315 //DWARFExpression location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001316 const char *name = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00001317 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001318 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001319 AccessType accessibility = eAccessNone;
Greg Clayton73b472d2010-10-27 03:32:59 +00001320 //off_t member_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001321 size_t byte_size = 0;
1322 size_t bit_offset = 0;
1323 size_t bit_size = 0;
1324 uint32_t i;
Greg Clayton24739922010-10-13 03:15:28 +00001325 for (i=0; i<num_attributes && !is_artificial; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001326 {
1327 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1328 DWARFFormValue form_value;
1329 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1330 {
1331 switch (attr)
1332 {
1333 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1334 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1335 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1336 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
1337 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1338 case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
1339 case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
1340 case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
1341 case DW_AT_data_member_location:
Greg Clayton73b472d2010-10-27 03:32:59 +00001342// if (form_value.BlockData())
1343// {
1344// Value initialValue(0);
1345// Value memberOffset(0);
1346// const DataExtractor& debug_info_data = get_debug_info_data();
1347// uint32_t block_length = form_value.Unsigned();
1348// uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1349// if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1350// {
1351// member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1352// }
1353// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001354 break;
1355
Greg Clayton8cf05932010-07-22 18:30:50 +00001356 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
Greg Clayton24739922010-10-13 03:15:28 +00001357 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001358 case DW_AT_declaration:
1359 case DW_AT_description:
1360 case DW_AT_mutable:
1361 case DW_AT_visibility:
1362 default:
1363 case DW_AT_sibling:
1364 break;
1365 }
1366 }
1367 }
Sean Callanan5a477cf2010-10-30 01:56:10 +00001368
Greg Clayton44953932011-10-25 01:25:35 +00001369 // Clang has a DWARF generation bug where sometimes it
1370 // represents fields that are references with bad byte size
1371 // and bit size/offset information such as:
1372 //
1373 // DW_AT_byte_size( 0x00 )
1374 // DW_AT_bit_size( 0x40 )
1375 // DW_AT_bit_offset( 0xffffffffffffffc0 )
1376 //
1377 // So check the bit offset to make sure it is sane, and if
1378 // the values are not sane, remove them. If we don't do this
1379 // then we will end up with a crash if we try to use this
1380 // type in an expression when clang becomes unhappy with its
1381 // recycled debug info.
Sean Callanan5a477cf2010-10-30 01:56:10 +00001382
Greg Clayton44953932011-10-25 01:25:35 +00001383 if (bit_offset > 128)
1384 {
1385 bit_size = 0;
1386 bit_offset = 0;
1387 }
1388
1389 // FIXME: Make Clang ignore Objective-C accessibility for expressions
Sean Callanan5a477cf2010-10-30 01:56:10 +00001390 if (class_language == eLanguageTypeObjC ||
1391 class_language == eLanguageTypeObjC_plus_plus)
1392 accessibility = eAccessNone;
Greg Clayton6beaaa62011-01-17 03:46:26 +00001393
1394 if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1395 {
1396 // Not all compilers will mark the vtable pointer
1397 // member as artificial (llvm-gcc). We can't have
1398 // the virtual members in our classes otherwise it
1399 // throws off all child offsets since we end up
1400 // having and extra pointer sized member in our
1401 // class layouts.
1402 is_artificial = true;
1403 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404
Greg Clayton24739922010-10-13 03:15:28 +00001405 if (is_artificial == false)
1406 {
1407 Type *member_type = ResolveTypeUID(encoding_uid);
Greg Claytond16e1e52011-07-12 17:06:17 +00001408 if (member_type)
1409 {
1410 if (accessibility == eAccessNone)
1411 accessibility = default_accessibility;
1412 member_accessibilities.push_back(accessibility);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001413
Greg Claytond16e1e52011-07-12 17:06:17 +00001414 GetClangASTContext().AddFieldToRecordType (class_clang_type,
1415 name,
1416 member_type->GetClangLayoutType(),
1417 accessibility,
1418 bit_size);
1419 }
1420 else
1421 {
1422 if (name)
Greg Clayton81c22f62011-10-19 18:09:39 +00001423 ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed",
1424 MakeUserID(die->GetOffset()),
Greg Claytond16e1e52011-07-12 17:06:17 +00001425 name,
1426 encoding_uid);
1427 else
Greg Clayton81c22f62011-10-19 18:09:39 +00001428 ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed",
1429 MakeUserID(die->GetOffset()),
Greg Claytond16e1e52011-07-12 17:06:17 +00001430 encoding_uid);
1431 }
Greg Clayton24739922010-10-13 03:15:28 +00001432 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001433 }
Greg Clayton6beaaa62011-01-17 03:46:26 +00001434 ++member_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001435 }
1436 break;
1437
1438 case DW_TAG_subprogram:
Greg Claytonc93237c2010-10-01 20:48:32 +00001439 // Let the type parsing code handle this one for us.
1440 member_function_dies.Append (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001441 break;
1442
1443 case DW_TAG_inheritance:
1444 {
1445 is_a_class = true;
Sean Callananc7fbf732010-08-06 00:32:49 +00001446 if (default_accessibility == eAccessNone)
1447 default_accessibility = eAccessPrivate;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001448 // TODO: implement DW_TAG_inheritance type parsing
1449 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytonba2d22d2010-11-13 22:57:37 +00001450 const size_t num_attributes = die->GetAttributes (this,
1451 dwarf_cu,
1452 fixed_form_sizes,
1453 attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001454 if (num_attributes > 0)
1455 {
1456 Declaration decl;
1457 DWARFExpression location;
1458 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
Sean Callananc7fbf732010-08-06 00:32:49 +00001459 AccessType accessibility = default_accessibility;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001460 bool is_virtual = false;
1461 bool is_base_of_class = true;
1462 off_t member_offset = 0;
1463 uint32_t i;
1464 for (i=0; i<num_attributes; ++i)
1465 {
1466 const dw_attr_t attr = attributes.AttributeAtIndex(i);
1467 DWARFFormValue form_value;
1468 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1469 {
1470 switch (attr)
1471 {
1472 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1473 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
1474 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1475 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
1476 case DW_AT_data_member_location:
1477 if (form_value.BlockData())
1478 {
1479 Value initialValue(0);
1480 Value memberOffset(0);
1481 const DataExtractor& debug_info_data = get_debug_info_data();
1482 uint32_t block_length = form_value.Unsigned();
1483 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
Greg Claytonba2d22d2010-11-13 22:57:37 +00001484 if (DWARFExpression::Evaluate (NULL,
1485 NULL,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001486 NULL,
1487 NULL,
Jason Molenda2d107dd2010-11-20 01:28:30 +00001488 NULL,
Greg Clayton1a65ae12011-01-25 23:55:37 +00001489 debug_info_data,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001490 block_offset,
1491 block_length,
1492 eRegisterKindDWARF,
1493 &initialValue,
1494 memberOffset,
1495 NULL))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001496 {
1497 member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1498 }
1499 }
1500 break;
1501
1502 case DW_AT_accessibility:
Greg Clayton8cf05932010-07-22 18:30:50 +00001503 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001504 break;
1505
1506 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1507 default:
1508 case DW_AT_sibling:
1509 break;
1510 }
1511 }
1512 }
1513
Greg Clayton526e5af2010-11-13 03:52:47 +00001514 Type *base_class_type = ResolveTypeUID(encoding_uid);
1515 assert(base_class_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001516
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001517 clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1518 assert (base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001519 if (class_language == eLanguageTypeObjC)
1520 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001521 GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
Greg Clayton9e409562010-07-28 02:04:09 +00001522 }
1523 else
1524 {
Greg Claytonf4ecaa52011-02-16 23:00:21 +00001525 base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
Greg Claytonba2d22d2010-11-13 22:57:37 +00001526 accessibility,
1527 is_virtual,
1528 is_base_of_class));
Greg Clayton9e409562010-07-28 02:04:09 +00001529 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001530 }
1531 }
1532 break;
1533
1534 default:
1535 break;
1536 }
1537 }
1538 return count;
1539}
1540
1541
1542clang::DeclContext*
Sean Callanan72e49402011-08-05 23:43:37 +00001543SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001544{
1545 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton81c22f62011-10-19 18:09:39 +00001546 if (debug_info && UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001547 {
1548 DWARFCompileUnitSP cu_sp;
1549 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1550 if (die)
Greg Claytoncb5860a2011-10-13 23:49:28 +00001551 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
Sean Callanan72e49402011-08-05 23:43:37 +00001552 }
1553 return NULL;
1554}
1555
1556clang::DeclContext*
1557SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1558{
Greg Clayton81c22f62011-10-19 18:09:39 +00001559 if (UserIDMatches(type_uid))
1560 return GetClangDeclContextForDIEOffset (sc, type_uid);
1561 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001562}
1563
1564Type*
Greg Claytonc685f8e2010-09-15 04:15:46 +00001565SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001566{
Greg Clayton81c22f62011-10-19 18:09:39 +00001567 if (UserIDMatches(type_uid))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001568 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001569 DWARFDebugInfo* debug_info = DebugInfo();
1570 if (debug_info)
Greg Claytonca512b32011-01-14 04:54:56 +00001571 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001572 DWARFCompileUnitSP cu_sp;
1573 const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1574 if (type_die != NULL)
Greg Claytonca512b32011-01-14 04:54:56 +00001575 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001576 // We might be coming in in the middle of a type tree (a class
1577 // withing a class, an enum within a class), so parse any needed
1578 // parent DIEs before we get to this one...
1579 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu_sp.get(), type_die);
1580 switch (decl_ctx_die->Tag())
1581 {
1582 case DW_TAG_structure_type:
1583 case DW_TAG_union_type:
1584 case DW_TAG_class_type:
1585 ResolveType(cu_sp.get(), decl_ctx_die);
1586 break;
1587 }
1588 return ResolveType (cu_sp.get(), type_die);
Greg Claytonca512b32011-01-14 04:54:56 +00001589 }
Greg Claytonca512b32011-01-14 04:54:56 +00001590 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001591 }
1592 return NULL;
1593}
1594
Greg Clayton6beaaa62011-01-17 03:46:26 +00001595// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1596// SymbolFileDWARF objects to detect if this DWARF file is the one that
1597// can resolve a clang_type.
1598bool
1599SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1600{
1601 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1602 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1603 return die != NULL;
1604}
1605
1606
Greg Clayton1be10fc2010-09-29 01:12:09 +00001607lldb::clang_type_t
1608SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1609{
1610 // We have a struct/union/class/enum that needs to be fully resolved.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001611 clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1612 const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001613 if (die == NULL)
Greg Clayton73b472d2010-10-27 03:32:59 +00001614 {
1615 // We have already resolved this type...
1616 return clang_type;
1617 }
1618 // Once we start resolving this type, remove it from the forward declaration
1619 // map in case anyone child members or other types require this type to get resolved.
1620 // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1621 // are done.
Greg Clayton6beaaa62011-01-17 03:46:26 +00001622 m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
Greg Clayton73b472d2010-10-27 03:32:59 +00001623
Greg Clayton1be10fc2010-09-29 01:12:09 +00001624
Greg Clayton85ae2e12011-10-18 23:36:41 +00001625 // Disable external storage for this type so we don't get anymore
1626 // clang::ExternalASTSource queries for this type.
1627 ClangASTContext::SetHasExternalStorage (clang_type, false);
1628
Greg Clayton450e3f32010-10-12 02:24:53 +00001629 DWARFDebugInfo* debug_info = DebugInfo();
1630
Greg Clayton96d7d742010-11-10 23:42:09 +00001631 DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001632 Type *type = m_die_to_type.lookup (die);
1633
1634 const dw_tag_t tag = die->Tag();
1635
Greg Clayton81c22f62011-10-19 18:09:39 +00001636 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") - resolve forward declaration...\n",
1637 MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001638 DW_TAG_value_to_name(tag),
1639 type->GetName().AsCString());
Greg Clayton1be10fc2010-09-29 01:12:09 +00001640 assert (clang_type);
1641 DWARFDebugInfoEntry::Attributes attributes;
1642
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001643 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00001644
1645 switch (tag)
1646 {
1647 case DW_TAG_structure_type:
1648 case DW_TAG_union_type:
1649 case DW_TAG_class_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001650 ast.StartTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001651 if (die->HasChildren())
1652 {
1653 LanguageType class_language = eLanguageTypeUnknown;
Greg Clayton450e3f32010-10-12 02:24:53 +00001654 bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1655 if (is_objc_class)
Greg Claytonc93237c2010-10-01 20:48:32 +00001656 class_language = eLanguageTypeObjC;
1657
1658 int tag_decl_kind = -1;
1659 AccessType default_accessibility = eAccessNone;
1660 if (tag == DW_TAG_structure_type)
Greg Clayton1be10fc2010-09-29 01:12:09 +00001661 {
Greg Claytonc93237c2010-10-01 20:48:32 +00001662 tag_decl_kind = clang::TTK_Struct;
1663 default_accessibility = eAccessPublic;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001664 }
Greg Claytonc93237c2010-10-01 20:48:32 +00001665 else if (tag == DW_TAG_union_type)
1666 {
1667 tag_decl_kind = clang::TTK_Union;
1668 default_accessibility = eAccessPublic;
1669 }
1670 else if (tag == DW_TAG_class_type)
1671 {
1672 tag_decl_kind = clang::TTK_Class;
1673 default_accessibility = eAccessPrivate;
1674 }
1675
Greg Clayton96d7d742010-11-10 23:42:09 +00001676 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
Greg Claytonc93237c2010-10-01 20:48:32 +00001677 std::vector<clang::CXXBaseSpecifier *> base_classes;
1678 std::vector<int> member_accessibilities;
1679 bool is_a_class = false;
1680 // Parse members and base classes first
1681 DWARFDIECollection member_function_dies;
1682
1683 ParseChildMembers (sc,
Greg Clayton96d7d742010-11-10 23:42:09 +00001684 curr_cu,
Greg Claytonc93237c2010-10-01 20:48:32 +00001685 die,
1686 clang_type,
1687 class_language,
1688 base_classes,
1689 member_accessibilities,
1690 member_function_dies,
1691 default_accessibility,
1692 is_a_class);
1693
1694 // Now parse any methods if there were any...
1695 size_t num_functions = member_function_dies.Size();
1696 if (num_functions > 0)
1697 {
1698 for (size_t i=0; i<num_functions; ++i)
1699 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001700 ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
Greg Claytonc93237c2010-10-01 20:48:32 +00001701 }
1702 }
1703
Greg Clayton450e3f32010-10-12 02:24:53 +00001704 if (class_language == eLanguageTypeObjC)
1705 {
Greg Claytone3055942011-06-30 02:28:26 +00001706 std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
Greg Clayton450e3f32010-10-12 02:24:53 +00001707 if (!class_str.empty())
1708 {
1709
Greg Claytond4a2b372011-09-12 23:21:58 +00001710 DIEArray method_die_offsets;
Greg Clayton5009f9d2011-10-27 17:55:14 +00001711 if (m_using_apple_tables)
1712 {
1713 if (m_apple_objc_ap.get())
1714 m_apple_objc_ap->FindByName(class_str.c_str(), method_die_offsets);
1715 }
1716 else
1717 {
1718 if (!m_indexed)
1719 Index ();
1720
1721 ConstString class_name (class_str.c_str());
1722 m_objc_class_selectors_index.Find (class_name, method_die_offsets);
1723 }
1724
1725 if (!method_die_offsets.empty())
Greg Clayton450e3f32010-10-12 02:24:53 +00001726 {
Greg Claytond4a2b372011-09-12 23:21:58 +00001727 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton450e3f32010-10-12 02:24:53 +00001728
Greg Claytond4a2b372011-09-12 23:21:58 +00001729 DWARFCompileUnit* method_cu = NULL;
1730 const size_t num_matches = method_die_offsets.size();
1731 for (size_t i=0; i<num_matches; ++i)
1732 {
1733 const dw_offset_t die_offset = method_die_offsets[i];
1734 DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
Greg Clayton450e3f32010-10-12 02:24:53 +00001735
1736 ResolveType (method_cu, method_die);
1737 }
1738 }
1739 }
1740 }
1741
Greg Claytonc93237c2010-10-01 20:48:32 +00001742 // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1743 // need to tell the clang type it is actually a class.
1744 if (class_language != eLanguageTypeObjC)
1745 {
1746 if (is_a_class && tag_decl_kind != clang::TTK_Class)
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001747 ast.SetTagTypeKind (clang_type, clang::TTK_Class);
Greg Claytonc93237c2010-10-01 20:48:32 +00001748 }
1749
1750 // Since DW_TAG_structure_type gets used for both classes
1751 // and structures, we may need to set any DW_TAG_member
1752 // fields to have a "private" access if none was specified.
1753 // When we parsed the child members we tracked that actual
1754 // accessibility value for each DW_TAG_member in the
1755 // "member_accessibilities" array. If the value for the
1756 // member is zero, then it was set to the "default_accessibility"
1757 // which for structs was "public". Below we correct this
1758 // by setting any fields to "private" that weren't correctly
1759 // set.
1760 if (is_a_class && !member_accessibilities.empty())
1761 {
1762 // This is a class and all members that didn't have
1763 // their access specified are private.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001764 ast.SetDefaultAccessForRecordFields (clang_type,
1765 eAccessPrivate,
1766 &member_accessibilities.front(),
1767 member_accessibilities.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001768 }
1769
1770 if (!base_classes.empty())
1771 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001772 ast.SetBaseClassesForClassType (clang_type,
1773 &base_classes.front(),
1774 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001775
1776 // Clang will copy each CXXBaseSpecifier in "base_classes"
1777 // so we have to free them all.
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001778 ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1779 base_classes.size());
Greg Claytonc93237c2010-10-01 20:48:32 +00001780 }
1781
1782 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001783 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Claytonc93237c2010-10-01 20:48:32 +00001784 return clang_type;
Greg Clayton1be10fc2010-09-29 01:12:09 +00001785
1786 case DW_TAG_enumeration_type:
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001787 ast.StartTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001788 if (die->HasChildren())
1789 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001790 SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1791 ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001792 }
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00001793 ast.CompleteTagDeclarationDefinition (clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00001794 return clang_type;
1795
1796 default:
1797 assert(false && "not a forward clang type decl!");
1798 break;
1799 }
1800 return NULL;
1801}
1802
Greg Claytonc685f8e2010-09-15 04:15:46 +00001803Type*
Greg Clayton96d7d742010-11-10 23:42:09 +00001804SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
Greg Claytonc685f8e2010-09-15 04:15:46 +00001805{
1806 if (type_die != NULL)
1807 {
Greg Clayton594e5ed2010-09-27 21:07:38 +00001808 Type *type = m_die_to_type.lookup (type_die);
Greg Claytonc685f8e2010-09-15 04:15:46 +00001809 if (type == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001810 type = GetTypeForDIE (curr_cu, type_die).get();
Greg Clayton24739922010-10-13 03:15:28 +00001811 if (assert_not_being_parsed)
1812 assert (type != DIE_IS_BEING_PARSED);
Greg Clayton594e5ed2010-09-27 21:07:38 +00001813 return type;
Greg Claytonc685f8e2010-09-15 04:15:46 +00001814 }
1815 return NULL;
1816}
1817
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001818CompileUnit*
Greg Clayton96d7d742010-11-10 23:42:09 +00001819SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001820{
1821 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001822 if (curr_cu->GetUserData() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001823 {
1824 // The symbol vendor doesn't know about this compile unit, we
1825 // need to parse and add it to the symbol vendor object.
1826 CompUnitSP dc_cu;
Greg Clayton96d7d742010-11-10 23:42:09 +00001827 ParseCompileUnit(curr_cu, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001828 if (dc_cu.get())
1829 {
1830 // Figure out the compile unit index if we weren't given one
Greg Clayton016a95e2010-09-14 02:20:48 +00001831 if (cu_idx == UINT32_MAX)
Greg Clayton96d7d742010-11-10 23:42:09 +00001832 DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001833
1834 m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
Greg Clayton450e3f32010-10-12 02:24:53 +00001835
1836 if (m_debug_map_symfile)
1837 m_debug_map_symfile->SetCompileUnit(this, dc_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001838 }
1839 }
Greg Clayton96d7d742010-11-10 23:42:09 +00001840 return (CompileUnit*)curr_cu->GetUserData();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001841}
1842
1843bool
Greg Clayton96d7d742010-11-10 23:42:09 +00001844SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001845{
1846 sc.Clear();
1847 // Check if the symbol vendor already knows about this compile unit?
Greg Clayton96d7d742010-11-10 23:42:09 +00001848 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001849
Greg Clayton81c22f62011-10-19 18:09:39 +00001850 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001851 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001852 sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
Jim Ingham4cda6e02011-10-07 22:23:45 +00001853
1854 if (sc.function)
1855 {
1856 sc.module_sp = sc.function->CalculateSymbolContextModule();
1857 return true;
1858 }
1859
1860 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001861}
1862
1863uint32_t
1864SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1865{
1866 Timer scoped_timer(__PRETTY_FUNCTION__,
1867 "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1868 so_addr.GetSection(),
1869 so_addr.GetOffset(),
1870 resolve_scope);
1871 uint32_t resolved = 0;
1872 if (resolve_scope & ( eSymbolContextCompUnit |
1873 eSymbolContextFunction |
1874 eSymbolContextBlock |
1875 eSymbolContextLineEntry))
1876 {
1877 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1878
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001879 DWARFDebugInfo* debug_info = DebugInfo();
Greg Claytond4a2b372011-09-12 23:21:58 +00001880 if (debug_info)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001881 {
Greg Claytond4a2b372011-09-12 23:21:58 +00001882 dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001883 if (cu_offset != DW_INVALID_OFFSET)
1884 {
1885 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001886 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1887 if (curr_cu)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001888 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001889 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001890 assert(sc.comp_unit != NULL);
1891 resolved |= eSymbolContextCompUnit;
1892
1893 if (resolve_scope & eSymbolContextLineEntry)
1894 {
1895 LineTable *line_table = sc.comp_unit->GetLineTable();
1896 if (line_table == NULL)
1897 {
1898 if (ParseCompileUnitLineTable(sc))
1899 line_table = sc.comp_unit->GetLineTable();
1900 }
1901 if (line_table != NULL)
1902 {
1903 if (so_addr.IsLinkedAddress())
1904 {
1905 Address linked_addr (so_addr);
1906 linked_addr.ResolveLinkedAddress();
1907 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1908 {
1909 resolved |= eSymbolContextLineEntry;
1910 }
1911 }
1912 else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1913 {
1914 resolved |= eSymbolContextLineEntry;
1915 }
1916 }
1917 }
1918
1919 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1920 {
1921 DWARFDebugInfoEntry *function_die = NULL;
1922 DWARFDebugInfoEntry *block_die = NULL;
1923 if (resolve_scope & eSymbolContextBlock)
1924 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001925 curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001926 }
1927 else
1928 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001929 curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001930 }
1931
1932 if (function_die != NULL)
1933 {
Greg Clayton81c22f62011-10-19 18:09:39 +00001934 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001935 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00001936 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001937 }
1938
1939 if (sc.function != NULL)
1940 {
1941 resolved |= eSymbolContextFunction;
1942
1943 if (resolve_scope & eSymbolContextBlock)
1944 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00001945 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001946
1947 if (block_die != NULL)
Greg Clayton81c22f62011-10-19 18:09:39 +00001948 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001949 else
Greg Clayton81c22f62011-10-19 18:09:39 +00001950 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001951 if (sc.block)
1952 resolved |= eSymbolContextBlock;
1953 }
1954 }
1955 }
1956 }
1957 }
1958 }
1959 }
1960 return resolved;
1961}
1962
1963
1964
1965uint32_t
1966SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1967{
1968 const uint32_t prev_size = sc_list.GetSize();
1969 if (resolve_scope & eSymbolContextCompUnit)
1970 {
1971 DWARFDebugInfo* debug_info = DebugInfo();
1972 if (debug_info)
1973 {
1974 uint32_t cu_idx;
Greg Clayton96d7d742010-11-10 23:42:09 +00001975 DWARFCompileUnit* curr_cu = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001976
Greg Clayton96d7d742010-11-10 23:42:09 +00001977 for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001978 {
Greg Clayton96d7d742010-11-10 23:42:09 +00001979 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001980 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1981 if (check_inlines || file_spec_matches_cu_file_spec)
1982 {
1983 SymbolContext sc (m_obj_file->GetModule());
Greg Clayton96d7d742010-11-10 23:42:09 +00001984 sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001985 assert(sc.comp_unit != NULL);
1986
1987 uint32_t file_idx = UINT32_MAX;
1988
1989 // If we are looking for inline functions only and we don't
1990 // find it in the support files, we are done.
1991 if (check_inlines)
1992 {
Jim Ingham87df91b2011-09-23 00:54:11 +00001993 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001994 if (file_idx == UINT32_MAX)
1995 continue;
1996 }
1997
1998 if (line != 0)
1999 {
2000 LineTable *line_table = sc.comp_unit->GetLineTable();
2001
2002 if (line_table != NULL && line != 0)
2003 {
2004 // We will have already looked up the file index if
2005 // we are searching for inline entries.
2006 if (!check_inlines)
Jim Ingham87df91b2011-09-23 00:54:11 +00002007 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002008
2009 if (file_idx != UINT32_MAX)
2010 {
2011 uint32_t found_line;
2012 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
2013 found_line = sc.line_entry.line;
2014
Greg Clayton016a95e2010-09-14 02:20:48 +00002015 while (line_idx != UINT32_MAX)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002016 {
2017 sc.function = NULL;
2018 sc.block = NULL;
2019 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
2020 {
2021 const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
2022 if (file_vm_addr != LLDB_INVALID_ADDRESS)
2023 {
2024 DWARFDebugInfoEntry *function_die = NULL;
2025 DWARFDebugInfoEntry *block_die = NULL;
Greg Clayton96d7d742010-11-10 23:42:09 +00002026 curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002027
2028 if (function_die != NULL)
2029 {
Greg Clayton81c22f62011-10-19 18:09:39 +00002030 sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002031 if (sc.function == NULL)
Greg Clayton96d7d742010-11-10 23:42:09 +00002032 sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002033 }
2034
2035 if (sc.function != NULL)
2036 {
Greg Clayton0b76a2c2010-08-21 02:22:51 +00002037 Block& block = sc.function->GetBlock (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002038
2039 if (block_die != NULL)
Greg Clayton81c22f62011-10-19 18:09:39 +00002040 sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002041 else
Greg Clayton81c22f62011-10-19 18:09:39 +00002042 sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002043 }
2044 }
2045 }
2046
2047 sc_list.Append(sc);
2048 line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
2049 }
2050 }
2051 }
2052 else if (file_spec_matches_cu_file_spec && !check_inlines)
2053 {
2054 // only append the context if we aren't looking for inline call sites
2055 // by file and line and if the file spec matches that of the compile unit
2056 sc_list.Append(sc);
2057 }
2058 }
2059 else if (file_spec_matches_cu_file_spec && !check_inlines)
2060 {
2061 // only append the context if we aren't looking for inline call sites
2062 // by file and line and if the file spec matches that of the compile unit
2063 sc_list.Append(sc);
2064 }
2065
2066 if (!check_inlines)
2067 break;
2068 }
2069 }
2070 }
2071 }
2072 return sc_list.GetSize() - prev_size;
2073}
2074
2075void
2076SymbolFileDWARF::Index ()
2077{
2078 if (m_indexed)
2079 return;
2080 m_indexed = true;
2081 Timer scoped_timer (__PRETTY_FUNCTION__,
2082 "SymbolFileDWARF::Index (%s)",
2083 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
2084
2085 DWARFDebugInfo* debug_info = DebugInfo();
2086 if (debug_info)
2087 {
2088 uint32_t cu_idx = 0;
2089 const uint32_t num_compile_units = GetNumCompileUnits();
2090 for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2091 {
Greg Clayton96d7d742010-11-10 23:42:09 +00002092 DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002093
Greg Clayton96d7d742010-11-10 23:42:09 +00002094 bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002095
Greg Clayton96d7d742010-11-10 23:42:09 +00002096 curr_cu->Index (cu_idx,
Greg Clayton83c5cd92010-11-14 22:13:40 +00002097 m_function_basename_index,
2098 m_function_fullname_index,
2099 m_function_method_index,
2100 m_function_selector_index,
2101 m_objc_class_selectors_index,
2102 m_global_index,
2103 m_type_index,
Greg Claytond4a2b372011-09-12 23:21:58 +00002104 m_namespace_index);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002105
2106 // Keep memory down by clearing DIEs if this generate function
2107 // caused them to be parsed
2108 if (clear_dies)
Greg Clayton96d7d742010-11-10 23:42:09 +00002109 curr_cu->ClearDIEs (true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002110 }
2111
Greg Claytond4a2b372011-09-12 23:21:58 +00002112 m_function_basename_index.Finalize();
2113 m_function_fullname_index.Finalize();
2114 m_function_method_index.Finalize();
2115 m_function_selector_index.Finalize();
2116 m_objc_class_selectors_index.Finalize();
2117 m_global_index.Finalize();
2118 m_type_index.Finalize();
2119 m_namespace_index.Finalize();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002120
Greg Clayton24739922010-10-13 03:15:28 +00002121#if defined (ENABLE_DEBUG_PRINTF)
Greg Clayton7bd65b92011-02-09 23:39:34 +00002122 StreamFile s(stdout, false);
Greg Claytonf9eec202011-09-01 23:16:13 +00002123 s.Printf ("DWARF index for '%s/%s':",
Greg Clayton24739922010-10-13 03:15:28 +00002124 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
2125 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
Greg Claytonba2d22d2010-11-13 22:57:37 +00002126 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
2127 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
2128 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
2129 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
2130 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
2131 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
Greg Clayton69b04882010-10-15 02:03:22 +00002132 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
Greg Claytonba2d22d2010-11-13 22:57:37 +00002133 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
Greg Claytonc685f8e2010-09-15 04:15:46 +00002134#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002135 }
2136}
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002137
2138bool
2139SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl)
2140{
2141 if (namespace_decl == NULL)
2142 {
2143 // Invalid namespace decl which means we aren't matching only things
2144 // in this symbol file, so return true to indicate it matches this
2145 // symbol file.
2146 return true;
2147 }
2148
2149 clang::ASTContext *namespace_ast = namespace_decl->GetASTContext();
2150
2151 if (namespace_ast == NULL)
2152 return true; // No AST in the "namespace_decl", return true since it
2153 // could then match any symbol file, including this one
2154
2155 if (namespace_ast == GetClangASTContext().getASTContext())
2156 return true; // The ASTs match, return true
2157
2158 // The namespace AST was valid, and it does not match...
Sean Callananc41e68b2011-10-13 21:08:11 +00002159 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2160
2161 if (log)
2162 log->Printf("Valid namespace does not match symbol file");
2163
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002164 return false;
2165}
2166
Greg Clayton2506a7a2011-10-12 23:34:26 +00002167bool
2168SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl,
2169 DWARFCompileUnit* cu,
2170 const DWARFDebugInfoEntry* die)
2171{
2172 // No namespace specified, so the answesr i
2173 if (namespace_decl == NULL)
2174 return true;
Sean Callananebe60672011-10-13 21:50:33 +00002175
2176 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002177
Greg Clayton2506a7a2011-10-12 23:34:26 +00002178 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
2179 if (decl_ctx_die)
2180 {
Greg Claytonbfe3dd42011-10-13 00:00:53 +00002181
Greg Clayton2506a7a2011-10-12 23:34:26 +00002182 clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl();
2183 if (clang_namespace_decl)
2184 {
2185 if (decl_ctx_die->Tag() != DW_TAG_namespace)
Sean Callananebe60672011-10-13 21:50:33 +00002186 {
2187 if (log)
2188 log->Printf("Found a match, but its parent is not a namespace");
Greg Clayton2506a7a2011-10-12 23:34:26 +00002189 return false;
Sean Callananebe60672011-10-13 21:50:33 +00002190 }
2191
Greg Clayton2506a7a2011-10-12 23:34:26 +00002192 DeclContextToDIEMap::iterator pos = m_decl_ctx_to_die.find(clang_namespace_decl);
2193
2194 if (pos == m_decl_ctx_to_die.end())
Sean Callananebe60672011-10-13 21:50:33 +00002195 {
2196 if (log)
2197 log->Printf("Found a match in a namespace, but its parent is not the requested namespace");
2198
Greg Clayton2506a7a2011-10-12 23:34:26 +00002199 return false;
Sean Callananebe60672011-10-13 21:50:33 +00002200 }
Greg Clayton2506a7a2011-10-12 23:34:26 +00002201
Greg Claytoncb5860a2011-10-13 23:49:28 +00002202 return pos->second.count (decl_ctx_die);
Greg Clayton2506a7a2011-10-12 23:34:26 +00002203 }
2204 else
2205 {
2206 // We have a namespace_decl that was not NULL but it contained
2207 // a NULL "clang::NamespaceDecl", so this means the global namespace
2208 // So as long the the contained decl context DIE isn't a namespace
2209 // we should be ok.
2210 if (decl_ctx_die->Tag() != DW_TAG_namespace)
2211 return true;
2212 }
2213 }
Sean Callananebe60672011-10-13 21:50:33 +00002214
2215 if (log)
2216 log->Printf("Found a match, but its parent doesn't exist");
2217
Greg Clayton2506a7a2011-10-12 23:34:26 +00002218 return false;
2219}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002220uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +00002221SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002222{
Greg Clayton21f2a492011-10-06 00:09:08 +00002223 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2224
2225 if (log)
2226 {
2227 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", name=\"%s\", append=%u, max_matches=%u, variables)",
2228 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2229 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2230 name.GetCString(), append, max_matches);
2231 }
Sean Callanan213fdb82011-10-13 01:49:10 +00002232
2233 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
2234 return 0;
2235
Greg Claytonc685f8e2010-09-15 04:15:46 +00002236 DWARFDebugInfo* info = DebugInfo();
2237 if (info == NULL)
2238 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002239
2240 // If we aren't appending the results to this list, then clear the list
2241 if (!append)
2242 variables.Clear();
2243
2244 // Remember how many variables are in the list before we search in case
2245 // we are appending the results to a variable list.
2246 const uint32_t original_size = variables.GetSize();
2247
Greg Claytond4a2b372011-09-12 23:21:58 +00002248 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002249
Greg Clayton97fbc342011-10-20 22:30:33 +00002250 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002251 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002252 if (m_apple_names_ap.get())
2253 {
2254 const char *name_cstr = name.GetCString();
2255 const char *base_name_start;
2256 const char *base_name_end = NULL;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002257
Greg Clayton97fbc342011-10-20 22:30:33 +00002258 if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end))
2259 base_name_start = name_cstr;
2260
2261 m_apple_names_ap->FindByName (base_name_start, die_offsets);
2262 }
Greg Clayton7f995132011-10-04 22:41:51 +00002263 }
2264 else
2265 {
2266 // Index the DWARF if we haven't already
2267 if (!m_indexed)
2268 Index ();
2269
2270 m_global_index.Find (name, die_offsets);
2271 }
2272
2273 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002274 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002275 {
Greg Clayton7f995132011-10-04 22:41:51 +00002276 SymbolContext sc;
2277 sc.module_sp = m_obj_file->GetModule();
2278 assert (sc.module_sp);
2279
Greg Claytond4a2b372011-09-12 23:21:58 +00002280 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton7f995132011-10-04 22:41:51 +00002281 DWARFCompileUnit* dwarf_cu = NULL;
2282 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002283 for (size_t i=0; i<num_matches; ++i)
2284 {
2285 const dw_offset_t die_offset = die_offsets[i];
2286 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002287
Greg Claytond4a2b372011-09-12 23:21:58 +00002288 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2289 assert(sc.comp_unit != NULL);
Sean Callanan213fdb82011-10-13 01:49:10 +00002290
2291 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2292 continue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002293
Greg Claytond4a2b372011-09-12 23:21:58 +00002294 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002295
Greg Claytond4a2b372011-09-12 23:21:58 +00002296 if (variables.GetSize() - original_size >= max_matches)
2297 break;
2298 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002299 }
2300
2301 // Return the number of variable that were appended to the list
2302 return variables.GetSize() - original_size;
2303}
2304
2305uint32_t
2306SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2307{
Greg Clayton21f2a492011-10-06 00:09:08 +00002308 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2309
2310 if (log)
2311 {
2312 log->Printf ("SymbolFileDWARF::FindGlobalVariables (file=\"%s/%s\", regex=\"%s\", append=%u, max_matches=%u, variables)",
2313 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2314 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2315 regex.GetText(), append, max_matches);
2316 }
2317
Greg Claytonc685f8e2010-09-15 04:15:46 +00002318 DWARFDebugInfo* info = DebugInfo();
2319 if (info == NULL)
2320 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002321
2322 // If we aren't appending the results to this list, then clear the list
2323 if (!append)
2324 variables.Clear();
2325
2326 // Remember how many variables are in the list before we search in case
2327 // we are appending the results to a variable list.
2328 const uint32_t original_size = variables.GetSize();
2329
Greg Clayton7f995132011-10-04 22:41:51 +00002330 DIEArray die_offsets;
2331
Greg Clayton97fbc342011-10-20 22:30:33 +00002332 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002333 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002334 if (m_apple_names_ap.get())
2335 m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, die_offsets);
Greg Clayton7f995132011-10-04 22:41:51 +00002336 }
2337 else
2338 {
2339 // Index the DWARF if we haven't already
2340 if (!m_indexed)
2341 Index ();
2342
2343 m_global_index.Find (regex, die_offsets);
2344 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002345
Greg Claytonc685f8e2010-09-15 04:15:46 +00002346 SymbolContext sc;
Greg Claytona2eee182011-09-17 07:23:18 +00002347 sc.module_sp = m_obj_file->GetModule();
Greg Claytonc685f8e2010-09-15 04:15:46 +00002348 assert (sc.module_sp);
2349
Greg Claytond4a2b372011-09-12 23:21:58 +00002350 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytonc685f8e2010-09-15 04:15:46 +00002351 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00002352 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002353 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002354 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002355 DWARFDebugInfo* debug_info = DebugInfo();
2356 for (size_t i=0; i<num_matches; ++i)
2357 {
2358 const dw_offset_t die_offset = die_offsets[i];
2359 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2360 sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002361
Greg Claytond4a2b372011-09-12 23:21:58 +00002362 ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002363
Greg Claytond4a2b372011-09-12 23:21:58 +00002364 if (variables.GetSize() - original_size >= max_matches)
2365 break;
2366 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002367 }
2368
2369 // Return the number of variable that were appended to the list
2370 return variables.GetSize() - original_size;
2371}
2372
Greg Claytonaa044962011-10-13 00:59:38 +00002373
Jim Ingham4cda6e02011-10-07 22:23:45 +00002374bool
2375SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
2376 DWARFCompileUnit *&dwarf_cu,
2377 SymbolContextList& sc_list)
Greg Clayton9e315582011-09-02 04:03:59 +00002378{
Greg Claytonaa044962011-10-13 00:59:38 +00002379 const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2380 return ResolveFunction (dwarf_cu, die, sc_list);
2381}
2382
2383
2384bool
2385SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
2386 const DWARFDebugInfoEntry *die,
2387 SymbolContextList& sc_list)
2388{
Greg Clayton9e315582011-09-02 04:03:59 +00002389 SymbolContext sc;
Greg Claytonaa044962011-10-13 00:59:38 +00002390
2391 if (die == NULL)
2392 return false;
2393
Jim Ingham4cda6e02011-10-07 22:23:45 +00002394 // If we were passed a die that is not a function, just return false...
2395 if (die->Tag() != DW_TAG_subprogram && die->Tag() != DW_TAG_inlined_subroutine)
2396 return false;
2397
2398 const DWARFDebugInfoEntry* inlined_die = NULL;
2399 if (die->Tag() == DW_TAG_inlined_subroutine)
Greg Clayton9e315582011-09-02 04:03:59 +00002400 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002401 inlined_die = die;
Greg Clayton9e315582011-09-02 04:03:59 +00002402
Jim Ingham4cda6e02011-10-07 22:23:45 +00002403 while ((die = die->GetParent()) != NULL)
Greg Clayton2bc22f82011-09-30 03:20:47 +00002404 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002405 if (die->Tag() == DW_TAG_subprogram)
2406 break;
Greg Clayton9e315582011-09-02 04:03:59 +00002407 }
2408 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002409 assert (die->Tag() == DW_TAG_subprogram);
Greg Claytonaa044962011-10-13 00:59:38 +00002410 if (GetFunction (cu, die, sc))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002411 {
2412 Address addr;
2413 // Parse all blocks if needed
2414 if (inlined_die)
2415 {
Greg Clayton81c22f62011-10-19 18:09:39 +00002416 sc.block = sc.function->GetBlock (true).FindBlockByID (MakeUserID(inlined_die->GetOffset()));
Jim Ingham4cda6e02011-10-07 22:23:45 +00002417 assert (sc.block != NULL);
2418 if (sc.block->GetStartAddress (addr) == false)
2419 addr.Clear();
2420 }
2421 else
2422 {
2423 sc.block = NULL;
2424 addr = sc.function->GetAddressRange().GetBaseAddress();
2425 }
2426
2427 if (addr.IsValid())
2428 {
2429
2430 // We found the function, so we should find the line table
2431 // and line table entry as well
2432 LineTable *line_table = sc.comp_unit->GetLineTable();
2433 if (line_table == NULL)
2434 {
2435 if (ParseCompileUnitLineTable(sc))
2436 line_table = sc.comp_unit->GetLineTable();
2437 }
2438 if (line_table != NULL)
2439 line_table->FindLineEntryByAddress (addr, sc.line_entry);
2440
2441 sc_list.Append(sc);
Greg Claytonaa044962011-10-13 00:59:38 +00002442 return true;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002443 }
2444 }
2445
Greg Claytonaa044962011-10-13 00:59:38 +00002446 return false;
Greg Clayton9e315582011-09-02 04:03:59 +00002447}
2448
Greg Clayton7f995132011-10-04 22:41:51 +00002449void
2450SymbolFileDWARF::FindFunctions (const ConstString &name,
2451 const NameToDIE &name_to_die,
2452 SymbolContextList& sc_list)
2453{
Greg Claytond4a2b372011-09-12 23:21:58 +00002454 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002455 if (name_to_die.Find (name, die_offsets))
2456 {
2457 ParseFunctions (die_offsets, sc_list);
2458 }
2459}
2460
2461
2462void
2463SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2464 const NameToDIE &name_to_die,
2465 SymbolContextList& sc_list)
2466{
2467 DIEArray die_offsets;
2468 if (name_to_die.Find (regex, die_offsets))
2469 {
2470 ParseFunctions (die_offsets, sc_list);
2471 }
2472}
2473
2474
2475void
2476SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2477 const DWARFMappedHash::MemoryTable &memory_table,
2478 SymbolContextList& sc_list)
2479{
2480 DIEArray die_offsets;
2481 if (memory_table.AppendAllDIEsThatMatchingRegex (regex, die_offsets))
2482 {
2483 ParseFunctions (die_offsets, sc_list);
2484 }
2485}
2486
2487void
2488SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
2489 SymbolContextList& sc_list)
2490{
2491 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00002492 if (num_matches)
Greg Claytonc685f8e2010-09-15 04:15:46 +00002493 {
Greg Clayton7f995132011-10-04 22:41:51 +00002494 SymbolContext sc;
Greg Clayton7f995132011-10-04 22:41:51 +00002495
2496 DWARFCompileUnit* dwarf_cu = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002497 for (size_t i=0; i<num_matches; ++i)
Greg Claytond7e05462010-11-14 00:22:48 +00002498 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002499 const dw_offset_t die_offset = die_offsets[i];
Jim Ingham4cda6e02011-10-07 22:23:45 +00002500 ResolveFunction (die_offset, dwarf_cu, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002501 }
2502 }
Greg Claytonc685f8e2010-09-15 04:15:46 +00002503}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002504
Jim Ingham4cda6e02011-10-07 22:23:45 +00002505bool
2506SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
2507 const DWARFCompileUnit *dwarf_cu,
2508 uint32_t name_type_mask,
2509 const char *partial_name,
2510 const char *base_name_start,
2511 const char *base_name_end)
2512{
2513 // If we are looking only for methods, throw away all the ones that aren't in C++ classes:
2514 if (name_type_mask == eFunctionNameTypeMethod
2515 || name_type_mask == eFunctionNameTypeBase)
2516 {
Greg Claytonf0705c82011-10-22 03:33:13 +00002517 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
2518 if (!containing_decl_ctx)
2519 return false;
2520
2521 bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
2522
2523 if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod)
2524 return false;
2525 if (is_cxx_method && name_type_mask == eFunctionNameTypeBase)
2526 return false;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002527 }
2528
2529 // Now we need to check whether the name we got back for this type matches the extra specifications
2530 // that were in the name we're looking up:
2531 if (base_name_start != partial_name || *base_name_end != '\0')
2532 {
2533 // First see if the stuff to the left matches the full name. To do that let's see if
2534 // we can pull out the mips linkage name attribute:
2535
2536 Mangled best_name;
2537
2538 DWARFDebugInfoEntry::Attributes attributes;
2539 die->GetAttributes(this, dwarf_cu, NULL, attributes);
2540 uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
2541 if (idx != UINT32_MAX)
2542 {
2543 DWARFFormValue form_value;
2544 if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
2545 {
2546 const char *name = form_value.AsCString(&get_debug_str_data());
2547 best_name.SetValue (name, true);
2548 }
2549 }
2550 if (best_name)
2551 {
2552 const char *demangled = best_name.GetDemangledName().GetCString();
2553 if (demangled)
2554 {
2555 std::string name_no_parens(partial_name, base_name_end - partial_name);
2556 if (strstr (demangled, name_no_parens.c_str()) == NULL)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002557 return false;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002558 }
2559 }
2560 }
2561
2562 return true;
2563}
Greg Claytonc685f8e2010-09-15 04:15:46 +00002564
Greg Clayton0c5cd902010-06-28 21:30:43 +00002565uint32_t
Greg Clayton2bc22f82011-09-30 03:20:47 +00002566SymbolFileDWARF::FindFunctions (const ConstString &name,
Sean Callanan213fdb82011-10-13 01:49:10 +00002567 const lldb_private::ClangNamespaceDecl *namespace_decl,
Greg Clayton2bc22f82011-09-30 03:20:47 +00002568 uint32_t name_type_mask,
2569 bool append,
2570 SymbolContextList& sc_list)
Greg Clayton0c5cd902010-06-28 21:30:43 +00002571{
2572 Timer scoped_timer (__PRETTY_FUNCTION__,
2573 "SymbolFileDWARF::FindFunctions (name = '%s')",
2574 name.AsCString());
2575
Greg Clayton21f2a492011-10-06 00:09:08 +00002576 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2577
2578 if (log)
2579 {
2580 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2581 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2582 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2583 name.GetCString(), name_type_mask, append);
2584 }
2585
Greg Clayton0c5cd902010-06-28 21:30:43 +00002586 // If we aren't appending the results to this list, then clear the list
2587 if (!append)
2588 sc_list.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00002589
2590 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
2591 return 0;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002592
2593 // If name is empty then we won't find anything.
2594 if (name.IsEmpty())
2595 return 0;
Greg Clayton0c5cd902010-06-28 21:30:43 +00002596
2597 // Remember how many sc_list are in the list before we search in case
2598 // we are appending the results to a variable list.
Greg Clayton9e315582011-09-02 04:03:59 +00002599
Greg Clayton9e315582011-09-02 04:03:59 +00002600 const uint32_t original_size = sc_list.GetSize();
Greg Clayton0c5cd902010-06-28 21:30:43 +00002601
Jim Ingham4cda6e02011-10-07 22:23:45 +00002602 const char *name_cstr = name.GetCString();
2603 uint32_t effective_name_type_mask = eFunctionNameTypeNone;
2604 const char *base_name_start = name_cstr;
2605 const char *base_name_end = name_cstr + strlen(name_cstr);
2606
2607 if (name_type_mask & eFunctionNameTypeAuto)
2608 {
2609 if (CPPLanguageRuntime::IsCPPMangledName (name_cstr))
2610 effective_name_type_mask = eFunctionNameTypeFull;
2611 else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
2612 effective_name_type_mask = eFunctionNameTypeFull;
2613 else
2614 {
2615 if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
2616 effective_name_type_mask |= eFunctionNameTypeSelector;
2617
2618 if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
2619 effective_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
2620 }
2621 }
2622 else
2623 {
2624 effective_name_type_mask = name_type_mask;
2625 if (effective_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
2626 {
2627 // If they've asked for a CPP method or function name and it can't be that, we don't
2628 // even need to search for CPP methods or names.
2629 if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
2630 {
2631 effective_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase);
2632 if (effective_name_type_mask == eFunctionNameTypeNone)
2633 return 0;
2634 }
2635 }
2636
2637 if (effective_name_type_mask & eFunctionNameTypeSelector)
2638 {
2639 if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
2640 {
2641 effective_name_type_mask &= ~(eFunctionNameTypeSelector);
2642 if (effective_name_type_mask == eFunctionNameTypeNone)
2643 return 0;
2644 }
2645 }
2646 }
2647
2648 DWARFDebugInfo* info = DebugInfo();
2649 if (info == NULL)
2650 return 0;
2651
Greg Claytonaa044962011-10-13 00:59:38 +00002652 DWARFCompileUnit *dwarf_cu = NULL;
Greg Clayton97fbc342011-10-20 22:30:33 +00002653 if (m_using_apple_tables)
Greg Clayton4d01ace2011-09-29 16:58:15 +00002654 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002655 if (m_apple_names_ap.get())
Jim Ingham4cda6e02011-10-07 22:23:45 +00002656 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002657
2658 DIEArray die_offsets;
2659
2660 uint32_t num_matches = 0;
2661
2662 if (effective_name_type_mask & eFunctionNameTypeFull)
Greg Claytonaa044962011-10-13 00:59:38 +00002663 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002664 // If they asked for the full name, match what they typed. At some point we may
2665 // want to canonicalize this (strip double spaces, etc. For now, we just add all the
2666 // dies that we find by exact match.
Jim Ingham4cda6e02011-10-07 22:23:45 +00002667 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002668 for (uint32_t i = 0; i < num_matches; i++)
2669 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002670 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
Greg Claytonaa044962011-10-13 00:59:38 +00002671 if (die)
2672 {
Sean Callanan213fdb82011-10-13 01:49:10 +00002673 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2674 continue;
2675
Greg Claytonaa044962011-10-13 00:59:38 +00002676 ResolveFunction (dwarf_cu, die, sc_list);
2677 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002678 }
Greg Clayton97fbc342011-10-20 22:30:33 +00002679 }
2680 else
2681 {
2682 if (effective_name_type_mask & eFunctionNameTypeSelector)
2683 {
2684 if (namespace_decl && *namespace_decl)
2685 return 0; // no selectors in namespaces
2686
2687 num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
2688 // Now make sure these are actually ObjC methods. In this case we can simply look up the name,
2689 // and if it is an ObjC method name, we're good.
2690
2691 for (uint32_t i = 0; i < num_matches; i++)
2692 {
2693 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2694 if (die)
2695 {
2696 const char *die_name = die->GetName(this, dwarf_cu);
2697 if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
2698 ResolveFunction (dwarf_cu, die, sc_list);
2699 }
2700 }
2701 die_offsets.clear();
2702 }
2703
2704 if (effective_name_type_mask & eFunctionNameTypeMethod
2705 || effective_name_type_mask & eFunctionNameTypeBase)
2706 {
2707 if ((effective_name_type_mask & eFunctionNameTypeMethod) &&
2708 (namespace_decl && *namespace_decl))
2709 return 0; // no methods in namespaces
2710
2711 // The apple_names table stores just the "base name" of C++ methods in the table. So we have to
2712 // extract the base name, look that up, and if there is any other information in the name we were
2713 // passed in we have to post-filter based on that.
2714
2715 // FIXME: Arrange the logic above so that we don't calculate the base name twice:
2716 std::string base_name(base_name_start, base_name_end - base_name_start);
2717 num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets);
2718
2719 for (uint32_t i = 0; i < num_matches; i++)
2720 {
2721 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2722 if (die)
2723 {
2724 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2725 continue;
2726
2727 if (!FunctionDieMatchesPartialName(die,
2728 dwarf_cu,
2729 effective_name_type_mask,
2730 name_cstr,
2731 base_name_start,
2732 base_name_end))
2733 continue;
2734
2735 // If we get to here, the die is good, and we should add it:
2736 ResolveFunction (dwarf_cu, die, sc_list);
2737 }
2738 }
2739 die_offsets.clear();
2740 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002741 }
2742 }
Greg Clayton7f995132011-10-04 22:41:51 +00002743 }
2744 else
2745 {
2746
2747 // Index the DWARF if we haven't already
2748 if (!m_indexed)
2749 Index ();
2750
Greg Clayton7f995132011-10-04 22:41:51 +00002751 if (name_type_mask & eFunctionNameTypeFull)
2752 FindFunctions (name, m_function_fullname_index, sc_list);
2753
Jim Ingham4cda6e02011-10-07 22:23:45 +00002754 std::string base_name(base_name_start, base_name_end - base_name_start);
2755 ConstString base_name_const(base_name.c_str());
2756 DIEArray die_offsets;
2757 DWARFCompileUnit *dwarf_cu = NULL;
2758
2759 if (effective_name_type_mask & eFunctionNameTypeBase)
2760 {
2761 uint32_t num_base = m_function_basename_index.Find(base_name_const, die_offsets);
Greg Claytonaa044962011-10-13 00:59:38 +00002762 for (uint32_t i = 0; i < num_base; i++)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002763 {
Greg Claytonaa044962011-10-13 00:59:38 +00002764 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2765 if (die)
2766 {
Sean Callanan213fdb82011-10-13 01:49:10 +00002767 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2768 continue;
2769
Greg Claytonaa044962011-10-13 00:59:38 +00002770 if (!FunctionDieMatchesPartialName(die,
2771 dwarf_cu,
2772 effective_name_type_mask,
2773 name_cstr,
2774 base_name_start,
2775 base_name_end))
2776 continue;
Jim Ingham4cda6e02011-10-07 22:23:45 +00002777
Greg Claytonaa044962011-10-13 00:59:38 +00002778 // If we get to here, the die is good, and we should add it:
2779 ResolveFunction (dwarf_cu, die, sc_list);
2780 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002781 }
2782 die_offsets.clear();
2783 }
2784
Jim Inghamea8005a2011-10-11 01:18:11 +00002785 if (effective_name_type_mask & eFunctionNameTypeMethod)
Jim Ingham4cda6e02011-10-07 22:23:45 +00002786 {
Sean Callanan213fdb82011-10-13 01:49:10 +00002787 if (namespace_decl && *namespace_decl)
2788 return 0; // no methods in namespaces
2789
Jim Ingham4cda6e02011-10-07 22:23:45 +00002790 uint32_t num_base = m_function_method_index.Find(base_name_const, die_offsets);
2791 {
Greg Claytonaa044962011-10-13 00:59:38 +00002792 for (uint32_t i = 0; i < num_base; i++)
2793 {
2794 const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
2795 if (die)
2796 {
2797 if (!FunctionDieMatchesPartialName(die,
2798 dwarf_cu,
2799 effective_name_type_mask,
2800 name_cstr,
2801 base_name_start,
2802 base_name_end))
2803 continue;
2804
2805 // If we get to here, the die is good, and we should add it:
2806 ResolveFunction (dwarf_cu, die, sc_list);
2807 }
2808 }
Jim Ingham4cda6e02011-10-07 22:23:45 +00002809 }
2810 die_offsets.clear();
2811 }
Greg Clayton7f995132011-10-04 22:41:51 +00002812
Sean Callanan213fdb82011-10-13 01:49:10 +00002813 if ((effective_name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
Jim Ingham4cda6e02011-10-07 22:23:45 +00002814 {
Greg Clayton7f995132011-10-04 22:41:51 +00002815 FindFunctions (name, m_function_selector_index, sc_list);
Jim Ingham4cda6e02011-10-07 22:23:45 +00002816 }
2817
Greg Clayton4d01ace2011-09-29 16:58:15 +00002818 }
2819
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002820 // Return the number of variable that were appended to the list
2821 return sc_list.GetSize() - original_size;
2822}
2823
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002824uint32_t
2825SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2826{
2827 Timer scoped_timer (__PRETTY_FUNCTION__,
2828 "SymbolFileDWARF::FindFunctions (regex = '%s')",
2829 regex.GetText());
2830
Greg Clayton21f2a492011-10-06 00:09:08 +00002831 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2832
2833 if (log)
2834 {
2835 log->Printf ("SymbolFileDWARF::FindFunctions (file=\"%s/%s\", regex=\"%s\"append=%u, sc_list)",
2836 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2837 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2838 regex.GetText(), append);
2839 }
2840
2841
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002842 // If we aren't appending the results to this list, then clear the list
2843 if (!append)
2844 sc_list.Clear();
2845
2846 // Remember how many sc_list are in the list before we search in case
2847 // we are appending the results to a variable list.
2848 uint32_t original_size = sc_list.GetSize();
2849
Greg Clayton97fbc342011-10-20 22:30:33 +00002850 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002851 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002852 if (m_apple_names_ap.get())
2853 FindFunctions (regex, *m_apple_names_ap, sc_list);
Greg Clayton7f995132011-10-04 22:41:51 +00002854 }
2855 else
2856 {
Jim Ingham4cda6e02011-10-07 22:23:45 +00002857 // Index the DWARF if we haven't already
Greg Clayton7f995132011-10-04 22:41:51 +00002858 if (!m_indexed)
2859 Index ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002860
Greg Clayton7f995132011-10-04 22:41:51 +00002861 FindFunctions (regex, m_function_basename_index, sc_list);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002862
Greg Clayton7f995132011-10-04 22:41:51 +00002863 FindFunctions (regex, m_function_fullname_index, sc_list);
2864 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002865
2866 // Return the number of variable that were appended to the list
2867 return sc_list.GetSize() - original_size;
2868}
Jim Ingham318c9f22011-08-26 19:44:13 +00002869
Greg Claytond16e1e52011-07-12 17:06:17 +00002870void
2871SymbolFileDWARF::ReportError (const char *format, ...)
2872{
2873 ::fprintf (stderr,
2874 "error: %s/%s ",
2875 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2876 m_obj_file->GetFileSpec().GetFilename().GetCString());
2877
Greg Claytoncfebbcf2011-10-01 01:37:20 +00002878 if (m_obj_file->GetModule()->GetObjectName())
2879 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString());
2880
Greg Claytond16e1e52011-07-12 17:06:17 +00002881 va_list args;
2882 va_start (args, format);
2883 vfprintf (stderr, format, args);
2884 va_end (args);
2885}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002886
Jim Inghamc1663042011-09-29 22:12:35 +00002887void
2888SymbolFileDWARF::ReportWarning (const char *format, ...)
2889{
2890 ::fprintf (stderr,
2891 "warning: %s/%s ",
2892 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2893 m_obj_file->GetFileSpec().GetFilename().GetCString());
2894
Greg Claytoncfebbcf2011-10-01 01:37:20 +00002895 if (m_obj_file->GetModule()->GetObjectName())
2896 ::fprintf (stderr, "(%s) ", m_obj_file->GetModule()->GetObjectName().GetCString());
2897
Jim Inghamc1663042011-09-29 22:12:35 +00002898 va_list args;
2899 va_start (args, format);
2900 vfprintf (stderr, format, args);
2901 va_end (args);
2902}
2903
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002904uint32_t
Sean Callanan213fdb82011-10-13 01:49:10 +00002905SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002906{
Greg Claytonc685f8e2010-09-15 04:15:46 +00002907 DWARFDebugInfo* info = DebugInfo();
2908 if (info == NULL)
2909 return 0;
2910
Greg Clayton21f2a492011-10-06 00:09:08 +00002911 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2912
2913 if (log)
2914 {
Sean Callananc41e68b2011-10-13 21:08:11 +00002915 log->Printf ("SymbolFileDWARF::FindTypes (file=\"%s/%s\", sc, name=\"%s\", append=%u, max_matches=%u, type_list)",
Greg Clayton21f2a492011-10-06 00:09:08 +00002916 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2917 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2918 name.GetCString(), append, max_matches);
2919 }
2920
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002921 // If we aren't appending the results to this list, then clear the list
2922 if (!append)
2923 types.Clear();
Sean Callanan213fdb82011-10-13 01:49:10 +00002924
2925 if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
2926 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002927
Greg Claytond4a2b372011-09-12 23:21:58 +00002928 DIEArray die_offsets;
Greg Clayton7f995132011-10-04 22:41:51 +00002929
Greg Clayton97fbc342011-10-20 22:30:33 +00002930 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00002931 {
Greg Clayton97fbc342011-10-20 22:30:33 +00002932 if (m_apple_types_ap.get())
2933 {
2934 const char *name_cstr = name.GetCString();
2935 m_apple_types_ap->FindByName (name_cstr, die_offsets);
2936 }
Greg Clayton7f995132011-10-04 22:41:51 +00002937 }
2938 else
2939 {
2940 if (!m_indexed)
2941 Index ();
2942
2943 m_type_index.Find (name, die_offsets);
2944 }
2945
2946
2947 const size_t num_matches = die_offsets.size();
2948
Greg Claytond4a2b372011-09-12 23:21:58 +00002949 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002950 {
Greg Clayton7f995132011-10-04 22:41:51 +00002951 const uint32_t initial_types_size = types.GetSize();
2952 DWARFCompileUnit* dwarf_cu = NULL;
2953 const DWARFDebugInfoEntry* die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00002954 DWARFDebugInfo* debug_info = DebugInfo();
2955 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002956 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002957 const dw_offset_t die_offset = die_offsets[i];
2958 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2959
Sean Callanan213fdb82011-10-13 01:49:10 +00002960 if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2961 continue;
2962
Greg Claytond4a2b372011-09-12 23:21:58 +00002963 Type *matching_type = ResolveType (dwarf_cu, die);
2964 if (matching_type)
Greg Clayton73bf5db2011-06-17 01:22:15 +00002965 {
Greg Claytond4a2b372011-09-12 23:21:58 +00002966 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton85ae2e12011-10-18 23:36:41 +00002967 types.InsertUnique (TypeSP (matching_type));
2968 if (types.GetSize() >= max_matches)
2969 break;
Greg Clayton73bf5db2011-06-17 01:22:15 +00002970 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002971 }
Greg Clayton7f995132011-10-04 22:41:51 +00002972 return types.GetSize() - initial_types_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002973 }
Greg Clayton7f995132011-10-04 22:41:51 +00002974 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002975}
2976
2977
Greg Clayton526e5af2010-11-13 03:52:47 +00002978ClangNamespaceDecl
Greg Clayton96d7d742010-11-10 23:42:09 +00002979SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
Sean Callanan213fdb82011-10-13 01:49:10 +00002980 const ConstString &name,
2981 const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00002982{
Greg Clayton21f2a492011-10-06 00:09:08 +00002983 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2984
2985 if (log)
2986 {
2987 log->Printf ("SymbolFileDWARF::FindNamespace (file=\"%s/%s\", sc, name=\"%s\")",
2988 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2989 m_obj_file->GetFileSpec().GetFilename().GetCString(),
2990 name.GetCString());
2991 }
Sean Callanan213fdb82011-10-13 01:49:10 +00002992
2993 if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl))
2994 return ClangNamespaceDecl();
Greg Clayton21f2a492011-10-06 00:09:08 +00002995
Greg Clayton526e5af2010-11-13 03:52:47 +00002996 ClangNamespaceDecl namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00002997 DWARFDebugInfo* info = DebugInfo();
Greg Clayton526e5af2010-11-13 03:52:47 +00002998 if (info)
Greg Clayton96d7d742010-11-10 23:42:09 +00002999 {
Greg Clayton7f995132011-10-04 22:41:51 +00003000 DIEArray die_offsets;
3001
Greg Clayton526e5af2010-11-13 03:52:47 +00003002 // Index if we already haven't to make sure the compile units
3003 // get indexed and make their global DIE index list
Greg Clayton97fbc342011-10-20 22:30:33 +00003004 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003005 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003006 if (m_apple_namespaces_ap.get())
3007 {
3008 const char *name_cstr = name.GetCString();
3009 m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
3010 }
Greg Clayton7f995132011-10-04 22:41:51 +00003011 }
3012 else
3013 {
3014 if (!m_indexed)
3015 Index ();
Greg Clayton96d7d742010-11-10 23:42:09 +00003016
Greg Clayton7f995132011-10-04 22:41:51 +00003017 m_namespace_index.Find (name, die_offsets);
3018 }
Greg Claytond4a2b372011-09-12 23:21:58 +00003019
3020 DWARFCompileUnit* dwarf_cu = NULL;
Greg Clayton526e5af2010-11-13 03:52:47 +00003021 const DWARFDebugInfoEntry* die = NULL;
Greg Clayton7f995132011-10-04 22:41:51 +00003022 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00003023 if (num_matches)
Greg Clayton526e5af2010-11-13 03:52:47 +00003024 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003025 DWARFDebugInfo* debug_info = DebugInfo();
3026 for (size_t i=0; i<num_matches; ++i)
Greg Clayton526e5af2010-11-13 03:52:47 +00003027 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003028 const dw_offset_t die_offset = die_offsets[i];
3029 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Sean Callanan213fdb82011-10-13 01:49:10 +00003030
3031 if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die))
3032 continue;
Greg Claytond4a2b372011-09-12 23:21:58 +00003033
3034 clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
3035 if (clang_namespace_decl)
3036 {
3037 namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
3038 namespace_decl.SetNamespaceDecl (clang_namespace_decl);
3039 }
Greg Clayton526e5af2010-11-13 03:52:47 +00003040 }
3041 }
Greg Clayton96d7d742010-11-10 23:42:09 +00003042 }
Greg Clayton526e5af2010-11-13 03:52:47 +00003043 return namespace_decl;
Greg Clayton96d7d742010-11-10 23:42:09 +00003044}
3045
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003046uint32_t
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003047SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003048{
3049 // Remember how many sc_list are in the list before we search in case
3050 // we are appending the results to a variable list.
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003051 uint32_t original_size = types.GetSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003052
3053 const uint32_t num_die_offsets = die_offsets.size();
3054 // Parse all of the types we found from the pubtypes matches
3055 uint32_t i;
3056 uint32_t num_matches = 0;
3057 for (i = 0; i < num_die_offsets; ++i)
3058 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003059 Type *matching_type = ResolveTypeUID (die_offsets[i]);
3060 if (matching_type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003061 {
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003062 // We found a type pointer, now find the shared pointer form our type list
Greg Clayton85ae2e12011-10-18 23:36:41 +00003063 types.InsertUnique (TypeSP (matching_type));
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003064 ++num_matches;
3065 if (num_matches >= max_matches)
3066 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003067 }
3068 }
3069
3070 // Return the number of variable that were appended to the list
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003071 return types.GetSize() - original_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003072}
3073
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003074
3075size_t
Greg Clayton5113dc82011-08-12 06:47:54 +00003076SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
3077 clang::DeclContext *containing_decl_ctx,
3078 TypeSP& type_sp,
3079 DWARFCompileUnit* dwarf_cu,
3080 const DWARFDebugInfoEntry *parent_die,
3081 bool skip_artificial,
3082 bool &is_static,
3083 TypeList* type_list,
3084 std::vector<clang_type_t>& function_param_types,
3085 std::vector<clang::ParmVarDecl*>& function_param_decls,
3086 unsigned &type_quals)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003087{
3088 if (parent_die == NULL)
3089 return 0;
3090
Greg Claytond88d7592010-09-15 08:33:30 +00003091 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
3092
Greg Clayton7fedea22010-11-16 02:10:54 +00003093 size_t arg_idx = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003094 const DWARFDebugInfoEntry *die;
3095 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3096 {
3097 dw_tag_t tag = die->Tag();
3098 switch (tag)
3099 {
3100 case DW_TAG_formal_parameter:
3101 {
3102 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003103 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003104 if (num_attributes > 0)
3105 {
3106 const char *name = NULL;
3107 Declaration decl;
3108 dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003109 bool is_artificial = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003110 // one of None, Auto, Register, Extern, Static, PrivateExtern
3111
Sean Callanane2ef6e32010-09-23 03:01:22 +00003112 clang::StorageClass storage = clang::SC_None;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003113 uint32_t i;
3114 for (i=0; i<num_attributes; ++i)
3115 {
3116 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3117 DWARFFormValue form_value;
3118 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3119 {
3120 switch (attr)
3121 {
3122 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3123 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3124 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3125 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
3126 case DW_AT_type: param_type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Claytona51ed9b2010-09-23 01:09:21 +00003127 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003128 case DW_AT_location:
3129 // if (form_value.BlockData())
3130 // {
3131 // const DataExtractor& debug_info_data = debug_info();
3132 // uint32_t block_length = form_value.Unsigned();
3133 // DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
3134 // }
3135 // else
3136 // {
3137 // }
3138 // break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003139 case DW_AT_const_value:
3140 case DW_AT_default_value:
3141 case DW_AT_description:
3142 case DW_AT_endianity:
3143 case DW_AT_is_optional:
3144 case DW_AT_segment:
3145 case DW_AT_variable_parameter:
3146 default:
3147 case DW_AT_abstract_origin:
3148 case DW_AT_sibling:
3149 break;
3150 }
3151 }
3152 }
Greg Claytona51ed9b2010-09-23 01:09:21 +00003153
Greg Clayton0fffff52010-09-24 05:15:53 +00003154 bool skip = false;
3155 if (skip_artificial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003156 {
Greg Clayton0fffff52010-09-24 05:15:53 +00003157 if (is_artificial)
Greg Clayton7fedea22010-11-16 02:10:54 +00003158 {
3159 // In order to determine if a C++ member function is
3160 // "const" we have to look at the const-ness of "this"...
3161 // Ugly, but that
3162 if (arg_idx == 0)
3163 {
Greg Claytonf0705c82011-10-22 03:33:13 +00003164 if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
Sean Callanan763d72a2011-08-02 22:21:50 +00003165 {
Greg Clayton5113dc82011-08-12 06:47:54 +00003166 // Often times compilers omit the "this" name for the
3167 // specification DIEs, so we can't rely upon the name
3168 // being in the formal parameter DIE...
3169 if (name == NULL || ::strcmp(name, "this")==0)
Greg Clayton7fedea22010-11-16 02:10:54 +00003170 {
Greg Clayton5113dc82011-08-12 06:47:54 +00003171 Type *this_type = ResolveTypeUID (param_type_die_offset);
3172 if (this_type)
3173 {
3174 uint32_t encoding_mask = this_type->GetEncodingMask();
3175 if (encoding_mask & Type::eEncodingIsPointerUID)
3176 {
3177 is_static = false;
3178
3179 if (encoding_mask & (1u << Type::eEncodingIsConstUID))
3180 type_quals |= clang::Qualifiers::Const;
3181 if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
3182 type_quals |= clang::Qualifiers::Volatile;
Greg Clayton7fedea22010-11-16 02:10:54 +00003183 }
3184 }
3185 }
3186 }
3187 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003188 skip = true;
Greg Clayton7fedea22010-11-16 02:10:54 +00003189 }
Greg Clayton0fffff52010-09-24 05:15:53 +00003190 else
3191 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003192
Greg Clayton0fffff52010-09-24 05:15:53 +00003193 // HACK: Objective C formal parameters "self" and "_cmd"
3194 // are not marked as artificial in the DWARF...
Greg Clayton96d7d742010-11-10 23:42:09 +00003195 CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
3196 if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
Greg Clayton0fffff52010-09-24 05:15:53 +00003197 {
3198 if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
3199 skip = true;
3200 }
3201 }
3202 }
3203
3204 if (!skip)
3205 {
3206 Type *type = ResolveTypeUID(param_type_die_offset);
3207 if (type)
3208 {
Greg Claytonc93237c2010-10-01 20:48:32 +00003209 function_param_types.push_back (type->GetClangForwardType());
Greg Clayton0fffff52010-09-24 05:15:53 +00003210
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003211 clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
Greg Clayton0fffff52010-09-24 05:15:53 +00003212 assert(param_var_decl);
3213 function_param_decls.push_back(param_var_decl);
3214 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003215 }
3216 }
Greg Clayton7fedea22010-11-16 02:10:54 +00003217 arg_idx++;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003218 }
3219 break;
3220
3221 default:
3222 break;
3223 }
3224 }
Greg Clayton7fedea22010-11-16 02:10:54 +00003225 return arg_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003226}
3227
3228size_t
3229SymbolFileDWARF::ParseChildEnumerators
3230(
3231 const SymbolContext& sc,
Greg Clayton1be10fc2010-09-29 01:12:09 +00003232 clang_type_t enumerator_clang_type,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003233 uint32_t enumerator_byte_size,
Greg Clayton0fffff52010-09-24 05:15:53 +00003234 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003235 const DWARFDebugInfoEntry *parent_die
3236)
3237{
3238 if (parent_die == NULL)
3239 return 0;
3240
3241 size_t enumerators_added = 0;
3242 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00003243 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
3244
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003245 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3246 {
3247 const dw_tag_t tag = die->Tag();
3248 if (tag == DW_TAG_enumerator)
3249 {
3250 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003251 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003252 if (num_child_attributes > 0)
3253 {
3254 const char *name = NULL;
3255 bool got_value = false;
3256 int64_t enum_value = 0;
3257 Declaration decl;
3258
3259 uint32_t i;
3260 for (i=0; i<num_child_attributes; ++i)
3261 {
3262 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3263 DWARFFormValue form_value;
3264 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3265 {
3266 switch (attr)
3267 {
3268 case DW_AT_const_value:
3269 got_value = true;
3270 enum_value = form_value.Unsigned();
3271 break;
3272
3273 case DW_AT_name:
3274 name = form_value.AsCString(&get_debug_str_data());
3275 break;
3276
3277 case DW_AT_description:
3278 default:
3279 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3280 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3281 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3282 case DW_AT_sibling:
3283 break;
3284 }
3285 }
3286 }
3287
3288 if (name && name[0] && got_value)
3289 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003290 GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
3291 enumerator_clang_type,
3292 decl,
3293 name,
3294 enum_value,
3295 enumerator_byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003296 ++enumerators_added;
3297 }
3298 }
3299 }
3300 }
3301 return enumerators_added;
3302}
3303
3304void
3305SymbolFileDWARF::ParseChildArrayInfo
3306(
3307 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00003308 DWARFCompileUnit* dwarf_cu,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003309 const DWARFDebugInfoEntry *parent_die,
3310 int64_t& first_index,
3311 std::vector<uint64_t>& element_orders,
3312 uint32_t& byte_stride,
3313 uint32_t& bit_stride
3314)
3315{
3316 if (parent_die == NULL)
3317 return;
3318
3319 const DWARFDebugInfoEntry *die;
Greg Claytond88d7592010-09-15 08:33:30 +00003320 const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003321 for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3322 {
3323 const dw_tag_t tag = die->Tag();
3324 switch (tag)
3325 {
3326 case DW_TAG_enumerator:
3327 {
3328 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003329 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003330 if (num_child_attributes > 0)
3331 {
3332 const char *name = NULL;
3333 bool got_value = false;
3334 int64_t enum_value = 0;
3335
3336 uint32_t i;
3337 for (i=0; i<num_child_attributes; ++i)
3338 {
3339 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3340 DWARFFormValue form_value;
3341 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3342 {
3343 switch (attr)
3344 {
3345 case DW_AT_const_value:
3346 got_value = true;
3347 enum_value = form_value.Unsigned();
3348 break;
3349
3350 case DW_AT_name:
3351 name = form_value.AsCString(&get_debug_str_data());
3352 break;
3353
3354 case DW_AT_description:
3355 default:
3356 case DW_AT_decl_file:
3357 case DW_AT_decl_line:
3358 case DW_AT_decl_column:
3359 case DW_AT_sibling:
3360 break;
3361 }
3362 }
3363 }
3364 }
3365 }
3366 break;
3367
3368 case DW_TAG_subrange_type:
3369 {
3370 DWARFDebugInfoEntry::Attributes attributes;
Greg Claytond88d7592010-09-15 08:33:30 +00003371 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003372 if (num_child_attributes > 0)
3373 {
3374 const char *name = NULL;
3375 bool got_value = false;
3376 uint64_t byte_size = 0;
3377 int64_t enum_value = 0;
3378 uint64_t num_elements = 0;
3379 uint64_t lower_bound = 0;
3380 uint64_t upper_bound = 0;
3381 uint32_t i;
3382 for (i=0; i<num_child_attributes; ++i)
3383 {
3384 const dw_attr_t attr = attributes.AttributeAtIndex(i);
3385 DWARFFormValue form_value;
3386 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3387 {
3388 switch (attr)
3389 {
3390 case DW_AT_const_value:
3391 got_value = true;
3392 enum_value = form_value.Unsigned();
3393 break;
3394
3395 case DW_AT_name:
3396 name = form_value.AsCString(&get_debug_str_data());
3397 break;
3398
3399 case DW_AT_count:
3400 num_elements = form_value.Unsigned();
3401 break;
3402
3403 case DW_AT_bit_stride:
3404 bit_stride = form_value.Unsigned();
3405 break;
3406
3407 case DW_AT_byte_stride:
3408 byte_stride = form_value.Unsigned();
3409 break;
3410
3411 case DW_AT_byte_size:
3412 byte_size = form_value.Unsigned();
3413 break;
3414
3415 case DW_AT_lower_bound:
3416 lower_bound = form_value.Unsigned();
3417 break;
3418
3419 case DW_AT_upper_bound:
3420 upper_bound = form_value.Unsigned();
3421 break;
3422
3423 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003424 case DW_AT_abstract_origin:
3425 case DW_AT_accessibility:
3426 case DW_AT_allocated:
3427 case DW_AT_associated:
3428 case DW_AT_data_location:
3429 case DW_AT_declaration:
3430 case DW_AT_description:
3431 case DW_AT_sibling:
3432 case DW_AT_threads_scaled:
3433 case DW_AT_type:
3434 case DW_AT_visibility:
3435 break;
3436 }
3437 }
3438 }
3439
3440 if (upper_bound > lower_bound)
3441 num_elements = upper_bound - lower_bound + 1;
3442
3443 if (num_elements > 0)
3444 element_orders.push_back (num_elements);
3445 }
3446 }
3447 break;
3448 }
3449 }
3450}
3451
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003452TypeSP
Greg Clayton96d7d742010-11-10 23:42:09 +00003453SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003454{
3455 TypeSP type_sp;
3456 if (die != NULL)
3457 {
Greg Clayton96d7d742010-11-10 23:42:09 +00003458 assert(curr_cu != NULL);
Greg Clayton594e5ed2010-09-27 21:07:38 +00003459 Type *type_ptr = m_die_to_type.lookup (die);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003460 if (type_ptr == NULL)
3461 {
Greg Claytonca512b32011-01-14 04:54:56 +00003462 CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
3463 assert (lldb_cu);
3464 SymbolContext sc(lldb_cu);
Greg Clayton96d7d742010-11-10 23:42:09 +00003465 type_sp = ParseType(sc, curr_cu, die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003466 }
3467 else if (type_ptr != DIE_IS_BEING_PARSED)
3468 {
3469 // Grab the existing type from the master types lists
Greg Clayton85ae2e12011-10-18 23:36:41 +00003470 type_sp = type_ptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003471 }
3472
3473 }
3474 return type_sp;
3475}
3476
3477clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00003478SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003479{
3480 if (die_offset != DW_INVALID_OFFSET)
3481 {
3482 DWARFCompileUnitSP cu_sp;
3483 const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
Greg Claytoncb5860a2011-10-13 23:49:28 +00003484 return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003485 }
3486 return NULL;
3487}
3488
Sean Callanan72e49402011-08-05 23:43:37 +00003489clang::DeclContext *
3490SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
3491{
3492 if (die_offset != DW_INVALID_OFFSET)
3493 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00003494 DWARFDebugInfo* debug_info = DebugInfo();
3495 if (debug_info)
3496 {
3497 DWARFCompileUnitSP cu_sp;
3498 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
3499 if (die)
3500 return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
3501 }
Sean Callanan72e49402011-08-05 23:43:37 +00003502 }
3503 return NULL;
3504}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003505
Greg Clayton96d7d742010-11-10 23:42:09 +00003506clang::NamespaceDecl *
3507SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3508{
Greg Clayton030a2042011-10-14 21:34:45 +00003509 if (die && die->Tag() == DW_TAG_namespace)
Greg Clayton96d7d742010-11-10 23:42:09 +00003510 {
Greg Clayton030a2042011-10-14 21:34:45 +00003511 // See if we already parsed this namespace DIE and associated it with a
3512 // uniqued namespace declaration
3513 clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
3514 if (namespace_decl)
Greg Clayton96d7d742010-11-10 23:42:09 +00003515 return namespace_decl;
Greg Clayton030a2042011-10-14 21:34:45 +00003516 else
3517 {
3518 const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
3519 if (namespace_name)
3520 {
3521 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (curr_cu, die, NULL);
3522 namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
3523 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
3524 if (log)
3525 {
3526 const char *object_name = m_obj_file->GetModule()->GetObjectName().GetCString();
Greg Clayton81c22f62011-10-19 18:09:39 +00003527 log->Printf ("ASTContext => %p: 0x%8.8llx: DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl * %p in %s/%s%s%s%s (original = %p)",
Greg Clayton030a2042011-10-14 21:34:45 +00003528 GetClangASTContext().getASTContext(),
Greg Clayton81c22f62011-10-19 18:09:39 +00003529 MakeUserID(die->GetOffset()),
Greg Clayton030a2042011-10-14 21:34:45 +00003530 namespace_name,
3531 namespace_decl,
3532 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
3533 m_obj_file->GetFileSpec().GetFilename().GetCString(),
3534 object_name ? "(" : "",
3535 object_name ? object_name : "",
3536 object_name ? "(" : "",
3537 namespace_decl->getOriginalNamespace());
3538 }
3539
3540 if (namespace_decl)
3541 LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
3542 return namespace_decl;
3543 }
Greg Clayton96d7d742010-11-10 23:42:09 +00003544 }
3545 }
3546 return NULL;
3547}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003548
3549clang::DeclContext *
Sean Callanan72e49402011-08-05 23:43:37 +00003550SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3551{
Greg Clayton5cf58b92011-10-05 22:22:08 +00003552 clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3553 if (clang_decl_ctx)
3554 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00003555 // If this DIE has a specification, or an abstract origin, then trace to those.
3556
3557 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
3558 if (die_offset != DW_INVALID_OFFSET)
3559 return GetClangDeclContextForDIEOffset (sc, die_offset);
3560
3561 die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3562 if (die_offset != DW_INVALID_OFFSET)
3563 return GetClangDeclContextForDIEOffset (sc, die_offset);
3564
3565 // This is the DIE we want. Parse it, then query our map.
3566
3567 ParseType(sc, curr_cu, die, NULL);
3568
Greg Clayton5cf58b92011-10-05 22:22:08 +00003569 clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3570
3571 return clang_decl_ctx;
Sean Callanan72e49402011-08-05 23:43:37 +00003572}
3573
3574clang::DeclContext *
Greg Claytoncb5860a2011-10-13 23:49:28 +00003575SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003576{
Greg Claytonca512b32011-01-14 04:54:56 +00003577 if (m_clang_tu_decl == NULL)
3578 m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003579
Greg Clayton2bc22f82011-09-30 03:20:47 +00003580 const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
Greg Claytoncb5860a2011-10-13 23:49:28 +00003581
3582 if (decl_ctx_die_copy)
3583 *decl_ctx_die_copy = decl_ctx_die;
Greg Clayton2bc22f82011-09-30 03:20:47 +00003584
3585 if (decl_ctx_die)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003586 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00003587
Greg Clayton2bc22f82011-09-30 03:20:47 +00003588 DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
3589 if (pos != m_die_to_decl_ctx.end())
3590 return pos->second;
3591
3592 switch (decl_ctx_die->Tag())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003593 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003594 case DW_TAG_compile_unit:
3595 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003596
Greg Clayton2bc22f82011-09-30 03:20:47 +00003597 case DW_TAG_namespace:
Greg Clayton030a2042011-10-14 21:34:45 +00003598 return ResolveNamespaceDIE (cu, decl_ctx_die);
Greg Clayton2bc22f82011-09-30 03:20:47 +00003599 break;
3600
3601 case DW_TAG_structure_type:
3602 case DW_TAG_union_type:
3603 case DW_TAG_class_type:
3604 {
3605 Type* type = ResolveType (cu, decl_ctx_die);
3606 if (type)
3607 {
3608 clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
3609 if (decl_ctx)
Greg Claytonca512b32011-01-14 04:54:56 +00003610 {
Greg Clayton2bc22f82011-09-30 03:20:47 +00003611 LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
3612 if (decl_ctx)
3613 return decl_ctx;
Greg Claytonca512b32011-01-14 04:54:56 +00003614 }
3615 }
Greg Claytonca512b32011-01-14 04:54:56 +00003616 }
Greg Clayton2bc22f82011-09-30 03:20:47 +00003617 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003618
Greg Clayton2bc22f82011-09-30 03:20:47 +00003619 default:
3620 break;
Greg Claytonca512b32011-01-14 04:54:56 +00003621 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003622 }
Greg Clayton7a345282010-11-09 23:46:37 +00003623 return m_clang_tu_decl;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003624}
3625
Greg Clayton2bc22f82011-09-30 03:20:47 +00003626
3627const DWARFDebugInfoEntry *
3628SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
3629{
3630 if (cu && die)
3631 {
3632 const DWARFDebugInfoEntry * const decl_die = die;
3633
3634 while (die != NULL)
3635 {
3636 // If this is the original DIE that we are searching for a declaration
3637 // for, then don't look in the cache as we don't want our own decl
3638 // context to be our decl context...
3639 if (decl_die != die)
3640 {
3641 switch (die->Tag())
3642 {
3643 case DW_TAG_compile_unit:
3644 case DW_TAG_namespace:
3645 case DW_TAG_structure_type:
3646 case DW_TAG_union_type:
3647 case DW_TAG_class_type:
3648 return die;
3649
3650 default:
3651 break;
3652 }
3653 }
3654
3655 dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
3656 if (die_offset != DW_INVALID_OFFSET)
3657 {
3658 DWARFCompileUnit *spec_cu = cu;
3659 const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
3660 const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
3661 if (spec_die_decl_ctx_die)
3662 return spec_die_decl_ctx_die;
3663 }
3664
3665 die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3666 if (die_offset != DW_INVALID_OFFSET)
3667 {
3668 DWARFCompileUnit *abs_cu = cu;
3669 const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
3670 const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
3671 if (abs_die_decl_ctx_die)
3672 return abs_die_decl_ctx_die;
3673 }
3674
3675 die = die->GetParent();
3676 }
3677 }
3678 return NULL;
3679}
3680
3681
3682
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003683// This function can be used when a DIE is found that is a forward declaration
3684// DIE and we want to try and find a type that has the complete definition.
3685TypeSP
Greg Clayton7f995132011-10-04 22:41:51 +00003686SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
3687 const DWARFDebugInfoEntry *die,
3688 const ConstString &type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003689{
3690 TypeSP type_sp;
3691
Greg Clayton1a65ae12011-01-25 23:55:37 +00003692 if (cu == NULL || die == NULL || !type_name)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003693 return type_sp;
3694
Greg Clayton7f995132011-10-04 22:41:51 +00003695 DIEArray die_offsets;
3696
Greg Clayton97fbc342011-10-20 22:30:33 +00003697 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00003698 {
Greg Clayton97fbc342011-10-20 22:30:33 +00003699 if (m_apple_types_ap.get())
3700 {
3701 const char *name_cstr = type_name.GetCString();
3702 m_apple_types_ap->FindByName (name_cstr, die_offsets);
3703 }
Greg Clayton7f995132011-10-04 22:41:51 +00003704 }
3705 else
3706 {
3707 if (!m_indexed)
3708 Index ();
3709
3710 m_type_index.Find (type_name, die_offsets);
3711 }
3712
3713
3714 const size_t num_matches = die_offsets.size();
Greg Clayton69974892010-12-03 21:42:06 +00003715
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003716 const dw_tag_t type_tag = die->Tag();
Greg Claytond4a2b372011-09-12 23:21:58 +00003717
3718 DWARFCompileUnit* type_cu = NULL;
3719 const DWARFDebugInfoEntry* type_die = NULL;
Greg Claytond4a2b372011-09-12 23:21:58 +00003720 if (num_matches)
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003721 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003722 DWARFDebugInfo* debug_info = DebugInfo();
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003723 for (size_t i=0; i<num_matches; ++i)
3724 {
Greg Claytond4a2b372011-09-12 23:21:58 +00003725 const dw_offset_t die_offset = die_offsets[i];
3726 type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003727
3728 if (type_die != die && type_die->Tag() == type_tag)
3729 {
3730 // Hold off on comparing parent DIE tags until
3731 // we know what happens with stuff in namespaces
3732 // for gcc and clang...
3733 //DWARFDebugInfoEntry *parent_die = die->GetParent();
3734 //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
3735 //if (parent_die->Tag() == parent_type_die->Tag())
3736 {
3737 Type *resolved_type = ResolveType (type_cu, type_die, false);
3738 if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
3739 {
Greg Clayton81c22f62011-10-19 18:09:39 +00003740 DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
3741 MakeUserID(die->GetOffset()),
3742 MakeUserID(curr_cu->GetOffset()),
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003743 m_obj_file->GetFileSpec().GetFilename().AsCString(),
Greg Clayton81c22f62011-10-19 18:09:39 +00003744 MakeUserID(type_die->GetOffset()),
3745 MakeUserID(type_cu->GetOffset()));
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003746
3747 m_die_to_type[die] = resolved_type;
Greg Clayton85ae2e12011-10-18 23:36:41 +00003748 type_sp = resolved_type;
Greg Clayton2ccf8cf2010-11-07 21:02:03 +00003749 break;
3750 }
3751 }
3752 }
3753 }
3754 }
3755 return type_sp;
3756}
3757
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003758TypeSP
Greg Clayton1be10fc2010-09-29 01:12:09 +00003759SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003760{
3761 TypeSP type_sp;
3762
Greg Clayton1be10fc2010-09-29 01:12:09 +00003763 if (type_is_new_ptr)
3764 *type_is_new_ptr = false;
3765
Sean Callananc7fbf732010-08-06 00:32:49 +00003766 AccessType accessibility = eAccessNone;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003767 if (die != NULL)
3768 {
Greg Clayton21f2a492011-10-06 00:09:08 +00003769 LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
Jim Ingham16746d12011-08-25 23:21:43 +00003770 if (log && dwarf_cu)
3771 {
Jim Ingham318c9f22011-08-26 19:44:13 +00003772 StreamString s;
Jim Inghamd3d25d92011-08-27 01:24:54 +00003773 die->DumpLocation (this, dwarf_cu, s);
Jim Ingham318c9f22011-08-26 19:44:13 +00003774 log->Printf ("SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
3775
Jim Ingham16746d12011-08-25 23:21:43 +00003776 }
3777
Greg Clayton594e5ed2010-09-27 21:07:38 +00003778 Type *type_ptr = m_die_to_type.lookup (die);
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003779 TypeList* type_list = GetTypeList();
Greg Clayton594e5ed2010-09-27 21:07:38 +00003780 if (type_ptr == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003781 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003782 ClangASTContext &ast = GetClangASTContext();
Greg Clayton1be10fc2010-09-29 01:12:09 +00003783 if (type_is_new_ptr)
3784 *type_is_new_ptr = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003785
Greg Clayton594e5ed2010-09-27 21:07:38 +00003786 const dw_tag_t tag = die->Tag();
3787
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003788 bool is_forward_declaration = false;
3789 DWARFDebugInfoEntry::Attributes attributes;
3790 const char *type_name_cstr = NULL;
Greg Clayton24739922010-10-13 03:15:28 +00003791 ConstString type_name_const_str;
Greg Clayton526e5af2010-11-13 03:52:47 +00003792 Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3793 size_t byte_size = 0;
Greg Clayton36909642011-03-15 04:38:20 +00003794 bool byte_size_valid = false;
Greg Clayton526e5af2010-11-13 03:52:47 +00003795 Declaration decl;
3796
Greg Clayton4957bf62010-09-30 21:49:03 +00003797 Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
Greg Clayton1be10fc2010-09-29 01:12:09 +00003798 clang_type_t clang_type = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003799
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003800 dw_attr_t attr;
3801
3802 switch (tag)
3803 {
3804 case DW_TAG_base_type:
3805 case DW_TAG_pointer_type:
3806 case DW_TAG_reference_type:
3807 case DW_TAG_typedef:
3808 case DW_TAG_const_type:
3809 case DW_TAG_restrict_type:
3810 case DW_TAG_volatile_type:
3811 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003812 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003813 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003814
Greg Claytond88d7592010-09-15 08:33:30 +00003815 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003816 uint32_t encoding = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003817 lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3818
3819 if (num_attributes > 0)
3820 {
3821 uint32_t i;
3822 for (i=0; i<num_attributes; ++i)
3823 {
3824 attr = attributes.AttributeAtIndex(i);
3825 DWARFFormValue form_value;
3826 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3827 {
3828 switch (attr)
3829 {
3830 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3831 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
3832 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3833 case DW_AT_name:
Jim Ingham337030f2011-04-15 23:41:23 +00003834
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003835 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Jim Ingham337030f2011-04-15 23:41:23 +00003836 // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3837 // include the "&"...
3838 if (tag == DW_TAG_reference_type)
3839 {
3840 if (strchr (type_name_cstr, '&') == NULL)
3841 type_name_cstr = NULL;
3842 }
3843 if (type_name_cstr)
3844 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003845 break;
Greg Clayton36909642011-03-15 04:38:20 +00003846 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003847 case DW_AT_encoding: encoding = form_value.Unsigned(); break;
3848 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
3849 default:
3850 case DW_AT_sibling:
3851 break;
3852 }
3853 }
3854 }
3855 }
3856
Greg Clayton81c22f62011-10-19 18:09:39 +00003857 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
Greg Claytonc93237c2010-10-01 20:48:32 +00003858
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003859 switch (tag)
3860 {
3861 default:
Greg Clayton526e5af2010-11-13 03:52:47 +00003862 break;
3863
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003864 case DW_TAG_base_type:
Greg Clayton526e5af2010-11-13 03:52:47 +00003865 resolve_state = Type::eResolveStateFull;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003866 clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3867 encoding,
3868 byte_size * 8);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003869 break;
3870
Greg Clayton526e5af2010-11-13 03:52:47 +00003871 case DW_TAG_pointer_type: encoding_data_type = Type::eEncodingIsPointerUID; break;
3872 case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID; break;
3873 case DW_TAG_typedef: encoding_data_type = Type::eEncodingIsTypedefUID; break;
3874 case DW_TAG_const_type: encoding_data_type = Type::eEncodingIsConstUID; break;
3875 case DW_TAG_restrict_type: encoding_data_type = Type::eEncodingIsRestrictUID; break;
3876 case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003877 }
3878
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003879 if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3880 (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3881 {
3882 static ConstString g_objc_type_name_id("id");
3883 static ConstString g_objc_type_name_Class("Class");
3884 static ConstString g_objc_type_name_selector("SEL");
3885
Greg Clayton24739922010-10-13 03:15:28 +00003886 if (type_name_const_str == g_objc_type_name_id)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003887 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003888 clang_type = ast.GetBuiltInType_objc_id();
Greg Clayton526e5af2010-11-13 03:52:47 +00003889 resolve_state = Type::eResolveStateFull;
3890
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003891 }
Greg Clayton24739922010-10-13 03:15:28 +00003892 else if (type_name_const_str == g_objc_type_name_Class)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003893 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003894 clang_type = ast.GetBuiltInType_objc_Class();
Greg Clayton526e5af2010-11-13 03:52:47 +00003895 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003896 }
Greg Clayton24739922010-10-13 03:15:28 +00003897 else if (type_name_const_str == g_objc_type_name_selector)
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003898 {
Sean Callananf6c73082010-12-06 23:53:20 +00003899 clang_type = ast.GetBuiltInType_objc_selector();
Greg Clayton526e5af2010-11-13 03:52:47 +00003900 resolve_state = Type::eResolveStateFull;
Greg Claytonb0b9fe62010-08-03 00:35:52 +00003901 }
3902 }
3903
Greg Clayton81c22f62011-10-19 18:09:39 +00003904 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003905 this,
3906 type_name_const_str,
3907 byte_size,
3908 NULL,
3909 encoding_uid,
3910 encoding_data_type,
3911 &decl,
3912 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00003913 resolve_state));
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00003914
Greg Clayton594e5ed2010-09-27 21:07:38 +00003915 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003916
3917// Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3918// if (encoding_type != NULL)
3919// {
3920// if (encoding_type != DIE_IS_BEING_PARSED)
3921// type_sp->SetEncodingType(encoding_type);
3922// else
3923// m_indirect_fixups.push_back(type_sp.get());
3924// }
3925 }
3926 break;
3927
3928 case DW_TAG_structure_type:
3929 case DW_TAG_union_type:
3930 case DW_TAG_class_type:
3931 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003932 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00003933 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003934
Greg Clayton9e409562010-07-28 02:04:09 +00003935 LanguageType class_language = eLanguageTypeUnknown;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003936 //bool struct_is_class = false;
Greg Claytond88d7592010-09-15 08:33:30 +00003937 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003938 if (num_attributes > 0)
3939 {
3940 uint32_t i;
3941 for (i=0; i<num_attributes; ++i)
3942 {
3943 attr = attributes.AttributeAtIndex(i);
3944 DWARFFormValue form_value;
3945 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3946 {
3947 switch (attr)
3948 {
Greg Clayton9e409562010-07-28 02:04:09 +00003949 case DW_AT_decl_file:
3950 decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3951 break;
3952
3953 case DW_AT_decl_line:
3954 decl.SetLine(form_value.Unsigned());
3955 break;
3956
3957 case DW_AT_decl_column:
3958 decl.SetColumn(form_value.Unsigned());
3959 break;
3960
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003961 case DW_AT_name:
3962 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00003963 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003964 break;
Greg Clayton9e409562010-07-28 02:04:09 +00003965
3966 case DW_AT_byte_size:
3967 byte_size = form_value.Unsigned();
Greg Clayton36909642011-03-15 04:38:20 +00003968 byte_size_valid = true;
Greg Clayton9e409562010-07-28 02:04:09 +00003969 break;
3970
3971 case DW_AT_accessibility:
3972 accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3973 break;
3974
3975 case DW_AT_declaration:
Greg Clayton7a345282010-11-09 23:46:37 +00003976 is_forward_declaration = form_value.Unsigned() != 0;
Greg Clayton9e409562010-07-28 02:04:09 +00003977 break;
3978
3979 case DW_AT_APPLE_runtime_class:
3980 class_language = (LanguageType)form_value.Signed();
3981 break;
3982
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003983 case DW_AT_allocated:
3984 case DW_AT_associated:
3985 case DW_AT_data_location:
3986 case DW_AT_description:
3987 case DW_AT_start_scope:
3988 case DW_AT_visibility:
3989 default:
3990 case DW_AT_sibling:
3991 break;
3992 }
3993 }
3994 }
3995 }
3996
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00003997 UniqueDWARFASTType unique_ast_entry;
3998 if (decl.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003999 {
Greg Claytone576ab22011-02-15 00:19:15 +00004000 if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
Greg Clayton36909642011-03-15 04:38:20 +00004001 this,
4002 dwarf_cu,
Greg Claytone576ab22011-02-15 00:19:15 +00004003 die,
4004 decl,
Greg Clayton36909642011-03-15 04:38:20 +00004005 byte_size_valid ? byte_size : -1,
Greg Claytone576ab22011-02-15 00:19:15 +00004006 unique_ast_entry))
Greg Claytonc615ce42010-11-09 04:42:43 +00004007 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004008 // We have already parsed this type or from another
4009 // compile unit. GCC loves to use the "one definition
4010 // rule" which can result in multiple definitions
4011 // of the same class over and over in each compile
4012 // unit.
4013 type_sp = unique_ast_entry.m_type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00004014 if (type_sp)
4015 {
Greg Clayton4272cc72011-02-02 02:24:04 +00004016 m_die_to_type[die] = type_sp.get();
4017 return type_sp;
4018 }
4019 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004020 }
4021
Greg Clayton81c22f62011-10-19 18:09:39 +00004022 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004023
4024 int tag_decl_kind = -1;
4025 AccessType default_accessibility = eAccessNone;
4026 if (tag == DW_TAG_structure_type)
4027 {
4028 tag_decl_kind = clang::TTK_Struct;
4029 default_accessibility = eAccessPublic;
4030 }
4031 else if (tag == DW_TAG_union_type)
4032 {
4033 tag_decl_kind = clang::TTK_Union;
4034 default_accessibility = eAccessPublic;
4035 }
4036 else if (tag == DW_TAG_class_type)
4037 {
4038 tag_decl_kind = clang::TTK_Class;
4039 default_accessibility = eAccessPrivate;
4040 }
4041
4042
4043 if (is_forward_declaration)
4044 {
4045 // We have a forward declaration to a type and we need
4046 // to try and find a full declaration. We look in the
4047 // current type index just in case we have a forward
4048 // declaration followed by an actual declarations in the
4049 // DWARF. If this fails, we need to look elsewhere...
4050
4051 type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
4052
4053 if (!type_sp && m_debug_map_symfile)
Greg Clayton4272cc72011-02-02 02:24:04 +00004054 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004055 // We weren't able to find a full declaration in
4056 // this DWARF, see if we have a declaration anywhere
4057 // else...
4058 type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
Greg Clayton4272cc72011-02-02 02:24:04 +00004059 }
4060
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004061 if (type_sp)
Greg Clayton4272cc72011-02-02 02:24:04 +00004062 {
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004063 // We found a real definition for this type elsewhere
4064 // so lets use it and cache the fact that we found
4065 // a complete type for this die
4066 m_die_to_type[die] = type_sp.get();
4067 return type_sp;
Greg Clayton4272cc72011-02-02 02:24:04 +00004068 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004069 }
4070 assert (tag_decl_kind != -1);
4071 bool clang_type_was_created = false;
4072 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
4073 if (clang_type == NULL)
4074 {
Greg Claytonf0705c82011-10-22 03:33:13 +00004075 clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, NULL);
Greg Clayton55561e92011-10-26 03:31:36 +00004076 if (accessibility == eAccessNone && decl_ctx)
4077 {
4078 // Check the decl context that contains this class/struct/union.
4079 // If it is a class we must give it an accessability.
4080 const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
4081 if (DeclKindIsCXXClass (containing_decl_kind))
4082 accessibility = default_accessibility;
4083 }
4084
Greg Claytonf0705c82011-10-22 03:33:13 +00004085 if (type_name_cstr && strchr (type_name_cstr, '<'))
4086 {
4087 ClangASTContext::TemplateParameterInfos template_param_infos;
4088 if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos))
4089 {
4090 clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx,
Greg Clayton55561e92011-10-26 03:31:36 +00004091 accessibility,
Greg Claytonf0705c82011-10-22 03:33:13 +00004092 type_name_cstr,
4093 tag_decl_kind,
4094 template_param_infos);
4095
4096 clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx,
4097 class_template_decl,
4098 tag_decl_kind,
4099 template_param_infos);
4100 clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
4101 clang_type_was_created = true;
4102 }
4103 }
4104
4105 if (!clang_type_was_created)
4106 {
4107 clang_type_was_created = true;
Greg Clayton55561e92011-10-26 03:31:36 +00004108 clang_type = ast.CreateRecordType (decl_ctx,
4109 accessibility,
4110 type_name_cstr,
Greg Claytonf0705c82011-10-22 03:33:13 +00004111 tag_decl_kind,
Greg Claytonf0705c82011-10-22 03:33:13 +00004112 class_language);
4113 }
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004114 }
4115
4116 // Store a forward declaration to this class type in case any
4117 // parameters in any class methods need it for the clang
Greg Claytona2721472011-06-25 00:44:06 +00004118 // types for function prototypes.
4119 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
Greg Clayton81c22f62011-10-19 18:09:39 +00004120 type_sp.reset (new Type (MakeUserID(die->GetOffset()),
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004121 this,
4122 type_name_const_str,
4123 byte_size,
4124 NULL,
4125 LLDB_INVALID_UID,
4126 Type::eEncodingIsUID,
4127 &decl,
4128 clang_type,
4129 Type::eResolveStateForward));
4130
4131
4132 // Add our type to the unique type map so we don't
4133 // end up creating many copies of the same type over
4134 // and over in the ASTContext for our module
4135 unique_ast_entry.m_type_sp = type_sp;
Greg Clayton36909642011-03-15 04:38:20 +00004136 unique_ast_entry.m_symfile = this;
4137 unique_ast_entry.m_cu = dwarf_cu;
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004138 unique_ast_entry.m_die = die;
4139 unique_ast_entry.m_declaration = decl;
Greg Claytone576ab22011-02-15 00:19:15 +00004140 GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
4141 unique_ast_entry);
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004142
4143 if (die->HasChildren() == false && is_forward_declaration == false)
4144 {
4145 // No children for this struct/union/class, lets finish it
4146 ast.StartTagDeclarationDefinition (clang_type);
4147 ast.CompleteTagDeclarationDefinition (clang_type);
4148 }
4149 else if (clang_type_was_created)
4150 {
4151 // Leave this as a forward declaration until we need
4152 // to know the details of the type. lldb_private::Type
4153 // will automatically call the SymbolFile virtual function
4154 // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
4155 // When the definition needs to be defined.
4156 m_forward_decl_die_to_clang_type[die] = clang_type;
4157 m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
4158 ClangASTContext::SetHasExternalStorage (clang_type, true);
Greg Claytonc615ce42010-11-09 04:42:43 +00004159 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004160 }
4161 break;
4162
4163 case DW_TAG_enumeration_type:
4164 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004165 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00004166 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004167
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004168 lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004169
Greg Claytond88d7592010-09-15 08:33:30 +00004170 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004171 if (num_attributes > 0)
4172 {
4173 uint32_t i;
4174
4175 for (i=0; i<num_attributes; ++i)
4176 {
4177 attr = attributes.AttributeAtIndex(i);
4178 DWARFFormValue form_value;
4179 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4180 {
4181 switch (attr)
4182 {
Greg Clayton7a345282010-11-09 23:46:37 +00004183 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4184 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4185 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004186 case DW_AT_name:
4187 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00004188 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004189 break;
Greg Clayton7a345282010-11-09 23:46:37 +00004190 case DW_AT_type: encoding_uid = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00004191 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Greg Clayton7a345282010-11-09 23:46:37 +00004192 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
4193 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004194 case DW_AT_allocated:
4195 case DW_AT_associated:
4196 case DW_AT_bit_stride:
4197 case DW_AT_byte_stride:
4198 case DW_AT_data_location:
4199 case DW_AT_description:
4200 case DW_AT_start_scope:
4201 case DW_AT_visibility:
4202 case DW_AT_specification:
4203 case DW_AT_abstract_origin:
4204 case DW_AT_sibling:
4205 break;
4206 }
4207 }
4208 }
4209
Greg Clayton81c22f62011-10-19 18:09:39 +00004210 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00004211
Greg Clayton1be10fc2010-09-29 01:12:09 +00004212 clang_type_t enumerator_clang_type = NULL;
4213 clang_type = m_forward_decl_die_to_clang_type.lookup (die);
4214 if (clang_type == NULL)
4215 {
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004216 enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
4217 DW_ATE_signed,
4218 byte_size * 8);
Greg Claytonca512b32011-01-14 04:54:56 +00004219 clang_type = ast.CreateEnumerationType (type_name_cstr,
Greg Claytoncb5860a2011-10-13 23:49:28 +00004220 GetClangDeclContextContainingDIE (dwarf_cu, die, NULL),
Greg Claytonca512b32011-01-14 04:54:56 +00004221 decl,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004222 enumerator_clang_type);
Greg Clayton1be10fc2010-09-29 01:12:09 +00004223 }
4224 else
4225 {
4226 enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
4227 assert (enumerator_clang_type != NULL);
4228 }
4229
Greg Claytona2721472011-06-25 00:44:06 +00004230 LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
4231
Greg Clayton81c22f62011-10-19 18:09:39 +00004232 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004233 this,
4234 type_name_const_str,
4235 byte_size,
4236 NULL,
4237 encoding_uid,
4238 Type::eEncodingIsUID,
4239 &decl,
4240 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004241 Type::eResolveStateForward));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004242
Greg Clayton6beaaa62011-01-17 03:46:26 +00004243 ast.StartTagDeclarationDefinition (clang_type);
4244 if (die->HasChildren())
4245 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00004246 SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
4247 ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
Greg Clayton6beaaa62011-01-17 03:46:26 +00004248 }
4249 ast.CompleteTagDeclarationDefinition (clang_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004250 }
4251 }
4252 break;
4253
Jim Inghamb0be4422010-08-12 01:20:14 +00004254 case DW_TAG_inlined_subroutine:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004255 case DW_TAG_subprogram:
4256 case DW_TAG_subroutine_type:
4257 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004258 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00004259 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004260
4261 const char *mangled = NULL;
4262 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
Greg Claytona51ed9b2010-09-23 01:09:21 +00004263 bool is_variadic = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004264 bool is_inline = false;
Greg Clayton0fffff52010-09-24 05:15:53 +00004265 bool is_static = false;
4266 bool is_virtual = false;
Greg Claytonf51de672010-10-01 02:31:07 +00004267 bool is_explicit = false;
Greg Clayton72da3972011-08-16 18:40:23 +00004268 dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
4269 dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
Greg Clayton0fffff52010-09-24 05:15:53 +00004270
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004271 unsigned type_quals = 0;
Sean Callanane2ef6e32010-09-23 03:01:22 +00004272 clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004273
4274
Greg Claytond88d7592010-09-15 08:33:30 +00004275 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004276 if (num_attributes > 0)
4277 {
4278 uint32_t i;
4279 for (i=0; i<num_attributes; ++i)
4280 {
Greg Clayton1a65ae12011-01-25 23:55:37 +00004281 attr = attributes.AttributeAtIndex(i);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004282 DWARFFormValue form_value;
4283 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4284 {
4285 switch (attr)
4286 {
4287 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4288 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4289 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4290 case DW_AT_name:
4291 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00004292 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004293 break;
4294
4295 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
4296 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004297 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00004298 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Greg Clayton0fffff52010-09-24 05:15:53 +00004299 case DW_AT_inline: is_inline = form_value.Unsigned() != 0; break;
4300 case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
Greg Claytonf51de672010-10-01 02:31:07 +00004301 case DW_AT_explicit: is_explicit = form_value.Unsigned() != 0; break;
4302
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004303 case DW_AT_external:
4304 if (form_value.Unsigned())
4305 {
Sean Callanane2ef6e32010-09-23 03:01:22 +00004306 if (storage == clang::SC_None)
4307 storage = clang::SC_Extern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004308 else
Sean Callanane2ef6e32010-09-23 03:01:22 +00004309 storage = clang::SC_PrivateExtern;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004310 }
4311 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004312
Greg Clayton72da3972011-08-16 18:40:23 +00004313 case DW_AT_specification:
4314 specification_die_offset = form_value.Reference(dwarf_cu);
4315 break;
4316
4317 case DW_AT_abstract_origin:
4318 abstract_origin_die_offset = form_value.Reference(dwarf_cu);
4319 break;
4320
4321
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004322 case DW_AT_allocated:
4323 case DW_AT_associated:
4324 case DW_AT_address_class:
4325 case DW_AT_artificial:
4326 case DW_AT_calling_convention:
4327 case DW_AT_data_location:
4328 case DW_AT_elemental:
4329 case DW_AT_entry_pc:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004330 case DW_AT_frame_base:
4331 case DW_AT_high_pc:
4332 case DW_AT_low_pc:
4333 case DW_AT_object_pointer:
4334 case DW_AT_prototyped:
4335 case DW_AT_pure:
4336 case DW_AT_ranges:
4337 case DW_AT_recursive:
4338 case DW_AT_return_addr:
4339 case DW_AT_segment:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004340 case DW_AT_start_scope:
4341 case DW_AT_static_link:
4342 case DW_AT_trampoline:
4343 case DW_AT_visibility:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004344 case DW_AT_vtable_elem_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004345 case DW_AT_description:
4346 case DW_AT_sibling:
4347 break;
4348 }
4349 }
4350 }
Greg Clayton24739922010-10-13 03:15:28 +00004351 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004352
Greg Clayton81c22f62011-10-19 18:09:39 +00004353 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00004354
Greg Clayton24739922010-10-13 03:15:28 +00004355 clang_type_t return_clang_type = NULL;
4356 Type *func_type = NULL;
4357
4358 if (type_die_offset != DW_INVALID_OFFSET)
4359 func_type = ResolveTypeUID(type_die_offset);
Greg Claytonf51de672010-10-01 02:31:07 +00004360
Greg Clayton24739922010-10-13 03:15:28 +00004361 if (func_type)
Greg Clayton526e5af2010-11-13 03:52:47 +00004362 return_clang_type = func_type->GetClangLayoutType();
Greg Clayton24739922010-10-13 03:15:28 +00004363 else
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004364 return_clang_type = ast.GetBuiltInType_void();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004365
Greg Claytonf51de672010-10-01 02:31:07 +00004366
Greg Clayton24739922010-10-13 03:15:28 +00004367 std::vector<clang_type_t> function_param_types;
4368 std::vector<clang::ParmVarDecl*> function_param_decls;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004369
Greg Clayton24739922010-10-13 03:15:28 +00004370 // Parse the function children for the parameters
Sean Callanan763d72a2011-08-02 22:21:50 +00004371
Greg Claytoncb5860a2011-10-13 23:49:28 +00004372 const DWARFDebugInfoEntry *decl_ctx_die = NULL;
4373 clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
Greg Clayton5113dc82011-08-12 06:47:54 +00004374 const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
4375
Greg Claytonf0705c82011-10-22 03:33:13 +00004376 const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
Greg Clayton5113dc82011-08-12 06:47:54 +00004377 // Start off static. This will be set to false in ParseChildParameters(...)
4378 // if we find a "this" paramters as the first parameter
4379 if (is_cxx_method)
Sean Callanan763d72a2011-08-02 22:21:50 +00004380 is_static = true;
4381
Greg Clayton24739922010-10-13 03:15:28 +00004382 if (die->HasChildren())
4383 {
Greg Clayton0fffff52010-09-24 05:15:53 +00004384 bool skip_artificial = true;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004385 ParseChildParameters (sc,
Greg Clayton5113dc82011-08-12 06:47:54 +00004386 containing_decl_ctx,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004387 type_sp,
4388 dwarf_cu,
4389 die,
Sean Callanan763d72a2011-08-02 22:21:50 +00004390 skip_artificial,
4391 is_static,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004392 type_list,
4393 function_param_types,
Greg Clayton7fedea22010-11-16 02:10:54 +00004394 function_param_decls,
4395 type_quals);
Greg Clayton24739922010-10-13 03:15:28 +00004396 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004397
Greg Clayton24739922010-10-13 03:15:28 +00004398 // clang_type will get the function prototype clang type after this call
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004399 clang_type = ast.CreateFunctionType (return_clang_type,
4400 &function_param_types[0],
4401 function_param_types.size(),
4402 is_variadic,
4403 type_quals);
4404
Greg Clayton24739922010-10-13 03:15:28 +00004405 if (type_name_cstr)
4406 {
4407 bool type_handled = false;
Greg Clayton24739922010-10-13 03:15:28 +00004408 if (tag == DW_TAG_subprogram)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004409 {
Jim Inghamb7f6b2f2011-09-08 22:13:49 +00004410 if (ObjCLanguageRuntime::IsPossibleObjCMethodName (type_name_cstr))
Greg Clayton0fffff52010-09-24 05:15:53 +00004411 {
Greg Clayton24739922010-10-13 03:15:28 +00004412 // We need to find the DW_TAG_class_type or
4413 // DW_TAG_struct_type by name so we can add this
4414 // as a member function of the class.
4415 const char *class_name_start = type_name_cstr + 2;
4416 const char *class_name_end = ::strchr (class_name_start, ' ');
4417 SymbolContext empty_sc;
4418 clang_type_t class_opaque_type = NULL;
4419 if (class_name_start < class_name_end)
Greg Clayton0fffff52010-09-24 05:15:53 +00004420 {
Greg Clayton24739922010-10-13 03:15:28 +00004421 ConstString class_name (class_name_start, class_name_end - class_name_start);
4422 TypeList types;
Sean Callanan213fdb82011-10-13 01:49:10 +00004423 const uint32_t match_count = FindTypes (empty_sc, class_name, NULL, true, UINT32_MAX, types);
Greg Clayton24739922010-10-13 03:15:28 +00004424 if (match_count > 0)
Greg Clayton0fffff52010-09-24 05:15:53 +00004425 {
Greg Clayton24739922010-10-13 03:15:28 +00004426 for (uint32_t i=0; i<match_count; ++i)
Greg Clayton0fffff52010-09-24 05:15:53 +00004427 {
Greg Clayton24739922010-10-13 03:15:28 +00004428 Type *type = types.GetTypeAtIndex (i).get();
4429 clang_type_t type_clang_forward_type = type->GetClangForwardType();
4430 if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
Greg Clayton0fffff52010-09-24 05:15:53 +00004431 {
Greg Clayton24739922010-10-13 03:15:28 +00004432 class_opaque_type = type_clang_forward_type;
4433 break;
Greg Clayton0fffff52010-09-24 05:15:53 +00004434 }
4435 }
4436 }
Greg Clayton24739922010-10-13 03:15:28 +00004437 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004438
Greg Clayton24739922010-10-13 03:15:28 +00004439 if (class_opaque_type)
4440 {
4441 // If accessibility isn't set to anything valid, assume public for
4442 // now...
4443 if (accessibility == eAccessNone)
4444 accessibility = eAccessPublic;
4445
4446 clang::ObjCMethodDecl *objc_method_decl;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004447 objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
4448 type_name_cstr,
4449 clang_type,
4450 accessibility);
Greg Clayton2c5f0e92011-08-04 21:02:57 +00004451 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
Greg Clayton24739922010-10-13 03:15:28 +00004452 type_handled = objc_method_decl != NULL;
4453 }
4454 }
Greg Clayton5113dc82011-08-12 06:47:54 +00004455 else if (is_cxx_method)
Greg Clayton24739922010-10-13 03:15:28 +00004456 {
4457 // Look at the parent of this DIE and see if is is
4458 // a class or struct and see if this is actually a
4459 // C++ method
Greg Claytoncb5860a2011-10-13 23:49:28 +00004460 Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
Greg Clayton24739922010-10-13 03:15:28 +00004461 if (class_type)
4462 {
Greg Clayton72da3972011-08-16 18:40:23 +00004463 if (specification_die_offset != DW_INVALID_OFFSET)
Greg Clayton0fffff52010-09-24 05:15:53 +00004464 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004465 // We have a specification which we are going to base our function
4466 // prototype off of, so we need this type to be completed so that the
4467 // m_die_to_decl_ctx for the method in the specification has a valid
4468 // clang decl context.
4469 class_type->GetClangFullType();
Greg Clayton72da3972011-08-16 18:40:23 +00004470 // If we have a specification, then the function type should have been
4471 // made with the specification and not with this die.
4472 DWARFCompileUnitSP spec_cu_sp;
4473 const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
Greg Clayton5cf58b92011-10-05 22:22:08 +00004474 clang::DeclContext *spec_clang_decl_ctx = GetCachedClangDeclContextForDIE (spec_die);
4475 if (spec_clang_decl_ctx)
4476 {
4477 LinkDeclContextToDIE(spec_clang_decl_ctx, die);
4478 }
4479 else
Jim Inghamc1663042011-09-29 22:12:35 +00004480 {
Greg Clayton81c22f62011-10-19 18:09:39 +00004481 ReportWarning ("0x%8.8llx: DW_AT_specification(0x%8.8x) has no decl\n",
4482 MakeUserID(die->GetOffset()),
Greg Clayton5cf58b92011-10-05 22:22:08 +00004483 specification_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00004484 }
Greg Clayton72da3972011-08-16 18:40:23 +00004485 type_handled = true;
4486 }
4487 else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
4488 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00004489 // We have a specification which we are going to base our function
4490 // prototype off of, so we need this type to be completed so that the
4491 // m_die_to_decl_ctx for the method in the abstract origin has a valid
4492 // clang decl context.
4493 class_type->GetClangFullType();
4494
Greg Clayton72da3972011-08-16 18:40:23 +00004495 DWARFCompileUnitSP abs_cu_sp;
4496 const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
Greg Clayton5cf58b92011-10-05 22:22:08 +00004497 clang::DeclContext *abs_clang_decl_ctx = GetCachedClangDeclContextForDIE (abs_die);
4498 if (abs_clang_decl_ctx)
4499 {
4500 LinkDeclContextToDIE (abs_clang_decl_ctx, die);
4501 }
4502 else
Jim Inghamc1663042011-09-29 22:12:35 +00004503 {
Greg Clayton81c22f62011-10-19 18:09:39 +00004504 ReportWarning ("0x%8.8llx: DW_AT_abstract_origin(0x%8.8x) has no decl\n",
4505 MakeUserID(die->GetOffset()),
Greg Clayton5cf58b92011-10-05 22:22:08 +00004506 abstract_origin_die_offset);
Jim Inghamc1663042011-09-29 22:12:35 +00004507 }
Greg Clayton72da3972011-08-16 18:40:23 +00004508 type_handled = true;
4509 }
4510 else
4511 {
4512 clang_type_t class_opaque_type = class_type->GetClangForwardType();
4513 if (ClangASTContext::IsCXXClassType (class_opaque_type))
Greg Clayton931180e2011-01-27 06:44:37 +00004514 {
Greg Clayton20568dd2011-10-13 23:13:20 +00004515 if (ClangASTContext::IsBeingDefined (class_opaque_type))
Greg Clayton72da3972011-08-16 18:40:23 +00004516 {
Greg Clayton20568dd2011-10-13 23:13:20 +00004517 // Neither GCC 4.2 nor clang++ currently set a valid accessibility
4518 // in the DWARF for C++ methods... Default to public for now...
4519 if (accessibility == eAccessNone)
4520 accessibility = eAccessPublic;
4521
4522 if (!is_static && !die->HasChildren())
4523 {
4524 // We have a C++ member function with no children (this pointer!)
4525 // and clang will get mad if we try and make a function that isn't
4526 // well formed in the DWARF, so we will just skip it...
4527 type_handled = true;
4528 }
4529 else
4530 {
4531 clang::CXXMethodDecl *cxx_method_decl;
4532 // REMOVE THE CRASH DESCRIPTION BELOW
Greg Clayton81c22f62011-10-19 18:09:39 +00004533 Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8llx from %s/%s",
Greg Clayton20568dd2011-10-13 23:13:20 +00004534 type_name_cstr,
4535 class_type->GetName().GetCString(),
Greg Clayton81c22f62011-10-19 18:09:39 +00004536 MakeUserID(die->GetOffset()),
Greg Clayton20568dd2011-10-13 23:13:20 +00004537 m_obj_file->GetFileSpec().GetDirectory().GetCString(),
4538 m_obj_file->GetFileSpec().GetFilename().GetCString());
4539
4540 cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
4541 type_name_cstr,
4542 clang_type,
4543 accessibility,
4544 is_virtual,
4545 is_static,
4546 is_inline,
4547 is_explicit);
4548 LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
4549
4550 type_handled = cxx_method_decl != NULL;
4551 }
Greg Clayton72da3972011-08-16 18:40:23 +00004552 }
4553 else
4554 {
Greg Clayton20568dd2011-10-13 23:13:20 +00004555 // We were asked to parse the type for a method in a class, yet the
4556 // class hasn't been asked to complete itself through the
4557 // clang::ExternalASTSource protocol, so we need to just have the
4558 // class complete itself and do things the right way, then our
4559 // DIE should then have an entry in the m_die_to_type map. First
4560 // we need to modify the m_die_to_type so it doesn't think we are
4561 // trying to parse this DIE anymore...
4562 m_die_to_type[die] = NULL;
4563
4564 // Now we get the full type to force our class type to complete itself
4565 // using the clang::ExternalASTSource protocol which will parse all
4566 // base classes and all methods (including the method for this DIE).
4567 class_type->GetClangFullType();
Greg Clayton2c5f0e92011-08-04 21:02:57 +00004568
Greg Clayton20568dd2011-10-13 23:13:20 +00004569 // The type for this DIE should have been filled in the function call above
4570 type_ptr = m_die_to_type[die];
4571 if (type_ptr)
4572 {
Greg Clayton85ae2e12011-10-18 23:36:41 +00004573 type_sp = type_ptr;
Greg Clayton20568dd2011-10-13 23:13:20 +00004574 break;
4575 }
Greg Clayton72da3972011-08-16 18:40:23 +00004576 }
Greg Clayton931180e2011-01-27 06:44:37 +00004577 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004578 }
4579 }
Greg Clayton0fffff52010-09-24 05:15:53 +00004580 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004581 }
Greg Clayton24739922010-10-13 03:15:28 +00004582
4583 if (!type_handled)
4584 {
4585 // We just have a function that isn't part of a class
Greg Clayton147e1fa2011-10-14 22:47:18 +00004586 clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (containing_decl_ctx,
4587 type_name_cstr,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004588 clang_type,
4589 storage,
4590 is_inline);
Greg Clayton24739922010-10-13 03:15:28 +00004591
4592 // Add the decl to our DIE to decl context map
4593 assert (function_decl);
Greg Claytona2721472011-06-25 00:44:06 +00004594 LinkDeclContextToDIE(function_decl, die);
Greg Clayton24739922010-10-13 03:15:28 +00004595 if (!function_param_decls.empty())
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004596 ast.SetFunctionParameters (function_decl,
4597 &function_param_decls.front(),
4598 function_param_decls.size());
Greg Clayton24739922010-10-13 03:15:28 +00004599 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004600 }
Greg Clayton81c22f62011-10-19 18:09:39 +00004601 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004602 this,
4603 type_name_const_str,
4604 0,
4605 NULL,
4606 LLDB_INVALID_UID,
4607 Type::eEncodingIsUID,
4608 &decl,
4609 clang_type,
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004610 Type::eResolveStateFull));
Greg Clayton24739922010-10-13 03:15:28 +00004611 assert(type_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004612 }
4613 break;
4614
4615 case DW_TAG_array_type:
4616 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004617 // Set a bit that lets us know that we are currently parsing this
Greg Clayton594e5ed2010-09-27 21:07:38 +00004618 m_die_to_type[die] = DIE_IS_BEING_PARSED;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004619
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004620 lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004621 int64_t first_index = 0;
4622 uint32_t byte_stride = 0;
4623 uint32_t bit_stride = 0;
Greg Claytond88d7592010-09-15 08:33:30 +00004624 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004625
4626 if (num_attributes > 0)
4627 {
4628 uint32_t i;
4629 for (i=0; i<num_attributes; ++i)
4630 {
4631 attr = attributes.AttributeAtIndex(i);
4632 DWARFFormValue form_value;
4633 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4634 {
4635 switch (attr)
4636 {
4637 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4638 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
4639 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4640 case DW_AT_name:
4641 type_name_cstr = form_value.AsCString(&get_debug_str_data());
Greg Clayton24739922010-10-13 03:15:28 +00004642 type_name_const_str.SetCString(type_name_cstr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004643 break;
4644
4645 case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
Greg Clayton36909642011-03-15 04:38:20 +00004646 case DW_AT_byte_size: byte_size = form_value.Unsigned(); byte_size_valid = true; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004647 case DW_AT_byte_stride: byte_stride = form_value.Unsigned(); break;
4648 case DW_AT_bit_stride: bit_stride = form_value.Unsigned(); break;
Greg Clayton8cf05932010-07-22 18:30:50 +00004649 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
Greg Clayton7a345282010-11-09 23:46:37 +00004650 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004651 case DW_AT_allocated:
4652 case DW_AT_associated:
4653 case DW_AT_data_location:
4654 case DW_AT_description:
4655 case DW_AT_ordering:
4656 case DW_AT_start_scope:
4657 case DW_AT_visibility:
4658 case DW_AT_specification:
4659 case DW_AT_abstract_origin:
4660 case DW_AT_sibling:
4661 break;
4662 }
4663 }
4664 }
4665
Greg Clayton81c22f62011-10-19 18:09:39 +00004666 DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Greg Claytonc93237c2010-10-01 20:48:32 +00004667
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004668 Type *element_type = ResolveTypeUID(type_die_offset);
4669
4670 if (element_type)
4671 {
4672 std::vector<uint64_t> element_orders;
4673 ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
Greg Claytona134cc12010-09-13 02:37:44 +00004674 // We have an array that claims to have no members, lets give it at least one member...
4675 if (element_orders.empty())
4676 element_orders.push_back (1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004677 if (byte_stride == 0 && bit_stride == 0)
4678 byte_stride = element_type->GetByteSize();
Greg Claytonf4ecaa52011-02-16 23:00:21 +00004679 clang_type_t array_element_type = element_type->GetClangFullType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004680 uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
4681 uint64_t num_elements = 0;
4682 std::vector<uint64_t>::const_reverse_iterator pos;
4683 std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
4684 for (pos = element_orders.rbegin(); pos != end; ++pos)
4685 {
4686 num_elements = *pos;
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004687 clang_type = ast.CreateArrayType (array_element_type,
4688 num_elements,
4689 num_elements * array_element_bit_stride);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004690 array_element_type = clang_type;
4691 array_element_bit_stride = array_element_bit_stride * num_elements;
4692 }
4693 ConstString empty_name;
Greg Clayton81c22f62011-10-19 18:09:39 +00004694 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004695 this,
4696 empty_name,
4697 array_element_bit_stride / 8,
4698 NULL,
Greg Clayton526e5af2010-11-13 03:52:47 +00004699 type_die_offset,
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004700 Type::eEncodingIsUID,
4701 &decl,
4702 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004703 Type::eResolveStateFull));
4704 type_sp->SetEncodingType (element_type);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004705 }
4706 }
4707 }
4708 break;
4709
Greg Clayton9b81a312010-06-12 01:20:30 +00004710 case DW_TAG_ptr_to_member_type:
4711 {
4712 dw_offset_t type_die_offset = DW_INVALID_OFFSET;
4713 dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
4714
Greg Claytond88d7592010-09-15 08:33:30 +00004715 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
Greg Clayton9b81a312010-06-12 01:20:30 +00004716
4717 if (num_attributes > 0) {
4718 uint32_t i;
4719 for (i=0; i<num_attributes; ++i)
4720 {
4721 attr = attributes.AttributeAtIndex(i);
4722 DWARFFormValue form_value;
4723 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4724 {
4725 switch (attr)
4726 {
4727 case DW_AT_type:
4728 type_die_offset = form_value.Reference(dwarf_cu); break;
4729 case DW_AT_containing_type:
4730 containing_type_die_offset = form_value.Reference(dwarf_cu); break;
4731 }
4732 }
4733 }
4734
4735 Type *pointee_type = ResolveTypeUID(type_die_offset);
4736 Type *class_type = ResolveTypeUID(containing_type_die_offset);
4737
Greg Clayton526e5af2010-11-13 03:52:47 +00004738 clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
4739 clang_type_t class_clang_type = class_type->GetClangLayoutType();
Greg Clayton9b81a312010-06-12 01:20:30 +00004740
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004741 clang_type = ast.CreateMemberPointerType(pointee_clang_type,
4742 class_clang_type);
Greg Clayton9b81a312010-06-12 01:20:30 +00004743
Greg Clayton526e5af2010-11-13 03:52:47 +00004744 byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
4745 clang_type) / 8;
Greg Clayton9b81a312010-06-12 01:20:30 +00004746
Greg Clayton81c22f62011-10-19 18:09:39 +00004747 type_sp.reset( new Type (MakeUserID(die->GetOffset()),
Greg Clayton2d95dc9b2010-11-10 04:57:04 +00004748 this,
4749 type_name_const_str,
4750 byte_size,
4751 NULL,
4752 LLDB_INVALID_UID,
4753 Type::eEncodingIsUID,
4754 NULL,
4755 clang_type,
Greg Clayton526e5af2010-11-13 03:52:47 +00004756 Type::eResolveStateForward));
Greg Clayton9b81a312010-06-12 01:20:30 +00004757 }
4758
4759 break;
4760 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004761 default:
Greg Clayton9b81a312010-06-12 01:20:30 +00004762 assert(false && "Unhandled type tag!");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004763 break;
4764 }
4765
4766 if (type_sp.get())
4767 {
4768 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4769 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4770
4771 SymbolContextScope * symbol_context_scope = NULL;
4772 if (sc_parent_tag == DW_TAG_compile_unit)
4773 {
4774 symbol_context_scope = sc.comp_unit;
4775 }
4776 else if (sc.function != NULL)
4777 {
Greg Clayton81c22f62011-10-19 18:09:39 +00004778 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004779 if (symbol_context_scope == NULL)
4780 symbol_context_scope = sc.function;
4781 }
4782
4783 if (symbol_context_scope != NULL)
4784 {
4785 type_sp->SetSymbolContextScope(symbol_context_scope);
4786 }
4787
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004788 // We are ready to put this type into the uniqued list up at the module level
4789 type_list->Insert (type_sp);
Greg Clayton450e3f32010-10-12 02:24:53 +00004790
Greg Clayton1c9e5ac2011-02-09 19:06:17 +00004791 m_die_to_type[die] = type_sp.get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004792 }
4793 }
Greg Clayton594e5ed2010-09-27 21:07:38 +00004794 else if (type_ptr != DIE_IS_BEING_PARSED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004795 {
Greg Clayton85ae2e12011-10-18 23:36:41 +00004796 type_sp = type_ptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004797 }
4798 }
4799 return type_sp;
4800}
4801
4802size_t
Greg Clayton1be10fc2010-09-29 01:12:09 +00004803SymbolFileDWARF::ParseTypes
4804(
4805 const SymbolContext& sc,
4806 DWARFCompileUnit* dwarf_cu,
4807 const DWARFDebugInfoEntry *die,
4808 bool parse_siblings,
4809 bool parse_children
4810)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004811{
4812 size_t types_added = 0;
4813 while (die != NULL)
4814 {
4815 bool type_is_new = false;
Greg Clayton1be10fc2010-09-29 01:12:09 +00004816 if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004817 {
4818 if (type_is_new)
4819 ++types_added;
4820 }
4821
4822 if (parse_children && die->HasChildren())
4823 {
4824 if (die->Tag() == DW_TAG_subprogram)
4825 {
4826 SymbolContext child_sc(sc);
Greg Clayton81c22f62011-10-19 18:09:39 +00004827 child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004828 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
4829 }
4830 else
4831 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
4832 }
4833
4834 if (parse_siblings)
4835 die = die->GetSibling();
4836 else
4837 die = NULL;
4838 }
4839 return types_added;
4840}
4841
4842
4843size_t
4844SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
4845{
4846 assert(sc.comp_unit && sc.function);
4847 size_t functions_added = 0;
4848 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4849 if (dwarf_cu)
4850 {
4851 dw_offset_t function_die_offset = sc.function->GetID();
4852 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
4853 if (function_die)
4854 {
Greg Claytondd7feaf2011-08-12 17:54:33 +00004855 ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004856 }
4857 }
4858
4859 return functions_added;
4860}
4861
4862
4863size_t
4864SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
4865{
4866 // At least a compile unit must be valid
4867 assert(sc.comp_unit);
4868 size_t types_added = 0;
4869 DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
4870 if (dwarf_cu)
4871 {
4872 if (sc.function)
4873 {
4874 dw_offset_t function_die_offset = sc.function->GetID();
4875 const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
4876 if (func_die && func_die->HasChildren())
4877 {
4878 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
4879 }
4880 }
4881 else
4882 {
4883 const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
4884 if (dwarf_cu_die && dwarf_cu_die->HasChildren())
4885 {
4886 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
4887 }
4888 }
4889 }
4890
4891 return types_added;
4892}
4893
4894size_t
4895SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4896{
4897 if (sc.comp_unit != NULL)
4898 {
Greg Clayton4b3dc102010-11-01 20:32:12 +00004899 DWARFDebugInfo* info = DebugInfo();
4900 if (info == NULL)
4901 return 0;
4902
4903 uint32_t cu_idx = UINT32_MAX;
4904 DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004905
4906 if (dwarf_cu == NULL)
4907 return 0;
4908
4909 if (sc.function)
4910 {
4911 const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
Greg Clayton016a95e2010-09-14 02:20:48 +00004912
4913 dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4914 assert (func_lo_pc != DW_INVALID_ADDRESS);
4915
Greg Claytonc662ec82011-06-17 22:10:16 +00004916 const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4917
4918 // Let all blocks know they have parse all their variables
4919 sc.function->GetBlock (false).SetDidParseVariables (true, true);
4920
4921 return num_variables;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004922 }
4923 else if (sc.comp_unit)
4924 {
4925 uint32_t vars_added = 0;
4926 VariableListSP variables (sc.comp_unit->GetVariableList(false));
4927
4928 if (variables.get() == NULL)
4929 {
4930 variables.reset(new VariableList());
4931 sc.comp_unit->SetVariableList(variables);
4932
Greg Claytond4a2b372011-09-12 23:21:58 +00004933 DWARFCompileUnit* match_dwarf_cu = NULL;
4934 const DWARFDebugInfoEntry* die = NULL;
4935 DIEArray die_offsets;
Greg Clayton97fbc342011-10-20 22:30:33 +00004936 if (m_using_apple_tables)
Greg Clayton7f995132011-10-04 22:41:51 +00004937 {
Greg Clayton97fbc342011-10-20 22:30:33 +00004938 if (m_apple_names_ap.get())
4939 m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
4940 dwarf_cu->GetNextCompileUnitOffset(),
4941 die_offsets);
Greg Clayton7f995132011-10-04 22:41:51 +00004942 }
4943 else
4944 {
4945 // Index if we already haven't to make sure the compile units
4946 // get indexed and make their global DIE index list
4947 if (!m_indexed)
4948 Index ();
4949
4950 m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
4951 dwarf_cu->GetNextCompileUnitOffset(),
4952 die_offsets);
4953 }
4954
4955 const size_t num_matches = die_offsets.size();
Greg Claytond4a2b372011-09-12 23:21:58 +00004956 if (num_matches)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004957 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004958 DWARFDebugInfo* debug_info = DebugInfo();
4959 for (size_t i=0; i<num_matches; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004960 {
Greg Claytond4a2b372011-09-12 23:21:58 +00004961 const dw_offset_t die_offset = die_offsets[i];
4962 die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
4963 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
4964 if (var_sp)
4965 {
4966 variables->AddVariableIfUnique (var_sp);
4967 ++vars_added;
4968 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004969 }
4970 }
4971 }
4972 return vars_added;
4973 }
4974 }
4975 return 0;
4976}
4977
4978
4979VariableSP
4980SymbolFileDWARF::ParseVariableDIE
4981(
4982 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00004983 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00004984 const DWARFDebugInfoEntry *die,
4985 const lldb::addr_t func_low_pc
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004986)
4987{
4988
Greg Clayton83c5cd92010-11-14 22:13:40 +00004989 VariableSP var_sp (m_die_to_variable_sp[die]);
4990 if (var_sp)
4991 return var_sp; // Already been parsed!
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004992
4993 const dw_tag_t tag = die->Tag();
Greg Clayton7f995132011-10-04 22:41:51 +00004994
4995 if ((tag == DW_TAG_variable) ||
4996 (tag == DW_TAG_constant) ||
4997 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004998 {
Greg Clayton7f995132011-10-04 22:41:51 +00004999 DWARFDebugInfoEntry::Attributes attributes;
5000 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
5001 if (num_attributes > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005002 {
Greg Clayton7f995132011-10-04 22:41:51 +00005003 const char *name = NULL;
5004 const char *mangled = NULL;
5005 Declaration decl;
5006 uint32_t i;
5007 Type *var_type = NULL;
5008 DWARFExpression location;
5009 bool is_external = false;
5010 bool is_artificial = false;
5011 bool location_is_const_value_data = false;
5012 AccessType accessibility = eAccessNone;
5013
5014 for (i=0; i<num_attributes; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005015 {
Greg Clayton7f995132011-10-04 22:41:51 +00005016 dw_attr_t attr = attributes.AttributeAtIndex(i);
5017 DWARFFormValue form_value;
5018 if (attributes.ExtractFormValueAtIndex(this, i, form_value))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005019 {
Greg Clayton7f995132011-10-04 22:41:51 +00005020 switch (attr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005021 {
Greg Clayton7f995132011-10-04 22:41:51 +00005022 case DW_AT_decl_file: decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
5023 case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
5024 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
5025 case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
5026 case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
5027 case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
5028 case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
5029 case DW_AT_const_value:
5030 location_is_const_value_data = true;
5031 // Fall through...
5032 case DW_AT_location:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005033 {
Greg Clayton7f995132011-10-04 22:41:51 +00005034 if (form_value.BlockData())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005035 {
Greg Clayton7f995132011-10-04 22:41:51 +00005036 const DataExtractor& debug_info_data = get_debug_info_data();
5037
5038 uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
5039 uint32_t block_length = form_value.Unsigned();
5040 location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
5041 }
5042 else
5043 {
5044 const DataExtractor& debug_loc_data = get_debug_loc_data();
5045 const dw_offset_t debug_loc_offset = form_value.Unsigned();
5046
5047 size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
5048 if (loc_list_length > 0)
5049 {
5050 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
5051 assert (func_low_pc != LLDB_INVALID_ADDRESS);
5052 location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
5053 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005054 }
5055 }
Greg Clayton7f995132011-10-04 22:41:51 +00005056 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005057
Greg Clayton7f995132011-10-04 22:41:51 +00005058 case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
5059 case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
5060 case DW_AT_declaration:
5061 case DW_AT_description:
5062 case DW_AT_endianity:
5063 case DW_AT_segment:
5064 case DW_AT_start_scope:
5065 case DW_AT_visibility:
5066 default:
5067 case DW_AT_abstract_origin:
5068 case DW_AT_sibling:
5069 case DW_AT_specification:
5070 break;
5071 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005072 }
5073 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005074
Greg Clayton7f995132011-10-04 22:41:51 +00005075 if (location.IsValid())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005076 {
Greg Clayton7f995132011-10-04 22:41:51 +00005077 assert(var_type != DIE_IS_BEING_PARSED);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005078
Greg Clayton7f995132011-10-04 22:41:51 +00005079 ValueType scope = eValueTypeInvalid;
5080
5081 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
5082 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
5083
5084 if (tag == DW_TAG_formal_parameter)
5085 scope = eValueTypeVariableArgument;
5086 else if (is_external || parent_tag == DW_TAG_compile_unit)
5087 scope = eValueTypeVariableGlobal;
5088 else
5089 scope = eValueTypeVariableLocal;
5090
5091 SymbolContextScope * symbol_context_scope = NULL;
Greg Clayton5cf58b92011-10-05 22:22:08 +00005092 switch (parent_tag)
Greg Clayton7f995132011-10-04 22:41:51 +00005093 {
Greg Clayton5cf58b92011-10-05 22:22:08 +00005094 case DW_TAG_subprogram:
5095 case DW_TAG_inlined_subroutine:
5096 case DW_TAG_lexical_block:
5097 if (sc.function)
5098 {
Greg Clayton81c22f62011-10-19 18:09:39 +00005099 symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Greg Clayton5cf58b92011-10-05 22:22:08 +00005100 if (symbol_context_scope == NULL)
5101 symbol_context_scope = sc.function;
5102 }
5103 break;
5104
5105 default:
Greg Clayton7f995132011-10-04 22:41:51 +00005106 symbol_context_scope = sc.comp_unit;
Greg Clayton5cf58b92011-10-05 22:22:08 +00005107 break;
Greg Clayton7f995132011-10-04 22:41:51 +00005108 }
5109
Greg Clayton5cf58b92011-10-05 22:22:08 +00005110 if (symbol_context_scope)
5111 {
Greg Clayton81c22f62011-10-19 18:09:39 +00005112 var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
5113 name,
5114 mangled,
5115 var_type,
5116 scope,
5117 symbol_context_scope,
5118 &decl,
5119 location,
5120 is_external,
5121 is_artificial));
Greg Clayton5cf58b92011-10-05 22:22:08 +00005122
5123 var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
5124 }
5125 else
5126 {
5127 // Not ready to parse this variable yet. It might be a global
5128 // or static variable that is in a function scope and the function
5129 // in the symbol context wasn't filled in yet
5130 return var_sp;
5131 }
Greg Clayton7f995132011-10-04 22:41:51 +00005132 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005133 }
Greg Clayton7f995132011-10-04 22:41:51 +00005134 // Cache var_sp even if NULL (the variable was just a specification or
5135 // was missing vital information to be able to be displayed in the debugger
5136 // (missing location due to optimization, etc)) so we don't re-parse
5137 // this DIE over and over later...
5138 m_die_to_variable_sp[die] = var_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005139 }
5140 return var_sp;
5141}
5142
Greg Claytonc662ec82011-06-17 22:10:16 +00005143
5144const DWARFDebugInfoEntry *
5145SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
5146 dw_offset_t spec_block_die_offset,
5147 DWARFCompileUnit **result_die_cu_handle)
5148{
5149 // Give the concrete function die specified by "func_die_offset", find the
5150 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
5151 // to "spec_block_die_offset"
5152 DWARFDebugInfo* info = DebugInfo();
5153
5154 const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
5155 if (die)
5156 {
5157 assert (*result_die_cu_handle);
5158 return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
5159 }
5160 return NULL;
5161}
5162
5163
5164const DWARFDebugInfoEntry *
5165SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
5166 const DWARFDebugInfoEntry *die,
5167 dw_offset_t spec_block_die_offset,
5168 DWARFCompileUnit **result_die_cu_handle)
5169{
5170 if (die)
5171 {
5172 switch (die->Tag())
5173 {
5174 case DW_TAG_subprogram:
5175 case DW_TAG_inlined_subroutine:
5176 case DW_TAG_lexical_block:
5177 {
5178 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
5179 {
5180 *result_die_cu_handle = dwarf_cu;
5181 return die;
5182 }
5183
5184 if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
5185 {
5186 *result_die_cu_handle = dwarf_cu;
5187 return die;
5188 }
5189 }
5190 break;
5191 }
5192
5193 // Give the concrete function die specified by "func_die_offset", find the
5194 // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
5195 // to "spec_block_die_offset"
5196 for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
5197 {
5198 const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
5199 child_die,
5200 spec_block_die_offset,
5201 result_die_cu_handle);
5202 if (result_die)
5203 return result_die;
5204 }
5205 }
5206
5207 *result_die_cu_handle = NULL;
5208 return NULL;
5209}
5210
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005211size_t
5212SymbolFileDWARF::ParseVariables
5213(
5214 const SymbolContext& sc,
Greg Clayton0fffff52010-09-24 05:15:53 +00005215 DWARFCompileUnit* dwarf_cu,
Greg Clayton016a95e2010-09-14 02:20:48 +00005216 const lldb::addr_t func_low_pc,
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005217 const DWARFDebugInfoEntry *orig_die,
5218 bool parse_siblings,
5219 bool parse_children,
5220 VariableList* cc_variable_list
5221)
5222{
5223 if (orig_die == NULL)
5224 return 0;
5225
Greg Claytonc662ec82011-06-17 22:10:16 +00005226 VariableListSP variable_list_sp;
5227
5228 size_t vars_added = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005229 const DWARFDebugInfoEntry *die = orig_die;
Greg Claytonc662ec82011-06-17 22:10:16 +00005230 while (die != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005231 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005232 dw_tag_t tag = die->Tag();
5233
5234 // Check to see if we have already parsed this variable or constant?
5235 if (m_die_to_variable_sp[die])
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005236 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005237 if (cc_variable_list)
5238 cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005239 }
5240 else
5241 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005242 // We haven't already parsed it, lets do that now.
5243 if ((tag == DW_TAG_variable) ||
5244 (tag == DW_TAG_constant) ||
5245 (tag == DW_TAG_formal_parameter && sc.function))
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005246 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005247 if (variable_list_sp.get() == NULL)
Greg Clayton73bf5db2011-06-17 01:22:15 +00005248 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005249 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
5250 dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
5251 switch (parent_tag)
5252 {
5253 case DW_TAG_compile_unit:
5254 if (sc.comp_unit != NULL)
5255 {
5256 variable_list_sp = sc.comp_unit->GetVariableList(false);
5257 if (variable_list_sp.get() == NULL)
5258 {
5259 variable_list_sp.reset(new VariableList());
5260 sc.comp_unit->SetVariableList(variable_list_sp);
5261 }
5262 }
5263 else
5264 {
Greg Clayton81c22f62011-10-19 18:09:39 +00005265 ReportError ("parent 0x%8.8llx %s with no valid compile unit in symbol context for 0x%8.8llx %s.\n",
5266 MakeUserID(sc_parent_die->GetOffset()),
5267 DW_TAG_value_to_name (parent_tag),
5268 MakeUserID(orig_die->GetOffset()),
5269 DW_TAG_value_to_name (orig_die->Tag()));
Greg Claytonc662ec82011-06-17 22:10:16 +00005270 }
5271 break;
5272
5273 case DW_TAG_subprogram:
5274 case DW_TAG_inlined_subroutine:
5275 case DW_TAG_lexical_block:
5276 if (sc.function != NULL)
5277 {
5278 // Check to see if we already have parsed the variables for the given scope
5279
Greg Clayton81c22f62011-10-19 18:09:39 +00005280 Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
Greg Claytonc662ec82011-06-17 22:10:16 +00005281 if (block == NULL)
5282 {
5283 // This must be a specification or abstract origin with
5284 // a concrete block couterpart in the current function. We need
5285 // to find the concrete block so we can correctly add the
5286 // variable to it
5287 DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
5288 const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
5289 sc_parent_die->GetOffset(),
5290 &concrete_block_die_cu);
5291 if (concrete_block_die)
Greg Clayton81c22f62011-10-19 18:09:39 +00005292 block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset()));
Greg Claytonc662ec82011-06-17 22:10:16 +00005293 }
5294
5295 if (block != NULL)
5296 {
5297 const bool can_create = false;
5298 variable_list_sp = block->GetBlockVariableList (can_create);
5299 if (variable_list_sp.get() == NULL)
5300 {
5301 variable_list_sp.reset(new VariableList());
5302 block->SetVariableList(variable_list_sp);
5303 }
5304 }
5305 }
5306 break;
5307
5308 default:
Greg Clayton81c22f62011-10-19 18:09:39 +00005309 ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8llx %s.\n",
5310 MakeUserID(orig_die->GetOffset()),
5311 DW_TAG_value_to_name (orig_die->Tag()));
Greg Claytonc662ec82011-06-17 22:10:16 +00005312 break;
5313 }
Greg Clayton73bf5db2011-06-17 01:22:15 +00005314 }
Greg Claytonc662ec82011-06-17 22:10:16 +00005315
5316 if (variable_list_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005317 {
Greg Clayton73bf5db2011-06-17 01:22:15 +00005318 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
5319 if (var_sp)
5320 {
Greg Claytonc662ec82011-06-17 22:10:16 +00005321 variable_list_sp->AddVariableIfUnique (var_sp);
Greg Clayton73bf5db2011-06-17 01:22:15 +00005322 if (cc_variable_list)
5323 cc_variable_list->AddVariableIfUnique (var_sp);
5324 ++vars_added;
5325 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005326 }
5327 }
5328 }
Greg Claytonc662ec82011-06-17 22:10:16 +00005329
5330 bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
5331
5332 if (!skip_children && parse_children && die->HasChildren())
5333 {
5334 vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
5335 }
5336
5337 if (parse_siblings)
5338 die = die->GetSibling();
5339 else
5340 die = NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005341 }
Greg Claytonc662ec82011-06-17 22:10:16 +00005342 return vars_added;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00005343}
5344
5345//------------------------------------------------------------------
5346// PluginInterface protocol
5347//------------------------------------------------------------------
5348const char *
5349SymbolFileDWARF::GetPluginName()
5350{
5351 return "SymbolFileDWARF";
5352}
5353
5354const char *
5355SymbolFileDWARF::GetShortPluginName()
5356{
5357 return GetPluginNameStatic();
5358}
5359
5360uint32_t
5361SymbolFileDWARF::GetPluginVersion()
5362{
5363 return 1;
5364}
5365
5366void
Greg Clayton6beaaa62011-01-17 03:46:26 +00005367SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
5368{
5369 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
5370 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
5371 if (clang_type)
5372 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
5373}
5374
5375void
5376SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
5377{
5378 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
5379 clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
5380 if (clang_type)
5381 symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
5382}
5383
Greg Claytona2721472011-06-25 00:44:06 +00005384void
Sean Callanancc427fa2011-07-30 02:42:06 +00005385SymbolFileDWARF::DumpIndexes ()
5386{
5387 StreamFile s(stdout, false);
5388
5389 s.Printf ("DWARF index for (%s) '%s/%s':",
5390 GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
5391 GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
5392 GetObjectFile()->GetFileSpec().GetFilename().AsCString());
5393 s.Printf("\nFunction basenames:\n"); m_function_basename_index.Dump (&s);
5394 s.Printf("\nFunction fullnames:\n"); m_function_fullname_index.Dump (&s);
5395 s.Printf("\nFunction methods:\n"); m_function_method_index.Dump (&s);
5396 s.Printf("\nFunction selectors:\n"); m_function_selector_index.Dump (&s);
5397 s.Printf("\nObjective C class selectors:\n"); m_objc_class_selectors_index.Dump (&s);
5398 s.Printf("\nGlobals and statics:\n"); m_global_index.Dump (&s);
5399 s.Printf("\nTypes:\n"); m_type_index.Dump (&s);
5400 s.Printf("\nNamepaces:\n"); m_namespace_index.Dump (&s);
5401}
5402
5403void
5404SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
5405 const char *name,
5406 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
Greg Claytona2721472011-06-25 00:44:06 +00005407{
Sean Callanancc427fa2011-07-30 02:42:06 +00005408 DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
Greg Claytona2721472011-06-25 00:44:06 +00005409
5410 if (iter == m_decl_ctx_to_die.end())
5411 return;
5412
Greg Claytoncb5860a2011-10-13 23:49:28 +00005413 for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos)
Greg Claytona2721472011-06-25 00:44:06 +00005414 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00005415 const DWARFDebugInfoEntry *context_die = *pos;
5416
5417 if (!results)
5418 return;
5419
5420 DWARFDebugInfo* info = DebugInfo();
5421
5422 DIEArray die_offsets;
5423
5424 DWARFCompileUnit* dwarf_cu = NULL;
5425 const DWARFDebugInfoEntry* die = NULL;
5426 size_t num_matches = m_type_index.Find (ConstString(name), die_offsets);
5427
5428 if (num_matches)
Greg Claytona2721472011-06-25 00:44:06 +00005429 {
Greg Claytoncb5860a2011-10-13 23:49:28 +00005430 for (size_t i = 0; i < num_matches; ++i)
5431 {
5432 const dw_offset_t die_offset = die_offsets[i];
5433 die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
Greg Claytond4a2b372011-09-12 23:21:58 +00005434
Greg Claytoncb5860a2011-10-13 23:49:28 +00005435 if (die->GetParent() != context_die)
5436 continue;
5437
5438 Type *matching_type = ResolveType (dwarf_cu, die);
5439
5440 lldb::clang_type_t type = matching_type->GetClangFullType();
5441 clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
5442
5443 if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
5444 {
5445 clang::TagDecl *tag_decl = tag_type->getDecl();
5446 results->push_back(tag_decl);
5447 }
5448 else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
5449 {
5450 clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
5451 results->push_back(typedef_decl);
5452 }
Greg Claytona2721472011-06-25 00:44:06 +00005453 }
5454 }
5455 }
5456}
5457
5458void
5459SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
Greg Clayton85ae2e12011-10-18 23:36:41 +00005460 const clang::DeclContext *decl_context,
5461 clang::DeclarationName decl_name,
Greg Claytona2721472011-06-25 00:44:06 +00005462 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
5463{
Greg Clayton85ae2e12011-10-18 23:36:41 +00005464
5465 switch (decl_context->getDeclKind())
5466 {
5467 case clang::Decl::Namespace:
5468 case clang::Decl::TranslationUnit:
5469 {
5470 SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
5471 symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results);
5472 }
5473 break;
5474 default:
5475 break;
5476 }
Greg Claytona2721472011-06-25 00:44:06 +00005477}