paulherman updated this revision to Diff 34911.
paulherman added a comment.
Add using directives to the clang::DeclContext and fix decls for variables
inside namespaces
Rebased the patch.
http://reviews.llvm.org/D12897
Files:
include/lldb/Symbol/SymbolFile.h
source/Expression/ClangExpressionDeclMap.cpp
source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
source/Symbol/ClangASTContext.cpp
test/lang/cpp/nsimport/TestCppNsImport.py
Index: test/lang/cpp/nsimport/TestCppNsImport.py
===================================================================
--- test/lang/cpp/nsimport/TestCppNsImport.py
+++ test/lang/cpp/nsimport/TestCppNsImport.py
@@ -80,18 +80,21 @@
test_result = frame.EvaluateExpression("fun_var")
self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 9, "fun_var = 9")
+ test_result = frame.EvaluateExpression("Fun::fun_var")
+ self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 0, "Fun::fun_var = 0")
+
test_result = frame.EvaluateExpression("not_imported")
self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 35, "not_imported = 35")
- # Disabled the "imported" test since it isn't valid. It should actually test for ambiguity
- #test_result = frame.EvaluateExpression("imported")
- #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 99, "imported = 99")
-
- test_result = frame.EvaluateExpression("::imported")
- self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 89, "::imported = 89")
+ # Currently there is no way to distinguish between "::imported" and "imported" in ClangExpressionDeclMap so this fails
+ #test_result = frame.EvaluateExpression("::imported")
+ #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 89, "::imported = 89")
test_result = frame.EvaluateExpression("Imported::imported")
self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 99, "Imported::imported = 99")
+
+ test_result = frame.EvaluateExpression("imported")
+ self.assertTrue(test_result.IsValid() and test_result.GetError().Fail(), "imported is ambiguous")
test_result = frame.EvaluateExpression("single")
self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 3, "single = 3")
Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ source/Symbol/ClangASTContext.cpp
@@ -1730,24 +1730,6 @@
// BAD!!!
}
}
-
-
- if (namespace_decl)
- {
- // If we make it here, we are creating the anonymous namespace decl
- // for the first time, so we need to do the using directive magic
- // like SEMA does
- UsingDirectiveDecl* using_directive_decl = UsingDirectiveDecl::Create (*ast,
- decl_ctx,
- SourceLocation(),
- SourceLocation(),
- NestedNameSpecifierLoc(),
- SourceLocation(),
- namespace_decl,
- decl_ctx);
- using_directive_decl->setImplicit();
- decl_ctx->addDecl(using_directive_decl);
- }
}
#ifdef LLDB_CONFIGURATION_DEBUG
VerifyDecl(namespace_decl);
@@ -1768,20 +1750,37 @@
return nullptr;
}
+clang::DeclContext *
+FindLCABetweenDecls(clang::DeclContext *left, clang::DeclContext *right, clang::DeclContext *root)
+{
+ if (root == nullptr)
+ return nullptr;
+
+ std::set<clang::DeclContext *> path_left;
+ for (clang::DeclContext *d = left; d != nullptr; d = d->getParent())
+ path_left.insert(d);
+
+ for (clang::DeclContext *d = right; d != nullptr; d = d->getParent())
+ if (path_left.find(d) != path_left.end())
+ return d;
+
+ return nullptr;
+}
+
clang::UsingDirectiveDecl *
ClangASTContext::CreateUsingDirectiveDeclaration (clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl)
{
if (decl_ctx != nullptr && ns_decl != nullptr)
{
- // TODO: run LCA between decl_tx and ns_decl
+ clang::TranslationUnitDecl *translation_unit = (clang::TranslationUnitDecl *)GetTranslationUnitDecl(getASTContext());
clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create(*getASTContext(),
decl_ctx,
clang::SourceLocation(),
clang::SourceLocation(),
clang::NestedNameSpecifierLoc(),
clang::SourceLocation(),
ns_decl,
- GetTranslationUnitDecl(getASTContext()));
+ FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit));
decl_ctx->addDecl(using_decl);
return using_decl;
}
@@ -1826,7 +1825,6 @@
clang::SC_None);
var_decl->setAccess(clang::AS_public);
decl_context->addDecl(var_decl);
- decl_context->makeDeclVisibleInContext(var_decl);
return var_decl;
}
return nullptr;
@@ -8867,23 +8865,20 @@
DeclContext *root_decl_ctx = (DeclContext *)opaque_decl_ctx;
std::set<DeclContext *> searched;
std::multimap<DeclContext *, DeclContext *> search_queue;
+ SymbolFile *symbol_file = GetSymbolFile();
for (clang::DeclContext *decl_context = root_decl_ctx; decl_context != nullptr && found_decls.empty(); decl_context = decl_context->getParent())
{
search_queue.insert(std::make_pair(decl_context, decl_context));
for (auto it = search_queue.find(decl_context); it != search_queue.end(); it++)
{
searched.insert(it->second);
+ symbol_file->ParseDeclsForContext(CompilerDeclContext(this, it->second));
+
for (clang::Decl *child : it->second->decls())
{
- if (clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(child))
- {
- IdentifierInfo *ii = nd->getIdentifier();
- if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
- found_decls.push_back(nd);
- }
- else if (clang::UsingDirectiveDecl *ud = llvm::dyn_cast<clang::UsingDirectiveDecl>(child))
+ if (clang::UsingDirectiveDecl *ud = llvm::dyn_cast<clang::UsingDirectiveDecl>(child))
{
clang::DeclContext *from = ud->getCommonAncestor();
if (searched.find(ud->getNominatedNamespace()) == searched.end())
@@ -8902,6 +8897,12 @@
}
}
}
+ else if (clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(child))
+ {
+ IdentifierInfo *ii = nd->getIdentifier();
+ if (ii != nullptr && ii->getName().equals(name.AsCString(nullptr)))
+ found_decls.push_back(nd);
+ }
}
}
}
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -162,6 +162,10 @@
lldb_private::CompilerDeclContext
GetDeclContextContainingUID (lldb::user_id_t uid) override;
+ void
+ ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx) override;
+
+
uint32_t
ResolveSymbolContext (const lldb_private::Address& so_addr,
uint32_t resolve_scope,
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1392,6 +1392,18 @@
return false;
}
+void
+SymbolFileDWARF::ParseDeclsForContext (CompilerDeclContext decl_ctx)
+{
+ TypeSystem *type_system = decl_ctx.GetTypeSystem();
+ DWARFASTParser *ast_parser = type_system->GetDWARFParser();
+ std::vector<DWARFDIE> decl_ctx_die_list = ast_parser->GetDIEForDeclContext(decl_ctx);
+
+ for (DWARFDIE decl_ctx_die : decl_ctx_die_list)
+ for (DWARFDIE decl = decl_ctx_die.GetFirstChild(); decl; decl = decl.GetSibling())
+ ast_parser->GetDeclForUIDFromDWARF(decl);
+}
+
CompilerDecl
SymbolFileDWARF::GetDeclForUID (lldb::user_id_t type_uid)
{
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
@@ -12,6 +12,7 @@
#include "DWARFDefines.h"
#include "DWARFASTParser.h"
+#include "DWARFDIE.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -57,6 +58,12 @@
return lldb_private::CompilerDecl();
}
+ virtual std::vector<DWARFDIE>
+ GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) override
+ {
+ return std::vector<DWARFDIE>();
+ }
+
private:
size_t ParseChildParameters(const lldb_private::SymbolContext &sc, const DWARFDIE &parent_die, bool &is_variadic,
std::vector<lldb_private::CompilerType> &function_param_types);
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -51,6 +51,9 @@
virtual lldb_private::CompilerDecl
GetDeclForUIDFromDWARF (const DWARFDIE &die) override;
+ virtual std::vector<DWARFDIE>
+ GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) override;
+
virtual lldb_private::CompilerDeclContext
GetDeclContextForUIDFromDWARF (const DWARFDIE &die) override;
@@ -173,7 +176,8 @@
typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;
- typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap;
+ //typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet> DeclContextToDIEMap;
+ typedef std::multimap<const clang::DeclContext *, const DWARFDIE> DeclContextToDIEMap;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *> DIEToDeclMap;
typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -35,6 +35,9 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include <map>
+#include <vector>
+
//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
@@ -2039,6 +2042,15 @@
return false;
}
+std::vector<DWARFDIE>
+DWARFASTParserClang::GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context)
+{
+ std::vector<DWARFDIE> result;
+ for (auto it = m_decl_ctx_to_die.find((clang::DeclContext *)decl_context.GetOpaqueDeclContext()); it != m_decl_ctx_to_die.end(); it++)
+ result.push_back(it->second);
+ return result;
+}
+
CompilerDecl
DWARFASTParserClang::GetDeclForUIDFromDWARF (const DWARFDIE &die)
{
@@ -3213,6 +3225,9 @@
if (!die)
return nullptr;
+ if (die.GetReferencedDIE(DW_AT_specification))
+ return GetClangDeclForDIE(die.GetReferencedDIE(DW_AT_specification));
+
clang::Decl *decl = m_die_to_decl[die.GetDIE()];
if (decl != nullptr)
return decl;
@@ -3261,8 +3276,8 @@
if (imported_decl)
{
clang::DeclContext *decl_context = ClangASTContext::DeclContextGetAsDeclContext(dwarf->GetDeclContextContainingUID(die.GetID()));
- if (clang::NamespaceDecl *clang_imported_decl = llvm::dyn_cast<clang::NamespaceDecl>((clang::DeclContext *)imported_decl.GetOpaqueDeclContext()))
- decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, clang_imported_decl);
+ if (clang::NamespaceDecl *ns_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(imported_decl))
+ decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
}
}
break;
@@ -3431,7 +3446,8 @@
{
m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
// There can be many DIEs for a single decl context
- m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
+ //m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
+ m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
}
bool
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -45,6 +45,9 @@
virtual lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) = 0;
+
+ virtual std::vector<DWARFDIE>
+ GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) = 0;
};
#endif // SymbolFileDWARF_DWARFASTParser_h_
Index: source/Expression/ClangExpressionDeclMap.cpp
===================================================================
--- source/Expression/ClangExpressionDeclMap.cpp
+++ source/Expression/ClangExpressionDeclMap.cpp
@@ -1351,7 +1351,6 @@
{
ValueObjectSP valobj;
VariableSP var;
- Error err;
if (frame && !namespace_decl)
{
@@ -1366,17 +1365,21 @@
// Search for declarations matching the name
std::vector<CompilerDecl> found_decls = compiler_decl_context.FindDeclByName(name);
+
+ bool variable_found = false;
for (CompilerDecl decl : found_decls)
{
var = decl.GetAsVariable();
if (var)
{
+ variable_found = true;
valobj = ValueObjectVariable::Create(frame, var);
AddOneVariable(context, var, valobj, current_id);
context.m_found.variable = true;
- return;
}
}
+ if (variable_found)
+ return;
}
}
if (target)
Index: include/lldb/Symbol/SymbolFile.h
===================================================================
--- include/lldb/Symbol/SymbolFile.h
+++ include/lldb/Symbol/SymbolFile.h
@@ -131,6 +131,7 @@
virtual size_t ParseVariablesForContext (const SymbolContext& sc) = 0;
virtual Type* ResolveTypeUID (lldb::user_id_t type_uid) = 0;
virtual bool CompleteType (CompilerType &clang_type) = 0;
+ virtual void ParseDeclsForContext (CompilerDeclContext decl_ctx) {}
virtual CompilerDecl GetDeclForUID (lldb::user_id_t uid) { return CompilerDecl(); }
virtual CompilerDeclContext GetDeclContextForUID (lldb::user_id_t uid) { return CompilerDeclContext(); }
virtual CompilerDeclContext GetDeclContextContainingUID (lldb::user_id_t uid) { return CompilerDeclContext(); }
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits