summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Expression/ClangASTSource.h20
-rw-r--r--lldb/include/lldb/Expression/ClangExpressionDeclMap.h31
-rw-r--r--lldb/include/lldb/Symbol/ClangASTContext.h10
-rw-r--r--lldb/include/lldb/Symbol/ClangASTImporter.h164
-rw-r--r--lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h10
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj6
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp15
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp147
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp80
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h21
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp1
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp42
-rw-r--r--lldb/source/Symbol/ClangASTImporter.cpp61
-rw-r--r--lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp11
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()) {
OpenPOWER on IntegriCloud