[Lldb-commits] [lldb] r178410 - Fixed the way ClangASTImporter deports types from
Sean Callanan
scallanan at apple.com
Fri Mar 29 19:31:21 PDT 2013
Author: spyffe
Date: Fri Mar 29 21:31:21 2013
New Revision: 178410
URL: http://llvm.org/viewvc/llvm-project?rev=178410&view=rev
Log:
Fixed the way ClangASTImporter deports types from
ASTContexts that will not stay around. Before, we
did this in a very half-hearted way. Now we maintain
work queues of all Decls that need to be completed
before the source ASTContext can go away; we then
expunge their origins completely.
<rdar://problem/13511875>
Modified:
lldb/trunk/include/lldb/Symbol/ClangASTImporter.h
lldb/trunk/source/Symbol/ClangASTImporter.cpp
Modified: lldb/trunk/include/lldb/Symbol/ClangASTImporter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTImporter.h?rev=178410&r1=178409&r2=178410&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTImporter.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTImporter.h Fri Mar 29 21:31:21 2013
@@ -11,6 +11,7 @@
#define liblldb_ClangASTImporter_h_
#include <map>
+#include <set>
#include "lldb/lldb-types.h"
@@ -250,17 +251,38 @@ private:
*source_ctx,
master.m_file_manager,
true /*minimal*/),
+ m_decls_to_deport(NULL),
+ m_decls_already_deported(NULL),
m_master(master),
m_source_ctx(source_ctx)
{
}
+ // A call to "InitDeportWorkQueues" puts the minion into deport mode.
+ // In deport mode, every copied Decl that could require completion is
+ // recorded and placed into the decls_to_deport set.
+ //
+ // A call to "ExecuteDeportWorkQueues" completes all the Decls that
+ // are in decls_to_deport, adding any Decls it sees along the way that
+ // it hasn't already deported. It proceeds until decls_to_deport is
+ // empty.
+ //
+ // These calls must be paired. Leaving a minion in deport mode or
+ // trying to start deport minion with a new pair of queues will result
+ // in an assertion failure.
+
+ void InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
+ std::set<clang::NamedDecl *> *decls_already_deported);
+ void ExecuteDeportWorkQueues ();
+
void ImportDefinitionTo (clang::Decl *to, clang::Decl *from);
clang::Decl *Imported (clang::Decl *from, clang::Decl *to);
- ClangASTImporter &m_master;
- clang::ASTContext *m_source_ctx;
+ std::set<clang::NamedDecl *> *m_decls_to_deport;
+ std::set<clang::NamedDecl *> *m_decls_already_deported;
+ ClangASTImporter &m_master;
+ clang::ASTContext *m_source_ctx;
};
typedef STD_SHARED_PTR(Minion) MinionSP;
Modified: lldb/trunk/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTImporter.cpp?rev=178410&r1=178409&r2=178410&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTImporter.cpp Fri Mar 29 21:31:21 2013
@@ -113,37 +113,27 @@ lldb::clang_type_t
ClangASTImporter::DeportType (clang::ASTContext *dst_ctx,
clang::ASTContext *src_ctx,
lldb::clang_type_t type)
-{
- lldb::clang_type_t result = CopyType(dst_ctx, src_ctx, type);
+{
+ MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
- if (!result)
+ if (!minion_sp)
return NULL;
- QualType qual_type = QualType::getFromOpaquePtr(type);
+ std::set<NamedDecl *> decls_to_deport;
+ std::set<NamedDecl *> decls_already_deported;
- if (const TagType *tag_type = qual_type->getAs<TagType>())
- {
- TagDecl *tag_decl = tag_type->getDecl();
- const TagType *result_tag_type = QualType::getFromOpaquePtr(result)->getAs<TagType>();
- TagDecl *result_tag_decl = result_tag_type->getDecl();
-
- if (tag_decl)
- {
- MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
-
- minion_sp->ImportDefinitionTo(result_tag_decl, tag_decl);
-
- ASTContextMetadataSP to_context_md = GetContextMetadata(dst_ctx);
-
- OriginMap::iterator oi = to_context_md->m_origins.find(result_tag_decl);
-
- if (oi != to_context_md->m_origins.end() &&
- oi->second.ctx == src_ctx)
- to_context_md->m_origins.erase(oi);
- }
- }
+ minion_sp->InitDeportWorkQueues(&decls_to_deport,
+ &decls_already_deported);
+
+ lldb::clang_type_t result = CopyType(dst_ctx, src_ctx, type);
+
+ minion_sp->ExecuteDeportWorkQueues();
+
+ if (!result)
+ return NULL;
return result;
+
}
clang::Decl *
@@ -160,31 +150,23 @@ ClangASTImporter::DeportDecl (clang::AST
src_ctx,
dst_ctx);
- clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
+ MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
- if (!result)
+ if (!minion_sp)
return NULL;
-
- ClangASTContext::GetCompleteDecl (src_ctx, decl);
-
- MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
- if (minion_sp && isa<TagDecl>(decl))
- minion_sp->ImportDefinitionTo(result, decl);
+ std::set<NamedDecl *> decls_to_deport;
+ std::set<NamedDecl *> decls_already_deported;
- ASTContextMetadataSP to_context_md = GetContextMetadata(dst_ctx);
-
- OriginMap::iterator oi = to_context_md->m_origins.find(result);
+ minion_sp->InitDeportWorkQueues(&decls_to_deport,
+ &decls_already_deported);
- if (oi != to_context_md->m_origins.end() &&
- oi->second.ctx == src_ctx)
- to_context_md->m_origins.erase(oi);
+ clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
+
+ minion_sp->ExecuteDeportWorkQueues();
- if (TagDecl *result_tag_decl = dyn_cast<TagDecl>(result))
- {
- result_tag_decl->setHasExternalLexicalStorage(false);
- result_tag_decl->setHasExternalVisibleStorage(false);
- }
+ if (!result)
+ return NULL;
if (log)
log->Printf(" [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
@@ -469,6 +451,63 @@ ClangASTImporter::MapCompleter::~MapComp
}
void
+ClangASTImporter::Minion::InitDeportWorkQueues (std::set<clang::NamedDecl *> *decls_to_deport,
+ std::set<clang::NamedDecl *> *decls_already_deported)
+{
+ assert(!m_decls_to_deport); // TODO make debug only
+ assert(!m_decls_already_deported);
+
+ m_decls_to_deport = decls_to_deport;
+ m_decls_already_deported = decls_already_deported;
+}
+
+void
+ClangASTImporter::Minion::ExecuteDeportWorkQueues ()
+{
+ assert(m_decls_to_deport); // TODO make debug only
+ assert(m_decls_already_deported);
+
+ ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&getToContext());
+
+ while (!m_decls_to_deport->empty())
+ {
+ NamedDecl *decl = *m_decls_to_deport->begin();
+
+ m_decls_already_deported->insert(decl);
+ m_decls_to_deport->erase(decl);
+
+ DeclOrigin &origin = to_context_md->m_origins[decl];
+
+ assert (origin.ctx == m_source_ctx); // otherwise we should never have added this
+ // because it doesn't need to be deported
+
+ Decl *original_decl = to_context_md->m_origins[decl].decl;
+
+ ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl);
+
+ if (TagDecl *tag_decl = dyn_cast<TagDecl>(decl))
+ {
+ if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
+ if (original_tag_decl->isCompleteDefinition())
+ ImportDefinitionTo(tag_decl, original_tag_decl);
+
+ tag_decl->setHasExternalLexicalStorage(false);
+ tag_decl->setHasExternalVisibleStorage(false);
+ }
+ else if (ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl))
+ {
+ interface_decl->setHasExternalLexicalStorage(false);
+ interface_decl->setHasExternalVisibleStorage(false);
+ }
+
+ to_context_md->m_origins.erase(decl);
+ }
+
+ m_decls_to_deport = NULL;
+ m_decls_already_deported = NULL;
+}
+
+void
ClangASTImporter::Minion::ImportDefinitionTo (clang::Decl *to, clang::Decl *from)
{
ASTImporter::Imported(from, to);
@@ -594,6 +633,17 @@ clang::Decl
}
else
{
+ if (m_decls_to_deport && m_decls_already_deported)
+ {
+ if (isa<TagDecl>(to) || isa<ObjCInterfaceDecl>(to))
+ {
+ NamedDecl *to_named_decl = dyn_cast<NamedDecl>(to);
+
+ if (!m_decls_already_deported->count(to_named_decl))
+ m_decls_to_deport->insert(to_named_decl);
+ }
+
+ }
to_context_md->m_origins[to] = DeclOrigin(m_source_ctx, from);
if (log)
@@ -630,15 +680,13 @@ clang::Decl
to_tag_decl->setHasExternalLexicalStorage();
to_tag_decl->setMustBuildLookupTable();
-
+
if (log)
log->Printf(" [ClangASTImporter] To is a TagDecl - attributes %s%s [%s->%s]",
(to_tag_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
(to_tag_decl->hasExternalVisibleStorage() ? " Visible" : ""),
(from_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"),
(to_tag_decl->isCompleteDefinition() ? "complete" : "incomplete"));
-
- to_tag_decl = NULL;
}
if (isa<NamespaceDecl>(from))
@@ -656,7 +704,7 @@ clang::Decl
to_interface_decl->setHasExternalLexicalStorage();
to_interface_decl->setHasExternalVisibleStorage();
-
+
/*to_interface_decl->setExternallyCompleted();*/
if (log)
More information about the lldb-commits
mailing list