Changed the ClangASTImporter to store metadata

for each AST context it knows about in a single
object.  This makes it faster to look up the
appropriate ASTImpoter for a given ASTContext
pair and also makes it much easier to delete all
metadata for a given AST context.

In the future, this fix will allow the
ClangASTImporter to propagate completion
information between the metadata for different
AST contexts as its minions move AST objects
around.

llvm-svn: 144835
This commit is contained in:
Sean Callanan 2011-11-16 21:40:57 +00:00
parent 89d14247ff
commit f487bd877f
2 changed files with 102 additions and 53 deletions

View File

@ -84,9 +84,22 @@ public:
NamespaceMapSP &parent_map) const = 0; NamespaceMapSP &parent_map) const = 0;
}; };
void InstallMapCompleter (NamespaceMapCompleter &completer) void InstallMapCompleter (clang::ASTContext *dst_ctx, NamespaceMapCompleter &completer)
{ {
m_map_completer = &completer; ASTContextMetadataSP context_md;
ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
if (context_md_iter == m_metadata_map.end())
{
context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
m_metadata_map[dst_ctx] = context_md;
}
else
{
context_md = context_md_iter->second;
}
context_md->m_map_completer = &completer;
} }
NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl); NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
@ -150,61 +163,78 @@ private:
clang::ASTContext *m_source_ctx; clang::ASTContext *m_source_ctx;
}; };
typedef lldb::SharedPtr<Minion>::Type MinionSP; typedef lldb::SharedPtr<Minion>::Type MinionSP;
struct MinionSpec typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
typedef std::map<const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
struct ASTContextMetadata
{ {
clang::ASTContext *dst; ASTContextMetadata(clang::ASTContext *dst_ctx) :
clang::ASTContext *src; m_dst_ctx (dst_ctx),
m_minions (),
MinionSpec (clang::ASTContext *_dst, m_origins (),
clang::ASTContext *_src) : m_namespace_maps (),
dst(_dst), m_map_completer (NULL)
src(_src)
{ {
} }
bool operator<(const MinionSpec &rhs) const clang::ASTContext *m_dst_ctx;
{ MinionMap m_minions;
if (dst < rhs.dst) OriginMap m_origins;
return true;
if (dst == rhs.dst && src < rhs.src) NamespaceMetaMap m_namespace_maps;
return true; NamespaceMapCompleter *m_map_completer;
return false;
}
}; };
typedef std::map<MinionSpec, MinionSP> MinionMap; typedef lldb::SharedPtr<ASTContextMetadata>::Type ASTContextMetadataSP;
typedef std::map<const clang::ASTContext *, ASTContextMetadataSP> ContextMetadataMap;
ContextMetadataMap m_metadata_map;
ASTContextMetadataSP
GetContextMetadata (clang::ASTContext *dst_ctx)
{
ContextMetadataMap::iterator context_md_iter = m_metadata_map.find(dst_ctx);
if (context_md_iter == m_metadata_map.end())
{
ASTContextMetadataSP context_md = ASTContextMetadataSP(new ASTContextMetadata(dst_ctx));
m_metadata_map[dst_ctx] = context_md;
return context_md;
}
else
{
return context_md_iter->second;
}
}
MinionSP MinionSP
GetMinion (clang::ASTContext *target_ctx, clang::ASTContext *source_ctx) GetMinion (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx)
{ {
MinionSpec spec(target_ctx, source_ctx); ASTContextMetadataSP context_md = GetContextMetadata(dst_ctx);
if (m_minions.find(spec) == m_minions.end()) MinionMap &minions = context_md->m_minions;
m_minions[spec] = MinionSP(new Minion(*this, target_ctx, source_ctx)); MinionMap::iterator minion_iter = minions.find(src_ctx);
return m_minions[spec]; if (minion_iter == minions.end())
{
MinionSP minion = MinionSP(new Minion(*this, dst_ctx, src_ctx));
minions[src_ctx] = minion;
return minion;
}
else
{
return minion_iter->second;
}
} }
DeclOrigin DeclOrigin
GetDeclOrigin (const clang::Decl *decl) GetDeclOrigin (const clang::Decl *decl);
{
OriginMap::iterator iter = m_origins.find(decl);
if (iter != m_origins.end())
return iter->second;
else
return DeclOrigin();
}
typedef std::map <const clang::NamespaceDecl *, NamespaceMapSP> NamespaceMetaMap;
NamespaceMetaMap m_namespace_maps;
NamespaceMapCompleter *m_map_completer;
clang::FileManager m_file_manager; clang::FileManager m_file_manager;
MinionMap m_minions;
OriginMap m_origins;
}; };
} }

View File

@ -113,19 +113,40 @@ ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface
return; return;
} }
ClangASTImporter::DeclOrigin
ClangASTImporter::GetDeclOrigin(const clang::Decl *decl)
{
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
OriginMap &origins = context_md->m_origins;
OriginMap::iterator iter = origins.find(decl);
if (iter != origins.end())
return iter->second;
else
return DeclOrigin();
}
void void
ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
NamespaceMapSP &namespace_map) NamespaceMapSP &namespace_map)
{ {
m_namespace_maps[decl] = namespace_map; ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
context_md->m_namespace_maps[decl] = namespace_map;
} }
ClangASTImporter::NamespaceMapSP ClangASTImporter::NamespaceMapSP
ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl) ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl)
{ {
NamespaceMetaMap::iterator iter = m_namespace_maps.find(decl); ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
NamespaceMetaMap &namespace_maps = context_md->m_namespace_maps;
if (iter != m_namespace_maps.end()) NamespaceMetaMap::iterator iter = namespace_maps.find(decl);
if (iter != namespace_maps.end())
return iter->second; return iter->second;
else else
return NamespaceMapSP(); return NamespaceMapSP();
@ -134,6 +155,8 @@ ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl)
void void
ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
{ {
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
const DeclContext *parent_context = decl->getDeclContext(); const DeclContext *parent_context = decl->getDeclContext();
const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context); const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context);
NamespaceMapSP parent_map; NamespaceMapSP parent_map;
@ -145,11 +168,11 @@ ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
new_map.reset(new NamespaceMap); new_map.reset(new NamespaceMap);
if (m_map_completer) if (context_md->m_map_completer)
{ {
std::string namespace_string = decl->getDeclName().getAsString(); std::string namespace_string = decl->getDeclName().getAsString();
m_map_completer->CompleteNamespaceMap (new_map, ConstString(namespace_string.c_str()), parent_map); context_md->m_map_completer->CompleteNamespaceMap (new_map, ConstString(namespace_string.c_str()), parent_map);
} }
RegisterNamespaceMap (decl, new_map); RegisterNamespaceMap (decl, new_map);
@ -158,13 +181,7 @@ ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
void void
ClangASTImporter::PurgeMaps (clang::ASTContext *dst_ast) ClangASTImporter::PurgeMaps (clang::ASTContext *dst_ast)
{ {
for (MinionMap::iterator i = m_minions.begin(); i != m_minions.end(); ) m_metadata_map.erase(dst_ast);
{
if ((*i).first.dst == dst_ast)
m_minions.erase(i++);
else
++i;
}
} }
ClangASTImporter::NamespaceMapCompleter::~NamespaceMapCompleter () ClangASTImporter::NamespaceMapCompleter::~NamespaceMapCompleter ()
@ -177,7 +194,9 @@ clang::Decl
{ {
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
m_master.m_origins[to] = DeclOrigin (m_source_ctx, from); ASTContextMetadataSP context_md = m_master.GetContextMetadata(&to->getASTContext());
context_md->m_origins[to] = DeclOrigin (m_source_ctx, from);
if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from)) if (TagDecl *from_tag_decl = dyn_cast<TagDecl>(from))
{ {