diff options
-rw-r--r-- | lldb/include/lldb/Expression/ClangASTSource.h | 20 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 31 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ClangASTContext.h | 10 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ClangASTImporter.h | 164 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h | 10 | ||||
-rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 6 | ||||
-rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 15 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 147 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 80 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 21 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp | 1 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTContext.cpp | 42 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTImporter.cpp | 61 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp | 11 |
14 files changed, 597 insertions, 22 deletions
diff --git a/lldb/include/lldb/Expression/ClangASTSource.h b/lldb/include/lldb/Expression/ClangASTSource.h index a840ad99a2e..22cdee5c371 100644 --- a/lldb/include/lldb/Expression/ClangASTSource.h +++ b/lldb/include/lldb/Expression/ClangASTSource.h @@ -251,6 +251,26 @@ struct NameSearchContext { /// The opaque QualType for the TypeDecl being registered. //------------------------------------------------------------------ clang::NamedDecl *AddTypeDecl(void *type); + + + //------------------------------------------------------------------ + /// Add Decls from the provided DeclContextLookupResult to the list + /// of results. + /// + /// @param[in] result + /// The DeclContextLookupResult, usually returned as the result + /// of querying a DeclContext. + //------------------------------------------------------------------ + void AddLookupResult (clang::DeclContextLookupConstResult result); + + //------------------------------------------------------------------ + /// Add a NamedDecl to the list of results. + /// + /// @param[in] decl + /// The NamedDecl, usually returned as the result + /// of querying a DeclContext. + //------------------------------------------------------------------ + void AddNamedDecl (clang::NamedDecl *decl); }; } diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index 665b3c09c5b..15c944ead88 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -25,6 +25,7 @@ #include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" #include "lldb/Expression/ClangExpressionVariable.h" +#include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/ExecutionContext.h" @@ -471,6 +472,23 @@ public: const ConstString &name); //------------------------------------------------------------------ + /// [Used by ClangASTSource] Fill in all the members of a (potentially + /// incomplete) DeclContext. + /// + /// @param[in] ast_context + /// The parser's AST context, in which the DeclContext is resident + /// + /// @param[in] decl_context + /// The DeclContext that needs to be filled in. + /// + /// @return + /// The completed context on success; NULL otherwise. + //------------------------------------------------------------------ + const clang::DeclContext * + CompleteDeclContext (clang::ASTContext *ast_context, + const clang::DeclContext *decl_context); + + //------------------------------------------------------------------ /// [Used by ClangASTSource] Report whether a $__lldb variable has /// been searched for yet. This is the trigger for beginning to /// actually look for externally-defined names. (Names that come @@ -535,11 +553,24 @@ private: m_sym_ctx.target_sp.get(); return NULL; } + + ClangASTImporter *GetASTImporter (clang::ASTContext *ast_context) + { + if (!m_ast_importer.get()) + m_ast_importer.reset(new ClangASTImporter(ast_context)); + + if (m_ast_importer->TargetASTContext() != ast_context) + return NULL; + + return m_ast_importer.get(); + } + ExecutionContext *m_exe_ctx; ///< The execution context to use when parsing. SymbolContext m_sym_ctx; ///< The symbol context to use in finding variables and types. ClangPersistentVariables *m_persistent_vars; ///< The persistent variables for the process. bool m_enable_lookups; ///< Set to true during parsing if we have found the first "$__lldb" name. bool m_ignore_lookups; ///< True during an import when we should be ignoring type lookups. + std::auto_ptr<ClangASTImporter> m_ast_importer; ///< The importer used to import types on the parser's behalf. private: DISALLOW_COPY_AND_ASSIGN (ParserVars); }; diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index bcb0dec2f24..73c9954e7ba 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -123,6 +123,16 @@ public: GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type); + bool + GetCompleteDecl (clang::Decl *decl) + { + return ClangASTContext::GetCompleteDecl(getASTContext(), decl); + } + + static bool + GetCompleteDecl (clang::ASTContext *ast, + clang::Decl *decl); + //------------------------------------------------------------------ // Basic Types //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Symbol/ClangASTImporter.h b/lldb/include/lldb/Symbol/ClangASTImporter.h new file mode 100644 index 00000000000..42fd947e3fd --- /dev/null +++ b/lldb/include/lldb/Symbol/ClangASTImporter.h @@ -0,0 +1,164 @@ +//===-- ClangASTImporter.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangASTImporter_h_ +#define liblldb_ClangASTImporter_h_ + +#include <map> + +#include "lldb/lldb-types.h" + +#include "clang/AST/ASTImporter.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" + +namespace lldb_private { + +class ClangASTImporter +{ +public: + ClangASTImporter (clang::ASTContext *target_ctx) : + m_target_ctx(target_ctx), + m_file_manager(clang::FileSystemOptions()) + { + } + + clang::ASTContext * + TargetASTContext () + { + return m_target_ctx; + } + + clang::QualType + CopyType (clang::ASTContext *src_ctx, + clang::QualType type); + + clang::Decl * + CopyDecl (clang::ASTContext *src_ctx, + clang::Decl *decl); + + const clang::DeclContext * + CompleteDeclContext (const clang::DeclContext *decl_context); + + bool + ResolveDeclOrigin (const clang::Decl *decl, clang::Decl **original_decl, clang::ASTContext **original_ctx) + { + DeclOrigin origin = GetDeclOrigin(decl); + + if (original_decl) + *original_decl = origin.decl; + + if (original_ctx) + *original_ctx = origin.ctx; + + return origin.Valid(); + } + +private: + + struct DeclOrigin + { + DeclOrigin () : + ctx(NULL), + decl(NULL) + { + } + + DeclOrigin (clang::ASTContext *_ctx, + clang::Decl *_decl) : + ctx(_ctx), + decl(_decl) + { + } + + DeclOrigin (const DeclOrigin &rhs) + { + ctx = rhs.ctx; + decl = rhs.decl; + } + + bool + Valid () + { + return (ctx != NULL || decl != NULL); + } + + clang::ASTContext *ctx; + clang::Decl *decl; + }; + + typedef std::map<const clang::Decl *, DeclOrigin> OriginMap; + + class Minion : public clang::ASTImporter + { + public: + Minion (ClangASTImporter &master, + clang::ASTContext *source_ctx, + bool minimal) : + clang::ASTImporter(*master.m_target_ctx, + master.m_file_manager, + *source_ctx, + master.m_file_manager, + minimal), + m_master(master), + m_source_ctx(source_ctx) + { + } + + clang::Decl *Imported (clang::Decl *from, clang::Decl *to) + { + m_master.m_origins[to] = DeclOrigin (m_source_ctx, from); + + return clang::ASTImporter::Imported(from, to); + } + + ClangASTImporter &m_master; + clang::ASTContext *m_source_ctx; + }; + + typedef lldb::SharedPtr<Minion>::Type MinionSP; + typedef std::map<clang::ASTContext *, MinionSP> MinionMap; + + MinionSP + GetMinion (clang::ASTContext *source_ctx, bool minimal) + { + MinionMap *minions; + + if (minimal) + minions = &m_minimal_minions; + else + minions = &m_minions; + + if (minions->find(source_ctx) == minions->end()) + (*minions)[source_ctx] = MinionSP(new Minion(*this, source_ctx, minimal)); + + return (*minions)[source_ctx]; + } + + DeclOrigin + GetDeclOrigin (const clang::Decl *decl) + { + OriginMap::iterator iter = m_origins.find(decl); + + if (iter != m_origins.end()) + return iter->second; + else + return DeclOrigin(); + } + + clang::FileManager m_file_manager; + clang::ASTContext *m_target_ctx; + MinionMap m_minions; + MinionMap m_minimal_minions; + OriginMap m_origins; +}; + +} + +#endif
\ No newline at end of file diff --git a/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h b/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h index 9137d1ed876..8c4fb4d16a6 100644 --- a/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h +++ b/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h @@ -58,17 +58,19 @@ public: typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *); typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton, clang::ObjCInterfaceDecl *); - + typedef void (*FindExternalVisibleDeclsByNameCallback)(void *baton, const clang::DeclContext *DC, clang::DeclarationName Name, llvm::SmallVectorImpl <clang::NamedDecl *> *results); ClangExternalASTSourceCallbacks (CompleteTagDeclCallback tag_decl_callback, CompleteObjCInterfaceDeclCallback objc_decl_callback, + FindExternalVisibleDeclsByNameCallback find_by_name_callback, void *callback_baton) : m_callback_tag_decl (tag_decl_callback), m_callback_objc_decl (objc_decl_callback), + m_callback_find_by_name (find_by_name_callback), m_callback_baton (callback_baton) { } - + //------------------------------------------------------------------ // clang::ExternalASTSource //------------------------------------------------------------------ @@ -140,10 +142,12 @@ public: void SetExternalSourceCallbacks (CompleteTagDeclCallback tag_decl_callback, CompleteObjCInterfaceDeclCallback objc_decl_callback, + FindExternalVisibleDeclsByNameCallback find_by_name_callback, void *callback_baton) { m_callback_tag_decl = tag_decl_callback; m_callback_objc_decl = objc_decl_callback; + m_callback_find_by_name = find_by_name_callback; m_callback_baton = callback_baton; } @@ -154,6 +158,7 @@ public: { m_callback_tag_decl = NULL; m_callback_objc_decl = NULL; + m_callback_find_by_name = NULL; } } @@ -163,6 +168,7 @@ protected: //------------------------------------------------------------------ CompleteTagDeclCallback m_callback_tag_decl; CompleteObjCInterfaceDeclCallback m_callback_objc_decl; + FindExternalVisibleDeclsByNameCallback m_callback_find_by_name; void * m_callback_baton; }; diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 309653a6f22..a79fc340bfa 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -390,6 +390,7 @@ 26F73062139D8FDB00FD51C7 /* History.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F73061139D8FDB00FD51C7 /* History.cpp */; }; 49C850771384A02F007DB519 /* ProcessDataAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 49C850761384A02F007DB519 /* ProcessDataAllocator.h */; }; 49C8507C1384A786007DB519 /* ProcessDataAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49C850781384A0CA007DB519 /* ProcessDataAllocator.cpp */; }; + 49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D8FB3513B558DE00411094 /* ClangASTImporter.cpp */; }; 4C74CB6312288704006A8171 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C74CB6212288704006A8171 /* Carbon.framework */; }; 4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */; }; 4CCA644D13B40B82003BDF98 /* ItaniumABILanguageRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA643D13B40B82003BDF98 /* ItaniumABILanguageRuntime.cpp */; }; @@ -1091,6 +1092,8 @@ 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangPersistentVariables.cpp; path = source/Expression/ClangPersistentVariables.cpp; sourceTree = "<group>"; }; 49D7072611B5AD03001AD875 /* ClangASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTSource.h; path = include/lldb/Expression/ClangASTSource.h; sourceTree = "<group>"; }; 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTSource.cpp; path = source/Expression/ClangASTSource.cpp; sourceTree = "<group>"; }; + 49D8FB3513B558DE00411094 /* ClangASTImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTImporter.cpp; path = source/Symbol/ClangASTImporter.cpp; sourceTree = "<group>"; }; + 49D8FB3713B5594900411094 /* ClangASTImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTImporter.h; path = include/lldb/Symbol/ClangASTImporter.h; sourceTree = "<group>"; }; 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRToDWARF.cpp; path = source/Expression/IRToDWARF.cpp; sourceTree = "<group>"; }; 49DA743411DE6BB2006AEF7E /* IRToDWARF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRToDWARF.h; path = include/lldb/Expression/IRToDWARF.h; sourceTree = "<group>"; }; 49E45FA911F660DC008F7B28 /* ClangASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTType.h; path = include/lldb/Symbol/ClangASTType.h; sourceTree = "<group>"; }; @@ -2001,6 +2004,8 @@ 26BC7F1310F1B8EC00F91463 /* Block.cpp */, 26BC7C5610F1B6E900F91463 /* ClangASTContext.h */, 26BC7F1410F1B8EC00F91463 /* ClangASTContext.cpp */, + 49D8FB3713B5594900411094 /* ClangASTImporter.h */, + 49D8FB3513B558DE00411094 /* ClangASTImporter.cpp */, 49E45FA911F660DC008F7B28 /* ClangASTType.h */, 49E45FAD11F660FE008F7B28 /* ClangASTType.cpp */, 26E6902E129C6BD500DDECD9 /* ClangExternalASTSourceCallbacks.h */, @@ -3233,6 +3238,7 @@ 4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */, 9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */, 9415F61813B2C0EF00A52B36 /* FormatManager.cpp in Sources */, + 49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index d91f2f1069e..a229a4a7f45 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -266,3 +266,18 @@ NameSearchContext::AddTypeDecl(void *type) } return NULL; } + +void +NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result) +{ + for (clang::NamedDecl * const *decl_iterator = result.first; + decl_iterator != result.second; + ++decl_iterator) + m_decls.push_back (*decl_iterator); +} + +void +NameSearchContext::AddNamedDecl (clang::NamedDecl *decl) +{ + m_decls.push_back (decl); +} diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index eacacaae4a7..3216b65588c 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -1656,6 +1656,69 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString log->Printf("Ignoring a query during an import"); return; } + + do + { + if (isa<TranslationUnitDecl>(context.m_decl_context)) + break; + + if (log) + log->Printf("'%s' is in something other than a translation unit", name.GetCString()); + + const Decl *context_decl = dyn_cast<Decl>(context.m_decl_context); + + if (!context_decl) + return; + + if (const NamespaceDecl *namespace_decl = dyn_cast<NamespaceDecl>(context_decl)) + { + Decl *original_decl; + ASTContext *original_ctx; + + if (log) + log->Printf("Resolving the containing context's origin..."); + + if (!m_parser_vars->GetASTImporter(context.GetASTContext())->ResolveDeclOrigin(namespace_decl, &original_decl, &original_ctx)) + break; + + if (log) + log->Printf("Casting it to a DeclContext..."); + + DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl); + + if (!original_decl_context) + break; + + if (log) + { + std::string s; + llvm::raw_string_ostream os(s); + original_decl->print(os); + os.flush(); + + log->Printf("Containing context:"); + log->Printf("%s", s.c_str()); + } + + if (!original_ctx->getExternalSource()) + break; + + DeclContextLookupConstResult original_lookup_result = original_ctx->getExternalSource()->FindExternalVisibleDeclsByName(original_decl_context, context.m_decl_name); + + NamedDecl *const *iter; + + for (iter = original_lookup_result.first; + iter != original_lookup_result.second; + ++iter) + { + clang::NamedDecl *copied_result = dyn_cast<NamedDecl>(m_parser_vars->GetASTImporter(context.GetASTContext())->CopyDecl(original_ctx, *iter)); + + if (copied_result) + context.AddNamedDecl(copied_result); + } + } + } + while (0); SymbolContextList sc_list; @@ -1721,14 +1784,6 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString else if (non_extern_symbol) AddOneFunction (context, NULL, non_extern_symbol); } - - ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name)); - if (namespace_decl) - { - clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl); - if (clang_namespace_decl) - clang_namespace_decl->setHasExternalLexicalStorage(); - } } else { @@ -1741,6 +1796,26 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString AddOneGenericVariable(context, *data_symbol); } } + + ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name)); + + if (namespace_decl) + { + 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()); + } + + clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl); + if (clang_namespace_decl) + clang_namespace_decl->setHasExternalLexicalStorage(); + } } else { @@ -1883,7 +1958,47 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString AddOneType(context, user_type, false); } } + +const clang::DeclContext * +ClangExpressionDeclMap::CompleteDeclContext (clang::ASTContext *ast_context, + const clang::DeclContext *decl_context) +{ + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + if (log) + { + const NamedDecl *named_decl = dyn_cast<NamedDecl>(decl_context); + if (named_decl) + log->Printf("Completing a '%s' DeclContext named '%s'", decl_context->getDeclKindName(), named_decl->getDeclName().getAsString().c_str()); + else + log->Printf("Completing a '%s' DeclContext", decl_context->getDeclKindName()); + } + + assert (m_parser_vars.get()); + + if (!m_parser_vars->GetASTImporter (ast_context)->CompleteDeclContext(decl_context)) + return NULL; + + if (log) + { + const Decl *decl = dyn_cast<Decl>(decl_context); + + if (decl) + { + std::string s; + llvm::raw_string_ostream os(s); + decl->print(os); + os.flush(); + + log->Printf("After:"); + log->Printf("%s", s.c_str()); + } + } + + return decl_context; +} + Value * ClangExpressionDeclMap::GetVariableValue ( @@ -2247,9 +2362,10 @@ ClangExpressionDeclMap::AddNamespace (NameSearchContext &context, const ClangNam { lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - clang::Decl *copied_decl = ClangASTContext::CopyDecl (context.GetASTContext(), - namespace_decl.GetASTContext(), - namespace_decl.GetNamespaceDecl()); + assert (m_parser_vars.get()); + + clang::Decl *copied_decl = m_parser_vars->GetASTImporter(context.GetASTContext())->CopyDecl(namespace_decl.GetASTContext(), + namespace_decl.GetNamespaceDecl()); return dyn_cast<clang::NamespaceDecl>(copied_decl); } @@ -2393,9 +2509,12 @@ ClangExpressionDeclMap::GuardedCopyType (ASTContext *dest_context, m_parser_vars->m_ignore_lookups = true; - void *ret = ClangASTContext::CopyType (dest_context, - source_context, - clang_type); + lldb_private::ClangASTImporter *importer = m_parser_vars->GetASTImporter(dest_context); + + QualType ret_qual_type = importer->CopyType (source_context, + QualType::getFromOpaquePtr(clang_type)); + + void *ret = ret_qual_type.getAsOpaquePtr(); m_parser_vars->m_ignore_lookups = false; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 57aaa011672..9a7e7fdfc3b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -218,6 +218,7 @@ SymbolFileDWARF::GetClangASTContext () llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap ( new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl, SymbolFileDWARF::CompleteObjCInterfaceDecl, + SymbolFileDWARF::FindExternalVisibleDeclsByName, this)); ast.SetExternalSource (ast_source_ap); @@ -2789,7 +2790,7 @@ SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebu Declaration decl; // TODO: fill in the decl object clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent())); if (namespace_decl) - m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl; + LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); return namespace_decl; } } @@ -2834,7 +2835,7 @@ SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWA if (namespace_decl) { //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset()); - m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl; + LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die); } return namespace_decl; } @@ -3282,8 +3283,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, // Store a forward declaration to this class type in case any // parameters in any class methods need it for the clang - // types for function prototypes. - m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); + // types for function prototypes. + LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); type_sp.reset (new Type (die->GetOffset(), this, type_name_const_str, @@ -3396,7 +3397,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, assert (enumerator_clang_type != NULL); } - m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type); + LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die); + type_sp.reset( new Type (die->GetOffset(), this, type_name_const_str, @@ -3661,7 +3663,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, // Add the decl to our DIE to decl context map assert (function_decl); - m_die_to_decl_ctx[die] = function_decl; + LinkDeclContextToDIE(function_decl, die); if (!function_param_decls.empty()) ast.SetFunctionParameters (function_decl, &function_param_decls.front(), @@ -4409,3 +4411,69 @@ SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDec symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); } +void +SymbolFileDWARF::SearchNamespace (const clang::NamespaceDecl *namespace_decl, + const char *name, + llvm::SmallVectorImpl <clang::NamedDecl *> *results) +{ + DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find((const clang::DeclContext*)namespace_decl); + + if (iter == m_decl_ctx_to_die.end()) + return; + + const DWARFDebugInfoEntry *namespace_die = iter->second; + + if (!results) + return; + + DWARFDebugInfo* info = DebugInfo(); + + std::vector<NameToDIE::Info> die_info_array; + + size_t num_matches = m_type_index.Find (name, die_info_array); + + if (num_matches) + { + for (int i = 0; + i < num_matches; + ++i) + { + DWARFCompileUnit* compile_unit = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx); + compile_unit->ExtractDIEsIfNeeded (false); + const DWARFDebugInfoEntry *die = compile_unit->GetDIEAtIndexUnchecked(die_info_array[i].die_idx); + + if (die->GetParent() != namespace_die) + continue; + + Type *matching_type = ResolveType (compile_unit, die); + + lldb::clang_type_t type = matching_type->GetClangFullType(); + clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type); + + + if (const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr())) + { + clang::TagDecl *tag_decl = tag_type->getDecl(); + results->push_back(tag_decl); + } + else if (const clang::TypedefType *typedef_type = dyn_cast<clang::TypedefType>(qual_type.getTypePtr())) + { + clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); + results->push_back(typedef_decl); + } + } + } +} + +void +SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton, + const clang::DeclContext *DC, + clang::DeclarationName Name, + llvm::SmallVectorImpl <clang::NamedDecl *> *results) +{ + SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; + + const clang::NamespaceDecl *DC_namespace = llvm::dyn_cast<clang::NamespaceDecl>(DC); + + symbol_file_dwarf->SearchNamespace (DC_namespace, Name.getAsString().c_str(), results); +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index f3c36c734e3..d3b309cfc9e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -18,6 +18,7 @@ #include <vector> // Other libraries and framework includes +#include "clang/AST/ExternalASTSource.h" #include "llvm/ADT/DenseMap.h" #include "lldb/Core/ClangForward.h" @@ -127,6 +128,12 @@ public: static void CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *); + + static void + FindExternalVisibleDeclsByName (void *baton, + const clang::DeclContext *DC, + clang::DeclarationName Name, + llvm::SmallVectorImpl <clang::NamedDecl *> *results); //------------------------------------------------------------------ // PluginInterface protocol @@ -180,6 +187,11 @@ public: clang::DeclContext * GetClangDeclContextForDIEOffset (dw_offset_t die_offset); + + void + SearchNamespace (const clang::NamespaceDecl *namespace_decl, + const char *name, + llvm::SmallVectorImpl <clang::NamedDecl *> *results); lldb_private::Flags& GetFlags () @@ -328,6 +340,13 @@ protected: UniqueDWARFASTTypeMap & GetUniqueDWARFASTTypeMap (); + void LinkDeclContextToDIE (clang::DeclContext *decl_ctx, + const DWARFDebugInfoEntry *die) + { + m_die_to_decl_ctx[die] = decl_ctx; + m_decl_ctx_to_die[decl_ctx] = die; + } + SymbolFileDWARFDebugMap * m_debug_map_symfile; clang::TranslationUnitDecl * m_clang_tu_decl; lldb_private::Flags m_flags; @@ -360,11 +379,13 @@ protected: std::auto_ptr<DWARFDebugRanges> m_ranges; UniqueDWARFASTTypeMap m_unique_ast_type_map; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap; + typedef llvm::DenseMap<const clang::DeclContext *, const DWARFDebugInfoEntry *> DeclContextToDIEMap; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::clang_type_t> DIEToClangType; typedef llvm::DenseMap<lldb::clang_type_t, const DWARFDebugInfoEntry *> ClangTypeToDIE; DIEToDeclContextMap m_die_to_decl_ctx; + DeclContextToDIEMap m_decl_ctx_to_die; DIEToTypePtr m_die_to_type; DIEToVariableSP m_die_to_variable_sp; DIEToClangType m_forward_decl_die_to_clang_type; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 2c9a7c39c4a..b6480cc9ac9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -81,6 +81,7 @@ SymbolFileDWARFDebugMap::InitializeObject() llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap ( new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl, SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl, + NULL, this)); GetClangASTContext().SetExternalSource (ast_source_ap); diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index add42fc7b41..b692ae507c5 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -4644,3 +4644,45 @@ ClangASTContext::GetCompleteType (clang_type_t clang_type) return ClangASTContext::GetCompleteType (getASTContext(), clang_type); } +bool +ClangASTContext::GetCompleteDecl (clang::ASTContext *ast, + clang::Decl *decl) +{ + if (!decl) + return false; + + ExternalASTSource *ast_source = ast->getExternalSource(); + + if (!ast_source) + return false; + + if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl)) + { + if (tag_decl->getDefinition()) + return true; + + if (!tag_decl->hasExternalLexicalStorage()) + return false; + + ast_source->CompleteType(tag_decl); + + return !tag_decl->getTypeForDecl()->isIncompleteType(); + } + else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl)) + { + if (!objc_interface_decl->isForwardDecl()) + return true; + + if (!objc_interface_decl->hasExternalLexicalStorage()) + return false; + + ast_source->CompleteType(objc_interface_decl); + + return !objc_interface_decl->isForwardDecl(); + } + else + { + return false; + } +} + diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp new file mode 100644 index 00000000000..84a765a1f35 --- /dev/null +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -0,0 +1,61 @@ +//===-- ClangASTImporter.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/Decl.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangASTImporter.h" + +using namespace lldb_private; +using namespace clang; + +clang::QualType +ClangASTImporter::CopyType (clang::ASTContext *src_ast, + clang::QualType type) +{ + MinionSP minion = GetMinion(src_ast, false); + + return minion->Import(type); +} + +clang::Decl * +ClangASTImporter::CopyDecl (clang::ASTContext *src_ast, + clang::Decl *decl) +{ + MinionSP minion; + + if (isa<clang::NamespaceDecl>(decl)) + minion = GetMinion(src_ast, true); + else + minion = GetMinion(src_ast, false); + + return minion->Import(decl); +} + +const clang::DeclContext * +ClangASTImporter::CompleteDeclContext (const clang::DeclContext *decl_context) +{ + const Decl *context_decl = dyn_cast<Decl>(decl_context); + + if (!context_decl) + return NULL; + + DeclOrigin context_decl_origin = GetDeclOrigin(context_decl); + + if (!context_decl_origin.Valid()) + return NULL; + + if (!ClangASTContext::GetCompleteDecl(context_decl_origin.ctx, context_decl_origin.decl)) + return NULL; + + MinionSP minion = GetMinion(context_decl_origin.ctx, false); + + minion->ImportDefinition(context_decl_origin.decl); + + return decl_context; +} diff --git a/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp b/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp index c79aefca53e..5b7b48fa901 100644 --- a/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp +++ b/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp @@ -52,6 +52,17 @@ ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName clang::DeclarationName clang_decl_name ) { + if (m_callback_find_by_name) + { + llvm::SmallVector <clang::NamedDecl *, 3> results; + + m_callback_find_by_name (m_callback_baton, decl_ctx, clang_decl_name, &results); + + DeclContextLookupResult lookup_result (SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results)); + + return lookup_result; + } + std::string decl_name (clang_decl_name.getAsString()); switch (clang_decl_name.getNameKind()) { |