Moved the target specific ClangASTContext initialization over into ClangASTContext::CreateInstance.

This involved changing the TypeSystem::CreateInstance to take a module or a target. This allows type systems to create an AST for modules (no expression support needed) or targets (expression support is needed) and return the correct class instance for both cases.

llvm-svn: 249747
This commit is contained in:
Greg Clayton
2015-10-08 21:04:34 +00:00
parent 1890799f0c
commit 5beec213e2
12 changed files with 248 additions and 157 deletions

View File

@@ -18,6 +18,7 @@
#include "lldb/Host/Mutex.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/PathMappingList.h"
namespace lldb_private {
@@ -1098,7 +1099,6 @@ public:
bool &match_name_after_lookup);
protected:
typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> TypeSystemMap;
//------------------------------------------------------------------
// Member Variables
//------------------------------------------------------------------

View File

@@ -71,7 +71,7 @@ public:
GetPluginNameStatic ();
static lldb::TypeSystemSP
CreateInstance (lldb::LanguageType language, const lldb_private::ArchSpec &arch);
CreateInstance (lldb::LanguageType language, Module *module, Target *target);
static void
Initialize ();
@@ -1153,6 +1153,7 @@ protected:
std::unique_ptr<clang::SelectorTable> m_selector_table_ap;
std::unique_ptr<clang::Builtin::Context> m_builtins_ap;
std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap;
std::unique_ptr<ClangASTSource> m_scratch_ast_source_ap;
CompleteTagDeclCallback m_callback_tag_decl;
CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
void * m_callback_baton;

View File

@@ -40,7 +40,7 @@ class GoASTContext : public TypeSystem
GetPluginNameStatic ();
static lldb::TypeSystemSP
CreateInstance (lldb::LanguageType language, const lldb_private::ArchSpec &arch);
CreateInstance (lldb::LanguageType language, Module *module, Target *target);
static void
Initialize ();

View File

@@ -11,10 +11,13 @@
#define liblldb_TypeSystem_h_
#include <functional>
#include <map>
#include <string>
#include "lldb/lldb-private.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Expression/Expression.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/Support/Casting.h"
@@ -71,7 +74,10 @@ public:
LLVMCastKind getKind() const { return m_kind; }
static lldb::TypeSystemSP
CreateInstance (lldb::LanguageType language, const lldb_private::ArchSpec &arch);
CreateInstance (lldb::LanguageType language, Module *module);
static lldb::TypeSystemSP
CreateInstance (lldb::LanguageType language, Target *target);
//----------------------------------------------------------------------
// Constructors and Destructors
@@ -521,7 +527,34 @@ protected:
SymbolFile *m_sym_file;
};
class TypeSystemMap
{
public:
TypeSystemMap ();
~TypeSystemMap();
void
Clear ();
// Iterate through all of the type systems that are created. Return true
// from callback to keep iterating, false to stop iterating.
void
ForEach (std::function <bool(TypeSystem *)> const &callback);
TypeSystem *
GetTypeSystemForLanguage (lldb::LanguageType language, Module *module, bool can_create);
TypeSystem *
GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create);
protected:
typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> collection;
mutable Mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments.
collection m_map;
};
} // namespace lldb_private
#endif // #ifndef liblldb_TypeSystem_h_

View File

@@ -25,6 +25,7 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Expression/Expression.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/PathMappingList.h"
#include "lldb/Target/ProcessLaunchInfo.h"
@@ -1504,10 +1505,7 @@ public:
lldb::SearchFilterSP
GetSearchFilterForModuleAndCUList (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles);
protected:
ClangASTContext *
GetScratchClangASTContextImpl(Error *error);
protected:
//------------------------------------------------------------------
// Member variables.
//------------------------------------------------------------------
@@ -1528,11 +1526,8 @@ protected:
lldb::ProcessSP m_process_sp;
lldb::SearchFilterSP m_search_filter_sp;
PathMappingList m_image_search_paths;
typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> TypeSystemMap;
TypeSystemMap m_scratch_type_system_map;
lldb::ClangASTSourceUP m_scratch_ast_source_ap;
lldb::ClangASTImporterUP m_ast_importer_ap;
lldb::ClangModulesDeclVendorUP m_clang_modules_decl_vendor_ap;

View File

@@ -311,7 +311,6 @@ namespace lldb {
typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
typedef std::unique_ptr<lldb_private::ClangASTContext> ClangASTContextUP;
typedef std::unique_ptr<lldb_private::ClangASTImporter> ClangASTImporterUP;
typedef std::unique_ptr<lldb_private::ClangASTSource> ClangASTSourceUP;
typedef std::unique_ptr<lldb_private::ClangModulesDeclVendor> ClangModulesDeclVendorUP;
typedef std::unique_ptr<lldb_private::ClangPersistentVariables> ClangPersistentVariablesUP;
typedef std::shared_ptr<lldb_private::UserExpression> UserExpressionSP;

View File

@@ -46,7 +46,7 @@ namespace lldb_private
typedef lldb::MemoryHistorySP (*MemoryHistoryCreateInstance) (const lldb::ProcessSP &process_sp);
typedef lldb::InstrumentationRuntimeType (*InstrumentationRuntimeGetType) ();
typedef lldb::InstrumentationRuntimeSP (*InstrumentationRuntimeCreateInstance) (const lldb::ProcessSP &process_sp);
typedef lldb::TypeSystemSP (*TypeSystemCreateInstance) (lldb::LanguageType language, const lldb_private::ArchSpec &arch);
typedef lldb::TypeSystemSP (*TypeSystemCreateInstance) (lldb::LanguageType language, Module *module, Target *target);
typedef int (*ComparisonFunction)(const void *, const void *);
typedef void (*DebuggerInitializeCallback)(Debugger &debugger);

View File

@@ -419,26 +419,7 @@ Module::GetUUID()
TypeSystem *
Module::GetTypeSystemForLanguage (LanguageType language)
{
Mutex::Locker locker (m_mutex);
TypeSystemMap::iterator pos = m_type_system_map.find(language);
if (pos != m_type_system_map.end())
return pos->second.get();
for (const auto &pair : m_type_system_map)
{
if (pair.second && pair.second->SupportsLanguage(language))
{
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
m_type_system_map[language] = pair.second;
return pair.second.get();
}
}
// Cache even if we get a shared pointer that contains null type system back
lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, GetArchitecture());
m_type_system_map[language] = type_system_sp;
return type_system_sp.get();
return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
}
void

View File

@@ -367,36 +367,59 @@ ClangASTContext::GetPluginVersion()
}
lldb::TypeSystemSP
ClangASTContext::CreateInstance (lldb::LanguageType language, const lldb_private::ArchSpec &arch)
ClangASTContext::CreateInstance (lldb::LanguageType language, Module *module, Target *target)
{
if (ClangASTContextSupportsLanguage(language))
{
std::shared_ptr<ClangASTContext> ast_sp(new ClangASTContext);
if (ast_sp)
ArchSpec arch;
if (module)
arch = module->GetArchitecture();
else if (target)
arch = target->GetArchitecture();
if (arch.IsValid())
{
if (arch.IsValid())
ArchSpec fixed_arch = arch;
// LLVM wants this to be set to iOS or MacOSX; if we're working on
// a bare-boards type image, change the triple for llvm's benefit.
if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple &&
fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS)
{
ArchSpec fixed_arch = arch;
// LLVM wants this to be set to iOS or MacOSX; if we're working on
// a bare-boards type image, change the triple for llvm's benefit.
if (fixed_arch.GetTriple().getVendor() == llvm::Triple::Apple &&
fixed_arch.GetTriple().getOS() == llvm::Triple::UnknownOS)
if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
fixed_arch.GetTriple().getArch() == llvm::Triple::thumb)
{
if (fixed_arch.GetTriple().getArch() == llvm::Triple::arm ||
fixed_arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
fixed_arch.GetTriple().getArch() == llvm::Triple::thumb)
{
fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
}
else
{
fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX);
}
fixed_arch.GetTriple().setOS(llvm::Triple::IOS);
}
else
{
fixed_arch.GetTriple().setOS(llvm::Triple::MacOSX);
}
}
if (module)
{
std::shared_ptr<ClangASTContext> ast_sp(new ClangASTContext);
if (ast_sp)
{
ast_sp->SetArchitecture (fixed_arch);
}
return ast_sp;
}
else if (target)
{
std::shared_ptr<ClangASTContextForExpressions> ast_sp(new ClangASTContextForExpressions(*target));
if (ast_sp)
{
ast_sp->SetArchitecture(fixed_arch);
ast_sp->m_scratch_ast_source_ap.reset (new ClangASTSource(target->shared_from_this()));
ast_sp->m_scratch_ast_source_ap->InstallASTContext(ast_sp->getASTContext());
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(ast_sp->m_scratch_ast_source_ap->CreateProxy());
ast_sp->SetExternalSource(proxy_ast_source);
return ast_sp;
}
ast_sp->SetArchitecture (fixed_arch);
}
}
return ast_sp;
}
return lldb::TypeSystemSP();
}

View File

@@ -22,6 +22,7 @@
#include "lldb/Symbol/GoASTContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserGo.h"
@@ -321,10 +322,16 @@ GoASTContext::GetPluginVersion()
}
lldb::TypeSystemSP
GoASTContext::CreateInstance (lldb::LanguageType language, const lldb_private::ArchSpec &arch)
GoASTContext::CreateInstance (lldb::LanguageType language, Module *module, Target *target)
{
if (language == eLanguageTypeGo)
{
ArchSpec arch;
if (module)
arch = module->GetArchitecture();
else if (target)
arch = target->GetArchitecture();
if (arch.IsValid())
{
std::shared_ptr<GoASTContext> go_ast_sp(new GoASTContext);

View File

@@ -8,6 +8,8 @@
#include "lldb/Symbol/TypeSystem.h"
#include <set>
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/CompilerType.h"
@@ -24,13 +26,28 @@ TypeSystem::~TypeSystem()
}
lldb::TypeSystemSP
TypeSystem::CreateInstance (lldb::LanguageType language, const lldb_private::ArchSpec &arch)
TypeSystem::CreateInstance (lldb::LanguageType language, Module *module)
{
uint32_t i = 0;
TypeSystemCreateInstance create_callback;
while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex (i++)) != nullptr)
{
lldb::TypeSystemSP type_system_sp = create_callback(language, arch);
lldb::TypeSystemSP type_system_sp = create_callback(language, module, nullptr);
if (type_system_sp)
return type_system_sp;
}
return lldb::TypeSystemSP();
}
lldb::TypeSystemSP
TypeSystem::CreateInstance (lldb::LanguageType language, Target *target)
{
uint32_t i = 0;
TypeSystemCreateInstance create_callback;
while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex (i++)) != nullptr)
{
lldb::TypeSystemSP type_system_sp = create_callback(language, nullptr, target);
if (type_system_sp)
return type_system_sp;
}
@@ -91,3 +108,98 @@ TypeSystem::ShouldPrintAsOneLiner (void* type)
{
return eLazyBoolCalculate;
}
#pragma mark TypeSystemMap
TypeSystemMap::TypeSystemMap() :
m_mutex (),
m_map ()
{
}
TypeSystemMap::~TypeSystemMap()
{
}
void
TypeSystemMap::Clear ()
{
Mutex::Locker locker (m_mutex);
m_map.clear();
}
void
TypeSystemMap::ForEach (std::function <bool(TypeSystem *)> const &callback)
{
Mutex::Locker locker (m_mutex);
// Use a std::set so we only call the callback once for each unique
// TypeSystem instance
std::set<TypeSystem *> visited;
for (auto pair : m_map)
{
TypeSystem *type_system = pair.second.get();
if (type_system && !visited.count(type_system))
{
visited.insert(type_system);
if (callback (type_system) == false)
break;
}
}
}
TypeSystem *
TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Module *module, bool can_create)
{
Mutex::Locker locker (m_mutex);
collection::iterator pos = m_map.find(language);
if (pos != m_map.end())
return pos->second.get();
for (const auto &pair : m_map)
{
if (pair.second && pair.second->SupportsLanguage(language))
{
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
m_map[language] = pair.second;
return pair.second.get();
}
}
if (!can_create)
return nullptr;
// Cache even if we get a shared pointer that contains null type system back
lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, module);
m_map[language] = type_system_sp;
return type_system_sp.get();
}
TypeSystem *
TypeSystemMap::GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create)
{
Mutex::Locker locker (m_mutex);
collection::iterator pos = m_map.find(language);
if (pos != m_map.end())
return pos->second.get();
for (const auto &pair : m_map)
{
if (pair.second && pair.second->SupportsLanguage(language))
{
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
m_map[language] = pair.second;
return pair.second.get();
}
}
if (!can_create)
return nullptr;
// Cache even if we get a shared pointer that contains null type system back
lldb::TypeSystemSP type_system_sp = TypeSystem::CreateInstance (language, target);
m_map[language] = type_system_sp;
return type_system_sp.get();
}

View File

@@ -85,7 +85,6 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::Plat
m_process_sp (),
m_search_filter_sp (),
m_image_search_paths (ImageSearchPathsChanged, this),
m_scratch_ast_source_ap (),
m_ast_importer_ap (),
m_source_manager_ap(),
m_stop_hooks (),
@@ -1122,8 +1121,7 @@ Target::ClearModules(bool delete_locations)
ModulesDidUnload (m_images, delete_locations);
m_section_load_history.Clear();
m_images.Clear();
m_scratch_type_system_map.clear();
m_scratch_ast_source_ap.reset();
m_scratch_type_system_map.Clear();
m_ast_importer_ap.reset();
}
@@ -1892,6 +1890,9 @@ Target::ImageSearchPathsChanged
TypeSystem *
Target::GetScratchTypeSystemForLanguage (Error *error, lldb::LanguageType language, bool create_on_demand)
{
if (!m_valid)
return nullptr;
if (error)
{
error->Clear();
@@ -1902,43 +1903,8 @@ Target::GetScratchTypeSystemForLanguage (Error *error, lldb::LanguageType langua
{
language = eLanguageTypeC;
}
TypeSystemMap::iterator pos = m_scratch_type_system_map.find(language);
if (pos != m_scratch_type_system_map.end())
return pos->second.get();
for (const auto &pair : m_scratch_type_system_map)
{
if (pair.second && pair.second->SupportsLanguage(language))
{
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
m_scratch_type_system_map[language] = pair.second;
return pair.second.get();
}
}
if (!create_on_demand)
return nullptr;
if (Language::LanguageIsC(language)
|| Language::LanguageIsObjC(language)
|| Language::LanguageIsCPlusPlus(language))
{
TypeSystem* ret = GetScratchClangASTContextImpl(error);
if (ret)
{
m_scratch_type_system_map[language].reset(ret);
return m_scratch_type_system_map[language].get();
}
else
{
return nullptr;
}
}
return nullptr;
return m_scratch_type_system_map.GetTypeSystemForLanguage(language, this, create_on_demand);
}
PersistentExpressionState *
@@ -2032,41 +1998,30 @@ Target::GetUtilityFunctionForLanguage (const char *text,
ClangASTContext *
Target::GetScratchClangASTContext(bool create_on_demand)
{
if (TypeSystem* type_system = GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC, create_on_demand))
if (m_valid)
{
return llvm::dyn_cast<ClangASTContext>(type_system);
}
else
{
return nullptr;
if (TypeSystem* type_system = GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC, create_on_demand))
return llvm::dyn_cast<ClangASTContext>(type_system);
}
return nullptr;
}
ClangASTContext *
Target::GetScratchClangASTContextImpl(Error *error)
{
ClangASTContextForExpressions *ast_context = new ClangASTContextForExpressions(*this);
m_scratch_ast_source_ap.reset (new ClangASTSource(shared_from_this()));
m_scratch_ast_source_ap->InstallASTContext(ast_context->getASTContext());
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(m_scratch_ast_source_ap->CreateProxy());
ast_context->SetExternalSource(proxy_ast_source);
return ast_context;
}
ClangASTImporter *
Target::GetClangASTImporter()
{
ClangASTImporter *ast_importer = m_ast_importer_ap.get();
if (!ast_importer)
if (m_valid)
{
ast_importer = new ClangASTImporter();
m_ast_importer_ap.reset(ast_importer);
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;
}
return ast_importer;
return nullptr;
}
void
@@ -2208,56 +2163,41 @@ Target::EvaluateExpression
return execution_results;
}
lldb::ExpressionVariableSP
Target::GetPersistentVariable(const ConstString &name)
{
std::set<TypeSystem *> visited;
for (const auto &pair : m_scratch_type_system_map)
lldb::ExpressionVariableSP variable_sp;
m_scratch_type_system_map.ForEach([this, name, &variable_sp](TypeSystem *type_system) -> bool
{
if (pair.second && !visited.count(pair.second.get()))
if (PersistentExpressionState *persistent_state = type_system->GetPersistentExpressionState())
{
visited.insert(pair.second.get());
if (PersistentExpressionState *persistent_state = pair.second->GetPersistentExpressionState())
{
lldb::ExpressionVariableSP variable_sp = persistent_state->GetVariable(name);
if (variable_sp)
{
return variable_sp;
}
}
variable_sp = persistent_state->GetVariable(name);
if (variable_sp)
return false; // Stop iterating the ForEach
}
}
return ExpressionVariableSP();
return true; // Keep iterating the ForEach
});
return variable_sp;
}
lldb::addr_t
Target::GetPersistentSymbol(const ConstString &name)
{
std::set<TypeSystem *> visited;
lldb::addr_t address = LLDB_INVALID_ADDRESS;
for (const auto &pair : m_scratch_type_system_map)
m_scratch_type_system_map.ForEach([this, name, &address](TypeSystem *type_system) -> bool
{
if (pair.second && !visited.count(pair.second.get()))
if (PersistentExpressionState *persistent_state = type_system->GetPersistentExpressionState())
{
visited.insert(pair.second.get());
if (PersistentExpressionState *persistent_state = pair.second->GetPersistentExpressionState())
{
lldb::addr_t address = persistent_state->LookupSymbol(name);
if (address != LLDB_INVALID_ADDRESS)
{
return address;
}
}
address = persistent_state->LookupSymbol(name);
if (address != LLDB_INVALID_ADDRESS)
return false; // Stop iterating the ForEach
}
}
return LLDB_INVALID_ADDRESS;
return true; // Keep iterating the ForEach
});
return address;
}
lldb::addr_t