Implemented a namespace map that allows searching

of namespaces (only in the modules where they've
been found) for entities inside those namespaces.

For each NamespaceDecl that has been imported into
the parser, we maintain a map containing
[ModuleSP, ClangNamespaceDecl] pairs in the ASTImporter.
This map has one entry for each module in which the
namespace has been found.  When we later scan for an
entity inside a namespace, we search only the modules
in which that namespace was found.

Also made a small whitespace fix in 
ClangExpressionParser.cpp.

llvm-svn: 141748
This commit is contained in:
Sean Callanan 2011-10-12 00:12:34 +00:00
parent af1389546e
commit 503aa525ea
6 changed files with 197 additions and 37 deletions

View File

@ -117,7 +117,7 @@ public:
clang::NamespaceDecl *
AddNamespace (NameSearchContext &context,
const ClangNamespaceDecl &namespace_decl);
ClangASTImporter::NamespaceMapSP &namespace_decls);
//------------------------------------------------------------------
/// [Used by IRForTarget] Get a constant variable given a name,
@ -601,8 +601,8 @@ public:
/// True on success; false otherwise.
//------------------------------------------------------------------
void
GetDecls (NameSearchContext &context,
const ConstString &name);
FindExternalVisibleDecls (NameSearchContext &context,
const ConstString &name);
//------------------------------------------------------------------
/// [Used by ClangASTSource] Find all Decls in a context that match
@ -830,6 +830,34 @@ private:
m_material_vars.reset();
}
//------------------------------------------------------------------
/// [Used by ClangASTSource] Find all entities matching a given name,
/// using a NameSearchContext to make Decls for them.
///
/// @param[in] context
/// The NameSearchContext that can construct Decls for this name.
///
/// @param[in] module
/// If non-NULL, the module to query.
///
/// @param[in] decl
/// If non-NULL and module is non-NULL, the parent namespace.
///
/// @param[in] name
/// The name as a plain C string. The NameSearchContext contains
/// a DeclarationName for the name so at first the name may seem
/// redundant, but ClangExpressionDeclMap operates in RTTI land so
/// it can't access DeclarationName.
///
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
void
FindExternalVisibleDecls (NameSearchContext &context,
lldb::ModuleSP module,
ClangNamespaceDecl &decl,
const ConstString &name);
//------------------------------------------------------------------
/// Given a stack frame, find a variable that matches the given name and
/// type. We need this for expression re-use; we may not always get the

View File

@ -63,6 +63,13 @@ public:
return origin.Valid();
}
typedef std::map<lldb::ModuleSP, ClangNamespaceDecl> NamespaceMap;
typedef lldb::SharedPtr<NamespaceMap>::Type NamespaceMapSP;
void RegisterNamespaceMap(const clang::NamespaceDecl *decl,
NamespaceMapSP &namespace_map);
NamespaceMapSP GetNamespaceMap(const clang::NamespaceDecl *decl);
private:
struct DeclOrigin
@ -152,7 +159,10 @@ private:
return DeclOrigin();
}
clang::FileManager m_file_manager;
typedef std::map <const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
NamespaceMetaMap m_namespace_maps;
clang::FileManager m_file_manager;
clang::ASTContext *m_target_ctx;
MinionMap m_minions;
MinionMap m_minimal_minions;

View File

@ -105,7 +105,7 @@ ClangASTSource::FindExternalVisibleDeclsByName
// printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name);
llvm::SmallVector<NamedDecl*, 4> name_decls;
NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
m_decl_map.GetDecls(name_search_context, const_decl_name);
m_decl_map.FindExternalVisibleDecls(name_search_context, const_decl_name);
DeclContext::lookup_result result (SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls));
// --g_depth;
m_active_lookups.erase (uniqued_const_decl_name);

View File

@ -32,6 +32,7 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/Variable.h"
@ -2055,16 +2056,10 @@ ClangExpressionDeclMap::FindGlobalVariable
// Interface for ClangASTSource
void
ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name)
void
ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, const ConstString &name)
{
assert (m_struct_vars.get());
assert (m_parser_vars.get());
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("Hunting for a definition for '%s'", name.GetCString());
if (m_parser_vars->m_ignore_lookups)
{
@ -2073,6 +2068,65 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
return;
}
if (log)
{
if (!context.m_decl_context)
log->Printf("FindExternalVisibleDecls for '%s' in a NULL DeclContext", name.GetCString());
else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
log->Printf("FindExternalVisibleDecls for '%s' in '%s'", name.GetCString(), context_named_decl->getNameAsString().c_str());
else
log->Printf("FindExternalVisibleDecls for '%s' in a '%s'", name.GetCString(), context.m_decl_context->getDeclKindName());
}
if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
{
ClangASTImporter::NamespaceMapSP namespace_map = m_parser_vars->m_ast_importer->GetNamespaceMap(namespace_context);
for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
i != e;
++i)
{
if (log)
log->Printf(" Searching namespace '%s' in file '%s'",
i->second.GetNamespaceDecl()->getNameAsString().c_str(),
i->first->GetFileSpec().GetFilename().GetCString());
//FindExternalVisibleDecls(context,
// i->first,
// i->second,
// name);
}
}
else if (!isa<TranslationUnitDecl>(context.m_decl_context))
{
// we shouldn't be getting FindExternalVisibleDecls calls for these
return;
}
else
{
ClangNamespaceDecl namespace_decl;
if (log)
log->Printf(" Searching without a namespace");
FindExternalVisibleDecls(context,
lldb::ModuleSP(),
namespace_decl,
name);
}
}
void
ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
lldb::ModuleSP module,
ClangNamespaceDecl &decl,
const ConstString &name)
{
assert (m_struct_vars.get());
assert (m_parser_vars.get());
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
do
{
if (isa<TranslationUnitDecl>(context.m_decl_context))
@ -2153,10 +2207,10 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
if (frame)
{
valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr,
eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember,
var,
err);
eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember,
var,
err);
// If we found a variable in scope, no need to pull up function names
if (err.Success() && var != NULL)
@ -2249,25 +2303,53 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString
}
}
ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name));
ModuleList &images = m_parser_vars->m_sym_ctx.target_sp->GetImages();
if (namespace_decl)
ClangASTImporter::NamespaceMapSP namespace_decls(new ClangASTImporter::NamespaceMap);
for (uint32_t i = 0, e = images.GetSize();
i != e;
++i)
{
if (log)
{
std::string s;
llvm::raw_string_ostream os(s);
namespace_decl.GetNamespaceDecl()->print(os);
os.flush();
log->Printf("Added namespace decl:");
log->Printf("%s", s.c_str());
}
ModuleSP image = images.GetModuleAtIndex(i);
if (!image)
continue;
ClangNamespaceDecl namespace_decl;
SymbolVendor *symbol_vendor = image->GetSymbolVendor();
if (!symbol_vendor)
continue;
SymbolContext null_sc;
namespace_decl = symbol_vendor->FindNamespace(null_sc, name);
if (namespace_decl)
{
(*namespace_decls)[image] = namespace_decl;
if (log)
{
std::string s;
llvm::raw_string_ostream os(s);
namespace_decl.GetNamespaceDecl()->print(os);
os.flush();
log->Printf("Found namespace %s in file %s", s.c_str(), image->GetFileSpec().GetFilename().GetCString());
}
}
}
if (!namespace_decls->empty())
{
NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decls);
NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl);
if (clang_namespace_decl)
clang_namespace_decl->setHasExternalLexicalStorage();
}
clang_namespace_decl->setHasExternalVisibleStorage();
}
}
else
{
@ -2485,7 +2567,20 @@ ClangExpressionDeclMap::FindExternalLexicalDecls (const DeclContext *decl_contex
ASTContext *ast_context = &context_decl->getASTContext();
if (log)
log->Printf("Finding lexical decls in a '%s' with %s predicate", context_decl->getDeclKindName(), (predicate ? "non-null" : "null"));
{
if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
log->Printf("FindExternalLexicalDecls in '%s' (a %s) with %s predicate",
context_named_decl->getNameAsString().c_str(),
context_decl->getDeclKindName(),
(predicate ? "non-null" : "null"));
else if(context_decl)
log->Printf("FindExternalLexicalDecls in a %s with %s predicate",
context_decl->getDeclKindName(),
(predicate ? "non-null" : "null"));
else
log->Printf("FindExternalLexicalDecls in a NULL context with %s predicate",
(predicate ? "non-null" : "null"));
}
Decl *original_decl = NULL;
ASTContext *original_ctx = NULL;
@ -2933,15 +3028,24 @@ ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
}
NamespaceDecl *
ClangExpressionDeclMap::AddNamespace (NameSearchContext &context, const ClangNamespaceDecl &namespace_decl)
ClangExpressionDeclMap::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls)
{
if (namespace_decls.empty())
return NULL;
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
assert (m_parser_vars.get());
const ClangNamespaceDecl &namespace_decl = namespace_decls->begin()->second;
Decl *copied_decl = m_parser_vars->GetASTImporter(context.GetASTContext())->CopyDecl(namespace_decl.GetASTContext(),
namespace_decl.GetNamespaceDecl());
namespace_decl.GetNamespaceDecl());
NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
m_parser_vars->GetASTImporter(context.GetASTContext())->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
return dyn_cast<NamespaceDecl>(copied_decl);
}

View File

@ -556,7 +556,7 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr,
.setOptLevel(CodeGenOpt::Less)
.setAllocateGVsWithCode(true)
.setCodeModel(CodeModel::Small)
.setUseMCJIT(true);
.setUseMCJIT(true);
m_execution_engine.reset(builder.create());
#endif

View File

@ -93,6 +93,24 @@ ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface
return;
}
void
ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
NamespaceMapSP &namespace_map)
{
m_namespace_maps[decl] = namespace_map;
}
ClangASTImporter::NamespaceMapSP
ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl)
{
NamespaceMetaMap::iterator iter = m_namespace_maps.find(decl);
if (iter != m_namespace_maps.end())
return iter->second;
else
return NamespaceMapSP();
}
clang::Decl
*ClangASTImporter::Minion::Imported (clang::Decl *from, clang::Decl *to)
{