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;
};
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);
@ -150,61 +163,78 @@ private:
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;
clang::ASTContext *src;
MinionSpec (clang::ASTContext *_dst,
clang::ASTContext *_src) :
dst(_dst),
src(_src)
ASTContextMetadata(clang::ASTContext *dst_ctx) :
m_dst_ctx (dst_ctx),
m_minions (),
m_origins (),
m_namespace_maps (),
m_map_completer (NULL)
{
}
bool operator<(const MinionSpec &rhs) const
{
if (dst < rhs.dst)
return true;
if (dst == rhs.dst && src < rhs.src)
return true;
return false;
}
clang::ASTContext *m_dst_ctx;
MinionMap m_minions;
OriginMap m_origins;
NamespaceMetaMap m_namespace_maps;
NamespaceMapCompleter *m_map_completer;
};
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
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())
m_minions[spec] = MinionSP(new Minion(*this, target_ctx, source_ctx));
MinionMap &minions = context_md->m_minions;
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
GetDeclOrigin (const clang::Decl *decl)
{
OriginMap::iterator iter = m_origins.find(decl);
GetDeclOrigin (const clang::Decl *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;
MinionMap m_minions;
OriginMap m_origins;
};
}

View File

@ -113,19 +113,40 @@ ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface
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
ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl,
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::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;
else
return NamespaceMapSP();
@ -134,6 +155,8 @@ ClangASTImporter::GetNamespaceMap(const clang::NamespaceDecl *decl)
void
ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
{
ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
const DeclContext *parent_context = decl->getDeclContext();
const NamespaceDecl *parent_namespace = dyn_cast<NamespaceDecl>(parent_context);
NamespaceMapSP parent_map;
@ -145,11 +168,11 @@ ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
new_map.reset(new NamespaceMap);
if (m_map_completer)
if (context_md->m_map_completer)
{
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);
@ -158,13 +181,7 @@ ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
void
ClangASTImporter::PurgeMaps (clang::ASTContext *dst_ast)
{
for (MinionMap::iterator i = m_minions.begin(); i != m_minions.end(); )
{
if ((*i).first.dst == dst_ast)
m_minions.erase(i++);
else
++i;
}
m_metadata_map.erase(dst_ast);
}
ClangASTImporter::NamespaceMapCompleter::~NamespaceMapCompleter ()
@ -177,7 +194,9 @@ clang::Decl
{
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))
{