From 503aa525eaea55fb68be1e3e27e5f9bfdcd4b7df Mon Sep 17 00:00:00 2001 From: Sean Callanan Date: Wed, 12 Oct 2011 00:12:34 +0000 Subject: [PATCH] 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 --- .../lldb/Expression/ClangExpressionDeclMap.h | 34 +++- lldb/include/lldb/Symbol/ClangASTImporter.h | 12 +- lldb/source/Expression/ClangASTSource.cpp | 2 +- .../Expression/ClangExpressionDeclMap.cpp | 166 ++++++++++++++---- .../Expression/ClangExpressionParser.cpp | 2 +- lldb/source/Symbol/ClangASTImporter.cpp | 18 ++ 6 files changed, 197 insertions(+), 37 deletions(-) diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index 4ea5b046bda8..5db2c44bdd15 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -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 diff --git a/lldb/include/lldb/Symbol/ClangASTImporter.h b/lldb/include/lldb/Symbol/ClangASTImporter.h index 32d2b3834f07..fb38de2b3516 100644 --- a/lldb/include/lldb/Symbol/ClangASTImporter.h +++ b/lldb/include/lldb/Symbol/ClangASTImporter.h @@ -63,6 +63,13 @@ public: return origin.Valid(); } + typedef std::map NamespaceMap; + typedef lldb::SharedPtr::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 NamespaceMetaMap; + + NamespaceMetaMap m_namespace_maps; + clang::FileManager m_file_manager; clang::ASTContext *m_target_ctx; MinionMap m_minions; MinionMap m_minimal_minions; diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 854fcc880d9a..f68e07c6b497 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -105,7 +105,7 @@ ClangASTSource::FindExternalVisibleDeclsByName // printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name); llvm::SmallVector 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); diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index e08985a27de7..42484f1242a8 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -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(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(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(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(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(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(copied_decl); + + m_parser_vars->GetASTImporter(context.GetASTContext())->RegisterNamespaceMap(copied_namespace_decl, namespace_decls); + return dyn_cast(copied_decl); } diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp index 17cc5a84c0d1..3156a3389a95 100644 --- a/lldb/source/Expression/ClangExpressionParser.cpp +++ b/lldb/source/Expression/ClangExpressionParser.cpp @@ -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 diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp index 4867400fcdec..3f987c6ea91c 100644 --- a/lldb/source/Symbol/ClangASTImporter.cpp +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -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) {