forked from OSchip/llvm-project
I made the ClangASTImporter owned by the target
rather than individually on behalf of each ASTContext. This allows the ASTImporter to know about all containers of types, which will let it be smarter about forwarding information about type origins. That means that the following sequence of steps will be possible (after a few more changes): - Import a type from a Module's ASTContext into an expression parser ASTContext, tracking its origin information -- this works now. - Because the result of the expression uses that type, import it from the expression parser ASTContext into the Target's scratch AST context, forwarding the origin information -- this needs to be added. - For a later expression that uses the result, import the type from the Target's scratch AST context, still forwarding origin information -- this also needs to be added. - Use the intact origin information to complete the type as needed -- this works now if the origin information is present. To this end, I made the following changes: - ASTImporter top-level copy functions now require both a source and a destination AST context parameter. - The ASTImporter now knows how to purge records related to an ASTContext that is going away. - The Target now owns and creates the ASTImporter whenever the main executable changes or (in the absence of a main executable) on demand. llvm-svn: 144802
This commit is contained in:
parent
8855ff61cb
commit
686b2319e5
|
@ -50,6 +50,7 @@ public:
|
|||
m_ast_context (NULL),
|
||||
m_active_lookups ()
|
||||
{
|
||||
m_ast_importer = m_target->GetClangASTImporter();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -71,13 +72,6 @@ public:
|
|||
|
||||
void InstallASTContext (clang::ASTContext *ast_context)
|
||||
{
|
||||
if (!m_ast_importer.get() ||
|
||||
m_ast_importer->TargetASTContext() != ast_context)
|
||||
{
|
||||
m_ast_importer.reset(new ClangASTImporter(ast_context));
|
||||
m_ast_importer->InstallMapCompleter(*this);
|
||||
}
|
||||
|
||||
m_ast_context = ast_context;
|
||||
}
|
||||
|
||||
|
@ -329,8 +323,8 @@ protected:
|
|||
bool m_lookups_enabled;
|
||||
|
||||
const lldb::TargetSP m_target; ///< The target to use in finding variables and types.
|
||||
clang::ASTContext *m_ast_context; ///< The parser's AST context, for copying types into
|
||||
std::auto_ptr<ClangASTImporter> m_ast_importer;
|
||||
clang::ASTContext *m_ast_context; ///< The AST context requests are coming in for.
|
||||
ClangASTImporter *m_ast_importer; ///< The target's AST importer.
|
||||
std::set<const char *> m_active_lookups;
|
||||
};
|
||||
|
||||
|
|
|
@ -28,24 +28,19 @@ namespace lldb_private {
|
|||
class ClangASTImporter
|
||||
{
|
||||
public:
|
||||
ClangASTImporter (clang::ASTContext *target_ctx) :
|
||||
m_file_manager(clang::FileSystemOptions()),
|
||||
m_target_ctx(target_ctx)
|
||||
ClangASTImporter () :
|
||||
m_file_manager(clang::FileSystemOptions())
|
||||
{
|
||||
}
|
||||
|
||||
clang::ASTContext *
|
||||
TargetASTContext ()
|
||||
{
|
||||
return m_target_ctx;
|
||||
}
|
||||
|
||||
clang::QualType
|
||||
CopyType (clang::ASTContext *src_ctx,
|
||||
CopyType (clang::ASTContext *dst_ctx,
|
||||
clang::ASTContext *src_ctx,
|
||||
clang::QualType type);
|
||||
|
||||
clang::Decl *
|
||||
CopyDecl (clang::ASTContext *src_ctx,
|
||||
CopyDecl (clang::ASTContext *dst_ctx,
|
||||
clang::ASTContext *src_ctx,
|
||||
clang::Decl *decl);
|
||||
|
||||
void
|
||||
|
@ -92,6 +87,8 @@ public:
|
|||
NamespaceMapSP GetNamespaceMap (const clang::NamespaceDecl *decl);
|
||||
|
||||
void BuildNamespaceMap (const clang::NamespaceDecl *decl);
|
||||
|
||||
void PurgeMaps (clang::ASTContext *dest_ast_ctx);
|
||||
private:
|
||||
struct DeclOrigin
|
||||
{
|
||||
|
@ -130,13 +127,13 @@ private:
|
|||
{
|
||||
public:
|
||||
Minion (ClangASTImporter &master,
|
||||
clang::ASTContext *source_ctx,
|
||||
bool minimal) :
|
||||
clang::ASTImporter(*master.m_target_ctx,
|
||||
clang::ASTContext *target_ctx,
|
||||
clang::ASTContext *source_ctx) :
|
||||
clang::ASTImporter(*target_ctx,
|
||||
master.m_file_manager,
|
||||
*source_ctx,
|
||||
master.m_file_manager,
|
||||
minimal),
|
||||
true /*minimal*/),
|
||||
m_master(master),
|
||||
m_source_ctx(source_ctx)
|
||||
{
|
||||
|
@ -149,24 +146,40 @@ private:
|
|||
};
|
||||
|
||||
typedef lldb::SharedPtr<Minion>::Type MinionSP;
|
||||
typedef std::map<clang::ASTContext *, MinionSP> MinionMap;
|
||||
|
||||
struct MinionSpec
|
||||
{
|
||||
clang::ASTContext *dst;
|
||||
clang::ASTContext *src;
|
||||
|
||||
MinionSpec (clang::ASTContext *_dst,
|
||||
clang::ASTContext *_src) :
|
||||
dst(_dst),
|
||||
src(_src)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const MinionSpec &rhs) const
|
||||
{
|
||||
if (dst < rhs.dst)
|
||||
return true;
|
||||
if (dst == rhs.dst && src < rhs.src)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<MinionSpec, MinionSP> MinionMap;
|
||||
|
||||
MinionSP
|
||||
GetMinion (clang::ASTContext *source_ctx, bool minimal)
|
||||
GetMinion (clang::ASTContext *target_ctx, clang::ASTContext *source_ctx)
|
||||
{
|
||||
MinionMap *minions;
|
||||
MinionSpec spec(target_ctx, source_ctx);
|
||||
|
||||
minimal = true; // This override is temporary, while I sort out the attendant issues.
|
||||
if (m_minions.find(spec) == m_minions.end())
|
||||
m_minions[spec] = MinionSP(new Minion(*this, target_ctx, source_ctx));
|
||||
|
||||
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];
|
||||
return m_minions[spec];
|
||||
}
|
||||
|
||||
DeclOrigin
|
||||
|
@ -185,9 +198,7 @@ private:
|
|||
NamespaceMetaMap m_namespace_maps;
|
||||
NamespaceMapCompleter *m_map_completer;
|
||||
clang::FileManager m_file_manager;
|
||||
clang::ASTContext *m_target_ctx;
|
||||
MinionMap m_minions;
|
||||
MinionMap m_minimal_minions;
|
||||
OriginMap m_origins;
|
||||
};
|
||||
|
||||
|
|
|
@ -801,6 +801,9 @@ public:
|
|||
ClangASTContext *
|
||||
GetScratchClangASTContext();
|
||||
|
||||
ClangASTImporter *
|
||||
GetClangASTImporter();
|
||||
|
||||
const char *
|
||||
GetExpressionPrefixContentsAsCString ();
|
||||
|
||||
|
@ -1054,6 +1057,7 @@ protected:
|
|||
PathMappingList m_image_search_paths;
|
||||
std::auto_ptr<ClangASTContext> m_scratch_ast_context_ap;
|
||||
std::auto_ptr<ClangASTSource> m_scratch_ast_source_ap;
|
||||
std::auto_ptr<ClangASTImporter> m_ast_importer_ap;
|
||||
ClangPersistentVariables m_persistent_variables; ///< These are the persistent variables associated with this process for the expression parser.
|
||||
|
||||
SourceManager m_source_manager;
|
||||
|
|
|
@ -41,6 +41,7 @@ class BreakpointSiteList;
|
|||
class Broadcaster;
|
||||
class CPPLanguageRuntime;
|
||||
class ClangASTContext;
|
||||
class ClangASTImporter;
|
||||
class ClangASTSource;
|
||||
class ClangASTType;
|
||||
class ClangNamespaceDecl;
|
||||
|
|
|
@ -24,6 +24,7 @@ using namespace lldb_private;
|
|||
|
||||
ClangASTSource::~ClangASTSource()
|
||||
{
|
||||
m_ast_importer->PurgeMaps(m_ast_context);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -249,7 +250,7 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
|
|||
log->Printf(" FELD[%d] Adding lexical decl %s", current_id, ast_dumper.GetCString());
|
||||
}
|
||||
|
||||
Decl *copied_decl = m_ast_importer->CopyDecl(original_ctx, decl);
|
||||
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl);
|
||||
|
||||
decls.push_back(copied_decl);
|
||||
}
|
||||
|
@ -551,7 +552,7 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
|
|||
|
||||
if (found_interface_decl->getName() == interface_decl->getName())
|
||||
{
|
||||
Decl *copied_decl = m_ast_importer->CopyDecl(&method_decl->getASTContext(), method_decl);
|
||||
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
|
||||
|
||||
if (!copied_decl)
|
||||
continue;
|
||||
|
@ -610,7 +611,7 @@ ClangASTSource::FindObjCPropertyDecls (NameSearchContext &context)
|
|||
if (!property_decl)
|
||||
return;
|
||||
|
||||
Decl *copied_decl = m_ast_importer->CopyDecl(orig_ast_ctx, property_decl);
|
||||
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, orig_ast_ctx, property_decl);
|
||||
|
||||
if (!copied_decl)
|
||||
return;
|
||||
|
@ -734,7 +735,7 @@ ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::Name
|
|||
|
||||
const ClangNamespaceDecl &namespace_decl = namespace_decls->begin()->second;
|
||||
|
||||
Decl *copied_decl = m_ast_importer->CopyDecl(namespace_decl.GetASTContext(), namespace_decl.GetNamespaceDecl());
|
||||
Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, namespace_decl.GetASTContext(), namespace_decl.GetNamespaceDecl());
|
||||
|
||||
NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
|
||||
|
||||
|
@ -750,7 +751,7 @@ ClangASTSource::GuardedCopyType (ASTContext *dest_context,
|
|||
{
|
||||
SetImportInProgress(true);
|
||||
|
||||
QualType ret_qual_type = m_ast_importer->CopyType (source_context, QualType::getFromOpaquePtr(clang_type));
|
||||
QualType ret_qual_type = m_ast_importer->CopyType (m_ast_context, source_context, QualType::getFromOpaquePtr(clang_type));
|
||||
|
||||
void *ret = ret_qual_type.getAsOpaquePtr();
|
||||
|
||||
|
|
|
@ -19,10 +19,11 @@ using namespace lldb_private;
|
|||
using namespace clang;
|
||||
|
||||
clang::QualType
|
||||
ClangASTImporter::CopyType (clang::ASTContext *src_ast,
|
||||
ClangASTImporter::CopyType (clang::ASTContext *dst_ast,
|
||||
clang::ASTContext *src_ast,
|
||||
clang::QualType type)
|
||||
{
|
||||
MinionSP minion_sp (GetMinion(src_ast, false));
|
||||
MinionSP minion_sp (GetMinion(dst_ast, src_ast));
|
||||
|
||||
if (minion_sp)
|
||||
return minion_sp->Import(type);
|
||||
|
@ -31,15 +32,13 @@ ClangASTImporter::CopyType (clang::ASTContext *src_ast,
|
|||
}
|
||||
|
||||
clang::Decl *
|
||||
ClangASTImporter::CopyDecl (clang::ASTContext *src_ast,
|
||||
ClangASTImporter::CopyDecl (clang::ASTContext *dst_ast,
|
||||
clang::ASTContext *src_ast,
|
||||
clang::Decl *decl)
|
||||
{
|
||||
MinionSP minion_sp;
|
||||
|
||||
if (isa<clang::NamespaceDecl>(decl))
|
||||
minion_sp = GetMinion(src_ast, true);
|
||||
else
|
||||
minion_sp = GetMinion(src_ast, false);
|
||||
minion_sp = GetMinion(dst_ast, src_ast);
|
||||
|
||||
if (minion_sp)
|
||||
{
|
||||
|
@ -77,7 +76,7 @@ ClangASTImporter::CompleteTagDecl (clang::TagDecl *decl)
|
|||
if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
|
||||
return;
|
||||
|
||||
MinionSP minion_sp (GetMinion(decl_origin.ctx, false));
|
||||
MinionSP minion_sp (GetMinion(&decl->getASTContext(), decl_origin.ctx));
|
||||
|
||||
if (minion_sp)
|
||||
minion_sp->ImportDefinition(decl_origin.decl);
|
||||
|
@ -98,7 +97,7 @@ ClangASTImporter::CompleteObjCInterfaceDecl (clang::ObjCInterfaceDecl *interface
|
|||
if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl))
|
||||
return;
|
||||
|
||||
MinionSP minion_sp (GetMinion(decl_origin.ctx, false));
|
||||
MinionSP minion_sp (GetMinion(&interface_decl->getASTContext(), decl_origin.ctx));
|
||||
|
||||
if (minion_sp)
|
||||
minion_sp->ImportDefinition(decl_origin.decl);
|
||||
|
@ -148,6 +147,18 @@ ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl)
|
|||
RegisterNamespaceMap (decl, new_map);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
ClangASTImporter::NamespaceMapCompleter::~NamespaceMapCompleter ()
|
||||
{
|
||||
return;
|
||||
|
|
|
@ -61,6 +61,8 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat
|
|||
m_search_filter_sp (),
|
||||
m_image_search_paths (ImageSearchPathsChanged, this),
|
||||
m_scratch_ast_context_ap (NULL),
|
||||
m_scratch_ast_source_ap (NULL),
|
||||
m_ast_importer_ap (NULL),
|
||||
m_persistent_variables (),
|
||||
m_source_manager(*this),
|
||||
m_stop_hooks (),
|
||||
|
@ -173,6 +175,7 @@ Target::Destroy()
|
|||
m_image_search_paths.Clear(notify);
|
||||
m_scratch_ast_context_ap.reset();
|
||||
m_scratch_ast_source_ap.reset();
|
||||
m_ast_importer_ap.reset();
|
||||
m_persistent_variables.Clear();
|
||||
m_stop_hooks.clear();
|
||||
m_stop_hook_next_id = 0;
|
||||
|
@ -797,6 +800,7 @@ Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
|
|||
m_images.Clear();
|
||||
m_scratch_ast_context_ap.reset();
|
||||
m_scratch_ast_source_ap.reset();
|
||||
m_ast_importer_ap.reset();
|
||||
|
||||
if (executable_sp.get())
|
||||
{
|
||||
|
@ -837,6 +841,7 @@ Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
|
|||
}
|
||||
}
|
||||
|
||||
m_ast_importer_ap.reset(new ClangASTImporter());
|
||||
}
|
||||
|
||||
UpdateInstanceName();
|
||||
|
@ -865,6 +870,8 @@ Target::SetArchitecture (const ArchSpec &arch_spec)
|
|||
ModuleSP executable_sp = GetExecutableModule ();
|
||||
m_images.Clear();
|
||||
m_scratch_ast_context_ap.reset();
|
||||
m_scratch_ast_source_ap.reset();
|
||||
m_ast_importer_ap.reset();
|
||||
// Need to do something about unsetting breakpoints.
|
||||
|
||||
if (executable_sp)
|
||||
|
@ -1342,6 +1349,20 @@ Target::GetScratchClangASTContext()
|
|||
return m_scratch_ast_context_ap.get();
|
||||
}
|
||||
|
||||
ClangASTImporter *
|
||||
Target::GetClangASTImporter()
|
||||
{
|
||||
ClangASTImporter *ast_importer = m_ast_importer_ap.get();
|
||||
|
||||
if (!ast_importer)
|
||||
{
|
||||
ast_importer = new ClangASTImporter();
|
||||
m_ast_importer_ap.reset(ast_importer);
|
||||
}
|
||||
|
||||
return ast_importer;
|
||||
}
|
||||
|
||||
void
|
||||
Target::SettingsInitialize ()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue