Search variables based on clang::DeclContext and clang::Decl tree
Summary: SymbolFileDWARF now creates VarDecl and BlockDecl and adds them to the Decl tree. Then, in ClangExpressionDeclMap it uses the Decl tree to search for a variable. This fixes lots of variable scoping problems.
Reviewers: sivachandra, chaoren, spyffe, clayborg
Subscribers: tberghammer, jingham, lldb-commits
Differential Revision: http://reviews.llvm.org/D12658
llvm-svn: 247746
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index caf95b7..2764902 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -48,6 +48,8 @@
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/CompilerDecl.h"
+#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -1391,6 +1393,26 @@
return false;
}
+CompilerDecl
+SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
+{
+ if (UserIDMatches(type_uid))
+ {
+ DWARFDebugInfo* debug_info = DebugInfo();
+ if (debug_info)
+ {
+ DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
+ if (die)
+ {
+ DWARFASTParser *dwarf_ast = die.GetDWARFParser();
+ if (dwarf_ast)
+ return dwarf_ast->GetDeclForUIDFromDWARF(die);
+ }
+ }
+ }
+ return CompilerDecl();
+}
+
CompilerDeclContext
SymbolFileDWARF::GetDeclContextForUID (lldb::user_id_t type_uid)
{
@@ -3057,6 +3079,8 @@
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type:
+ case DW_TAG_lexical_block:
+ case DW_TAG_subprogram:
return die;
default:
@@ -3741,6 +3765,7 @@
{
DWARFAttributes attributes;
const size_t num_attributes = die.GetAttributes(attributes);
+ DWARFDIE spec_die;
if (num_attributes > 0)
{
const char *name = NULL;
@@ -3862,7 +3887,13 @@
}
}
break;
-
+ case DW_AT_specification:
+ {
+ DWARFDebugInfo* debug_info = DebugInfo();
+ if (debug_info)
+ spec_die = debug_info->GetDIE(DIERef(form_value));
+ break;
+ }
case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
case DW_AT_accessibility: break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
case DW_AT_declaration:
@@ -3874,7 +3905,6 @@
default:
case DW_AT_abstract_origin:
case DW_AT_sibling:
- case DW_AT_specification:
break;
}
}
@@ -4078,6 +4108,8 @@
// (missing location due to optimization, etc)) so we don't re-parse
// this DIE over and over later...
GetDIEToVariable()[die.GetDIE()] = var_sp;
+ if (spec_die)
+ GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
}
return var_sp;
}