summaryrefslogtreecommitdiffstats
path: root/lldb
diff options
context:
space:
mode:
authorPaul Herman <paulherman@google.com>2015-09-16 18:48:30 +0000
committerPaul Herman <paulherman@google.com>2015-09-16 18:48:30 +0000
commitea188fc318a0df1e4bb5a8857d26fad456d0b1ee (patch)
treec1ae88dc714d4b8e85a71be406033ebd1d396e5b /lldb
parent459a64aed70f5e74f80bf081c9ebc827274fbd1e (diff)
downloadbcm5719-llvm-ea188fc318a0df1e4bb5a8857d26fad456d0b1ee.tar.gz
bcm5719-llvm-ea188fc318a0df1e4bb5a8857d26fad456d0b1ee.zip
Add using directives to the clang::DeclContext and fix decls for variables inside namespaces
Summary: Supports the parsing of the "using namespace XXX" and "using XXX::XXX" directives. Added ambiguity errors when it two decls with the same name are encountered (see comments in TestCppNsImport). Fixes using directives being duplicated for anonymous namespaces. Fixes GetDeclForUID for specification DIEs. Reviewers: sivachandra, chaoren, clayborg Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D12897 llvm-svn: 247836
Diffstat (limited to 'lldb')
-rw-r--r--lldb/include/lldb/Symbol/SymbolFile.h1
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp7
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp22
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h7
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp12
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h4
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp57
-rw-r--r--lldb/test/lang/cpp/nsimport/TestCppNsImport.py15
10 files changed, 94 insertions, 40 deletions
diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index db2124e1bfb..a43361a27dc 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -131,6 +131,7 @@ public:
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(); }
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 1678d835227..235288ab783 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -1351,7 +1351,6 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
{
ValueObjectSP valobj;
VariableSP var;
- Error err;
if (frame && !namespace_decl)
{
@@ -1366,17 +1365,21 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
// 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)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 11d231d4293..7af63b73c5b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -45,6 +45,9 @@ public:
virtual lldb_private::CompilerDeclContext
GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) = 0;
+
+ virtual std::vector<DWARFDIE>
+ GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) = 0;
};
#endif // SymbolFileDWARF_DWARFASTParser_h_
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 29c31ed4e7c..8782ac9526e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/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 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die,
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 @@ DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
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 @@ DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die)
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 @@ DWARFASTParserClang::LinkDeclContextToDIE (clang::DeclContext *decl_ctx, const D
{
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
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 1bfeaceebeb..4d0f9281308 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -51,6 +51,9 @@ public:
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 @@ protected:
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;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
index 7857fc540db..85b2425ea8b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
+++ b/lldb/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 @@ class DWARFASTParserGo : public DWARFASTParser
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);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 8a99bc2a49b..b654f2690da 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1392,6 +1392,18 @@ SymbolFileDWARF::ClassOrStructIsVirtual (const DWARFDIE &parent_die)
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)
{
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index cc0ccc999e4..3530e35afd3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -162,6 +162,10 @@ public:
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,
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 97a5a7f9203..712c5dd3aac 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -1730,24 +1730,6 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d
// 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,12 +1750,29 @@ ClangASTContext::CreateBlockDeclaration (clang::DeclContext *ctx)
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(),
@@ -1781,7 +1780,7 @@ ClangASTContext::CreateUsingDirectiveDeclaration (clang::DeclContext *decl_ctx,
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 @@ ClangASTContext::CreateVariableDeclaration (clang::DeclContext *decl_context, co
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,6 +8865,7 @@ ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString na
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())
{
@@ -8875,15 +8874,11 @@ ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString na
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 @@ ClangASTContext::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString na
}
}
}
+ 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);
+ }
}
}
}
diff --git a/lldb/test/lang/cpp/nsimport/TestCppNsImport.py b/lldb/test/lang/cpp/nsimport/TestCppNsImport.py
index 986f9d53253..01622bfa3ec 100644
--- a/lldb/test/lang/cpp/nsimport/TestCppNsImport.py
+++ b/lldb/test/lang/cpp/nsimport/TestCppNsImport.py
@@ -80,18 +80,21 @@ class TestCppNsImport(TestBase):
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")
OpenPOWER on IntegriCloud