summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Core/EmulateInstruction.cpp26
-rw-r--r--lldb/source/Core/FileSpec.cpp103
-rw-r--r--lldb/source/Core/PluginManager.cpp209
-rw-r--r--lldb/source/Host/common/Host.cpp115
-rw-r--r--lldb/source/Host/macosx/Symbols.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp204
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h3
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp41
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h151
-rw-r--r--lldb/source/Symbol/Declaration.cpp115
-rw-r--r--lldb/source/lldb.cpp7
11 files changed, 782 insertions, 194 deletions
diff --git a/lldb/source/Core/EmulateInstruction.cpp b/lldb/source/Core/EmulateInstruction.cpp
index 3718c12d320..391fa87a9d8 100644
--- a/lldb/source/Core/EmulateInstruction.cpp
+++ b/lldb/source/Core/EmulateInstruction.cpp
@@ -10,11 +10,37 @@
#include "EmulateInstruction.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Endian.h"
using namespace lldb;
using namespace lldb_private;
+EmulateInstruction*
+EmulateInstruction::FindPlugin (const ConstString &triple, const char *plugin_name)
+{
+ EmulateInstructionCreateInstance create_callback = NULL;
+ if (plugin_name)
+ {
+ create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
+ if (create_callback)
+ {
+ std::auto_ptr<EmulateInstruction> instance_ap(create_callback(triple));
+ if (instance_ap.get())
+ return instance_ap.release();
+ }
+ }
+ else
+ {
+ for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ {
+ std::auto_ptr<EmulateInstruction> instance_ap(create_callback(triple));
+ if (instance_ap.get())
+ return instance_ap.release();
+ }
+ }
+ return NULL;
+}
EmulateInstruction::EmulateInstruction
(
diff --git a/lldb/source/Core/FileSpec.cpp b/lldb/source/Core/FileSpec.cpp
index f1850439bc1..d0749bd3554 100644
--- a/lldb/source/Core/FileSpec.cpp
+++ b/lldb/source/Core/FileSpec.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
+#include <dirent.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdlib.h>
@@ -27,6 +28,7 @@
#include "lldb/Core/DataBufferMemoryMap.h"
#include "lldb/Core/Stream.h"
#include "lldb/Host/Host.h"
+#include "lldb/Utility/CleanUp.h"
using namespace lldb;
using namespace lldb_private;
@@ -572,7 +574,7 @@ FileSpec::GetFileType () const
default:
break;
}
- return eFileTypeUknown;
+ return eFileTypeUnknown;
}
return eFileTypeInvalid;
}
@@ -805,3 +807,102 @@ FileSpec::ReadFileLines (STLStringArray &lines)
}
return lines.size();
}
+
+FileSpec::EnumerateDirectoryResult
+FileSpec::EnumerateDirectory
+(
+ const char *dir_path,
+ bool find_directories,
+ bool find_files,
+ bool find_other,
+ EnumerateDirectoryCallbackType callback,
+ void *callback_baton
+)
+{
+ if (dir_path && dir_path[0])
+ {
+ lldb_utility::CleanUp <DIR *, int> dir_path_dir (opendir(dir_path), NULL, closedir);
+ if (dir_path_dir.is_valid())
+ {
+ struct dirent* dp;
+ while ((dp = readdir(dir_path_dir.get())) != NULL)
+ {
+ // Only search directories
+ if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
+ {
+ if (dp->d_namlen == 1 && dp->d_name[0] == '.')
+ continue;
+
+ if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
+ continue;
+ }
+
+ bool call_callback = false;
+ FileSpec::FileType file_type = eFileTypeUnknown;
+
+ switch (dp->d_type)
+ {
+ default:
+ case DT_UNKNOWN: file_type = eFileTypeUnknown; call_callback = true; break;
+ case DT_FIFO: file_type = eFileTypePipe; call_callback = find_other; break;
+ case DT_CHR: file_type = eFileTypeOther; call_callback = find_other; break;
+ case DT_DIR: file_type = eFileTypeDirectory; call_callback = find_directories; break;
+ case DT_BLK: file_type = eFileTypeOther; call_callback = find_other; break;
+ case DT_REG: file_type = eFileTypeRegular; call_callback = find_files; break;
+ case DT_LNK: file_type = eFileTypeSymbolicLink; call_callback = find_other; break;
+ case DT_SOCK: file_type = eFileTypeSocket; call_callback = find_other; break;
+ case DT_WHT: file_type = eFileTypeOther; call_callback = find_other; break;
+ }
+
+ if (call_callback)
+ {
+ char child_path[PATH_MAX];
+ const int child_path_len = ::snprintf (child_path, sizeof(child_path), "%s/%s", dir_path, dp->d_name);
+ if (child_path_len < sizeof(child_path) - 1)
+ {
+ // Don't resolve the file type or path
+ FileSpec child_path_spec (child_path, false);
+
+ EnumerateDirectoryResult result = callback (callback_baton, file_type, child_path_spec);
+
+ switch (result)
+ {
+ default:
+ case eEnumerateDirectoryResultNext:
+ // Enumerate next entry in the current directory. We just
+ // exit this switch and will continue enumerating the
+ // current directory as we currently are...
+ break;
+
+ case eEnumerateDirectoryResultEnter: // Recurse into the current entry if it is a directory or symlink, or next if not
+ if (FileSpec::EnumerateDirectory (child_path,
+ find_directories,
+ find_files,
+ find_other,
+ callback,
+ callback_baton) == eEnumerateDirectoryResultQuit)
+ {
+ // The subdirectory returned Quit, which means to
+ // stop all directory enumerations at all levels.
+ return eEnumerateDirectoryResultQuit;
+ }
+ break;
+
+ case eEnumerateDirectoryResultExit: // Exit from the current directory at the current level.
+ // Exit from this directory level and tell parent to
+ // keep enumerating.
+ return eEnumerateDirectoryResultNext;
+
+ case eEnumerateDirectoryResultQuit: // Stop directory enumerations at any level
+ return eEnumerateDirectoryResultQuit;
+ }
+ }
+ }
+ }
+ }
+ }
+ // By default when exiting a directory, we tell the parent enumeration
+ // to continue enumerating.
+ return eEnumerateDirectoryResultNext;
+}
+
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index 198beae191a..9117754fa2f 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -12,6 +12,12 @@
#include <string>
#include <vector>
+#include "lldb/Core/Error.h"
+#include "lldb/Core/FileSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/Mutex.h"
+
+using namespace lldb;
using namespace lldb_private;
enum PluginAction
@@ -21,6 +27,181 @@ enum PluginAction
ePluginGetInstanceAtIndex
};
+struct PluginInfo
+{
+ void *plugin_handle;
+ void *plugin_init_callback;
+ void *plugin_term_callback;
+};
+
+typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
+
+static Mutex &
+GetPluginMapMutex ()
+{
+ static Mutex g_plugin_map_mutex (Mutex::eMutexTypeRecursive);
+ return g_plugin_map_mutex;
+}
+
+static PluginTerminateMap &
+GetPluginMap ()
+{
+ static PluginTerminateMap g_plugin_map;
+ return g_plugin_map;
+}
+
+static bool
+PluginIsLoaded (const FileSpec &plugin_file_spec)
+{
+ Mutex::Locker locker (GetPluginMapMutex ());
+ PluginTerminateMap &plugin_map = GetPluginMap ();
+ return plugin_map.find (plugin_file_spec) != plugin_map.end();
+}
+
+static void
+SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
+{
+ Mutex::Locker locker (GetPluginMapMutex ());
+ PluginTerminateMap &plugin_map = GetPluginMap ();
+ assert (plugin_map.find (plugin_file_spec) != plugin_map.end());
+ plugin_map[plugin_file_spec] = plugin_info;
+}
+
+
+static FileSpec::EnumerateDirectoryResult
+LoadPluginCallback
+(
+ void *baton,
+ FileSpec::FileType file_type,
+ const FileSpec &file_spec
+)
+{
+// PluginManager *plugin_manager = (PluginManager *)baton;
+ Error error;
+
+ // If we have a regular file, a symbolic link or unknown file type, try
+ // and process the file. We must handle unknown as sometimes the directory
+ // enumeration might be enumerating a file system that doesn't have correct
+ // file type information.
+ if (file_type == FileSpec::eFileTypeRegular ||
+ file_type == FileSpec::eFileTypeSymbolicLink ||
+ file_type == FileSpec::eFileTypeUnknown )
+ {
+ FileSpec plugin_file_spec (file_spec);
+ plugin_file_spec.ResolvePath();
+
+ if (PluginIsLoaded (plugin_file_spec))
+ return FileSpec::eEnumerateDirectoryResultNext;
+ else
+ {
+ PluginInfo plugin_info = { NULL, NULL, NULL };
+ plugin_info.plugin_handle = Host::DynamicLibraryOpen (plugin_file_spec, error);
+ if (plugin_info.plugin_handle)
+ {
+ bool success = false;
+ plugin_info.plugin_init_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginInitialize", error);
+ if (plugin_info.plugin_init_callback)
+ {
+ // Call the plug-in "bool LLDBPluginInitialize(void)" function
+ success = ((bool (*)(void))plugin_info.plugin_init_callback)();
+ }
+
+ if (success)
+ {
+ // It is ok for the "LLDBPluginTerminate" symbol to be NULL
+ plugin_info.plugin_term_callback = Host::DynamicLibraryGetSymbol (plugin_info.plugin_handle, "LLDBPluginTerminate", error);
+ }
+ else
+ {
+ // The initialize function returned FALSE which means the
+ // plug-in might not be compatible, or might be too new or
+ // too old, or might not want to run on this machine.
+ Host::DynamicLibraryClose (plugin_info.plugin_handle);
+ plugin_info.plugin_handle = NULL;
+ plugin_info.plugin_init_callback = NULL;
+ }
+
+ // Regardless of success or failure, cache the plug-in load
+ // in our plug-in info so we don't try to load it again and
+ // again.
+ SetPluginInfo (plugin_file_spec, plugin_info);
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
+ }
+ }
+
+ if (file_type == FileSpec::eFileTypeUnknown ||
+ file_type == FileSpec::eFileTypeDirectory ||
+ file_type == FileSpec::eFileTypeSymbolicLink )
+ {
+ // Try and recurse into anything that a directory or symbolic link.
+ // We must also do this for unknown as sometimes the directory enumeration
+ // might be enurating a file system that doesn't have correct file type
+ // information.
+ return FileSpec::eEnumerateDirectoryResultEnter;
+ }
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+
+void
+PluginManager::Initialize ()
+{
+ FileSpec dir_spec;
+ const bool find_directories = true;
+ const bool find_files = true;
+ const bool find_other = true;
+ char dir_path[PATH_MAX];
+ if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec))
+ {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
+ {
+ FileSpec::EnumerateDirectory (dir_path,
+ find_directories,
+ find_files,
+ find_other,
+ LoadPluginCallback,
+ NULL);
+ }
+ }
+
+ if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec))
+ {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
+ {
+ FileSpec::EnumerateDirectory (dir_path,
+ find_directories,
+ find_files,
+ find_other,
+ LoadPluginCallback,
+ NULL);
+ }
+ }
+}
+
+void
+PluginManager::Terminate ()
+{
+ Mutex::Locker locker (GetPluginMapMutex ());
+ PluginTerminateMap &plugin_map = GetPluginMap ();
+
+ PluginTerminateMap::const_iterator pos, end = plugin_map.end();
+ for (pos = plugin_map.begin(); pos != end; ++pos)
+ {
+ // Call the plug-in "void LLDBPluginTerminate (void)" function if there
+ // is one (if the symbol was not NULL).
+ if (pos->second.plugin_handle)
+ {
+ if (pos->second.plugin_term_callback)
+ ((void (*)(void))pos->second.plugin_term_callback)();
+ Host::DynamicLibraryClose (pos->second.plugin_handle);
+ }
+ }
+ plugin_map.clear();
+}
+
#pragma mark ABI
@@ -88,11 +269,11 @@ AccessABIInstances (PluginAction action, ABIInstance &instance, uint32_t index)
bool
PluginManager::RegisterPlugin
- (
- const char *name,
- const char *description,
- ABICreateInstance create_callback
- )
+(
+ const char *name,
+ const char *description,
+ ABICreateInstance create_callback
+)
{
if (create_callback)
{
@@ -458,10 +639,10 @@ AccessEmulateInstructionInstances (PluginAction action, EmulateInstructionInstan
bool
PluginManager::RegisterPlugin
(
- const char *name,
- const char *description,
- EmulateInstructionCreateInstance create_callback
- )
+ const char *name,
+ const char *description,
+ EmulateInstructionCreateInstance create_callback
+)
{
if (create_callback)
{
@@ -580,11 +761,11 @@ AccessLanguageRuntimeInstances (PluginAction action, LanguageRuntimeInstance &in
bool
PluginManager::RegisterPlugin
- (
- const char *name,
- const char *description,
- LanguageRuntimeCreateInstance create_callback
- )
+(
+ const char *name,
+ const char *description,
+ LanguageRuntimeCreateInstance create_callback
+)
{
if (create_callback)
{
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index 9bd80812658..2f4247d4101 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -387,14 +387,14 @@ Host::ThreadCreated (const char *thread_name)
void
Host::Backtrace (Stream &strm, uint32_t max_frames)
{
- // TODO: Is there a way to backtrace the current process on linux?
+ // TODO: Is there a way to backtrace the current process on linux? Other systems?
}
size_t
Host::GetEnvironment (StringList &env)
{
- // TODO: Is there a way to the host environment for this process on linux?
+ // TODO: Is there a way to the host environment for this process on linux? Other systems?
return 0;
}
@@ -642,6 +642,62 @@ Host::ResolveExecutableInBundle (FileSpec &file)
}
#endif
+void *
+Host::DynamicLibraryOpen (const FileSpec &file_spec, Error &error)
+{
+ void *dynamic_library_handle = NULL;
+ char path[PATH_MAX];
+ if (file_spec.GetPath(path, sizeof(path)))
+ {
+ dynamic_library_handle = ::dlopen (path, RTLD_LAZY | RTLD_GLOBAL | RTLD_FIRST);
+ if (dynamic_library_handle)
+ {
+ error.Clear();
+ }
+ else
+ {
+ error.SetErrorString(::dlerror());
+ }
+ }
+ else
+ {
+ error.SetErrorString("failed to extract path");
+ }
+
+ return dynamic_library_handle;
+}
+
+Error
+Host::DynamicLibraryClose (void *dynamic_library_handle)
+{
+ Error error;
+ if (dynamic_library_handle == NULL)
+ {
+ error.SetErrorString ("invalid dynamic library handle");
+ }
+ else if (::dlclose(dynamic_library_handle) != 0)
+ {
+ error.SetErrorString(::dlerror());
+ }
+ return error;
+}
+
+void *
+Host::DynamicLibraryGetSymbol (void *dynamic_library_handle, const char *symbol_name, Error &error)
+{
+ if (dynamic_library_handle == NULL)
+ {
+ error.SetErrorString ("invalid dynamic library handle");
+ return NULL;
+ }
+
+ void *symbol_addr = ::dlsym (dynamic_library_handle, symbol_name);
+ if (symbol_addr == NULL)
+ error.SetErrorString(::dlerror());
+ else
+ error.Clear();
+ return symbol_addr;
+}
bool
Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
@@ -719,7 +775,7 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
g_lldb_headers_dir.SetCString(resolved_path);
}
#else
- // TODO: Anyone know how we can determine this for linux??
+ // TODO: Anyone know how we can determine this for linux? Other systems??
g_lldb_headers_dir.SetCString ("/opt/local/include/lldb");
#endif
}
@@ -730,7 +786,7 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
case ePathTypePythonDir:
{
- // TODO: Anyone know how we can determine this for linux??
+ // TODO: Anyone know how we can determine this for linux? Other systems?
// For linux we are currently assuming the location of the lldb
// binary that contains this function is the directory that will
// contain lldb.so, lldb.py and embedded_interpreter.py...
@@ -762,6 +818,57 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
}
break;
+ case ePathTypeLLDBSystemPlugins: // System plug-ins directory
+ {
+#if defined (__APPLE__)
+ static ConstString g_lldb_system_plugin_dir;
+ if (!g_lldb_system_plugin_dir)
+ {
+ FileSpec lldb_file_spec;
+ if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec))
+ {
+ char raw_path[PATH_MAX];
+ char resolved_path[PATH_MAX];
+ lldb_file_spec.GetPath(raw_path, sizeof(raw_path));
+
+ char *framework_pos = ::strstr (raw_path, "LLDB.framework");
+ if (framework_pos)
+ {
+ framework_pos += strlen("LLDB.framework");
+ ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path));
+ }
+ FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
+ g_lldb_system_plugin_dir.SetCString(resolved_path);
+ }
+ }
+ file_spec.GetDirectory() = g_lldb_system_plugin_dir;
+ return file_spec.GetDirectory();
+#endif
+ // TODO: where would system LLDB plug-ins be located on linux? Other systems?
+ return false;
+ }
+ break;
+
+ case ePathTypeLLDBUserPlugins: // User plug-ins directory
+ {
+#if defined (__APPLE__)
+ static ConstString g_lldb_user_plugin_dir;
+ if (!g_lldb_user_plugin_dir)
+ {
+ char user_plugin_path[PATH_MAX];
+ if (FileSpec::Resolve ("~/Library/Application Support/LLDB/PlugIns",
+ user_plugin_path,
+ sizeof(user_plugin_path)))
+ {
+ g_lldb_user_plugin_dir.SetCString(user_plugin_path);
+ }
+ }
+ file_spec.GetDirectory() = g_lldb_user_plugin_dir;
+ return file_spec.GetDirectory();
+#endif
+ // TODO: where would user LLDB plug-ins be located on linux? Other systems?
+ return false;
+ }
default:
assert (!"Unhandled PathType");
break;
diff --git a/lldb/source/Host/macosx/Symbols.cpp b/lldb/source/Host/macosx/Symbols.cpp
index e91f3dd692b..87b1dbbdb99 100644
--- a/lldb/source/Host/macosx/Symbols.cpp
+++ b/lldb/source/Host/macosx/Symbols.cpp
@@ -238,7 +238,7 @@ LocateDSYMMachFileInDSYMBundle
{
::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
- lldb_utility::CleanUp <DIR *, int> dirp (opendir("containing_part"), NULL, closedir);
+ lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir);
if (dirp.is_valid())
{
dsym_fspec.GetDirectory().SetCString(path);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index bb0182c6855..c1848f6ee9f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -179,7 +179,8 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
m_namespace_index(),
m_indexed (false),
m_is_external_ast_source (false),
- m_ranges()
+ m_ranges()//,
+ //m_unique_ast_type_map ()
{
}
@@ -3168,101 +3169,134 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
}
}
- DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
-
- int tag_decl_kind = -1;
- AccessType default_accessibility = eAccessNone;
- if (tag == DW_TAG_structure_type)
- {
- tag_decl_kind = clang::TTK_Struct;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_union_type)
- {
- tag_decl_kind = clang::TTK_Union;
- default_accessibility = eAccessPublic;
- }
- else if (tag == DW_TAG_class_type)
+// UniqueDWARFASTType unique_ast_entry;
+// if (decl.IsValid())
+// {
+// if (m_unique_ast_type_map.Find (type_name_const_str,
+// die,
+// decl,
+// unique_ast_entry))
+// {
+// // We have already parsed this type or from another
+// // compile unit. GCC loves to use the "one definition
+// // rule" which can result in multiple definitions
+// // of the same class over and over in each compile
+// // unit.
+// type_sp = unique_ast_entry.m_type_sp;
+// }
+// }
+//
+// if (type_sp)
+// {
+// m_die_to_type[die] = type_sp.get();
+//
+// }
+// else
{
- tag_decl_kind = clang::TTK_Class;
- default_accessibility = eAccessPrivate;
- }
+ DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
+ int tag_decl_kind = -1;
+ AccessType default_accessibility = eAccessNone;
+ if (tag == DW_TAG_structure_type)
+ {
+ tag_decl_kind = clang::TTK_Struct;
+ default_accessibility = eAccessPublic;
+ }
+ else if (tag == DW_TAG_union_type)
+ {
+ tag_decl_kind = clang::TTK_Union;
+ default_accessibility = eAccessPublic;
+ }
+ else if (tag == DW_TAG_class_type)
+ {
+ tag_decl_kind = clang::TTK_Class;
+ default_accessibility = eAccessPrivate;
+ }
- if (is_forward_declaration)
- {
- // We have a forward declaration to a type and we need
- // to try and find a full declaration. We look in the
- // current type index just in case we have a forward
- // declaration followed by an actual declarations in the
- // DWARF. If this fails, we need to look elsewhere...
-
- type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
- if (!type_sp && m_debug_map_symfile)
+ if (is_forward_declaration)
{
- // We weren't able to find a full declaration in
- // this DWARF, see if we have a declaration anywhere
- // else...
- type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
- }
+ // We have a forward declaration to a type and we need
+ // to try and find a full declaration. We look in the
+ // current type index just in case we have a forward
+ // declaration followed by an actual declarations in the
+ // DWARF. If this fails, we need to look elsewhere...
+
+ type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
- if (type_sp)
+ if (!type_sp && m_debug_map_symfile)
+ {
+ // We weren't able to find a full declaration in
+ // this DWARF, see if we have a declaration anywhere
+ // else...
+ type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
+ }
+
+ if (type_sp)
+ {
+ // We found a real definition for this type elsewhere
+ // so lets use it and cache the fact that we found
+ // a complete type for this die
+ m_die_to_type[die] = type_sp.get();
+ return type_sp;
+ }
+ }
+ assert (tag_decl_kind != -1);
+ bool clang_type_was_created = false;
+ clang_type = m_forward_decl_die_to_clang_type.lookup (die);
+ if (clang_type == NULL)
{
- // We found a real definition for this type elsewhere
- // so lets use it and cache the fact that we found
- // a complete type for this die
- m_die_to_type[die] = type_sp.get();
- return type_sp;
+ clang_type_was_created = true;
+ clang_type = ast.CreateRecordType (type_name_cstr,
+ tag_decl_kind,
+ GetClangDeclContextForDIE (dwarf_cu, die),
+ class_language);
}
- }
- assert (tag_decl_kind != -1);
- bool clang_type_was_created = false;
- clang_type = m_forward_decl_die_to_clang_type.lookup (die);
- if (clang_type == NULL)
- {
- clang_type_was_created = true;
- clang_type = ast.CreateRecordType (type_name_cstr,
- tag_decl_kind,
- GetClangDeclContextForDIE (dwarf_cu, die),
- class_language);
- }
- // Store a forward declaration to this class type in case any
- // parameters in any class methods need it for the clang
- // types for function prototypes.
- m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
- type_sp.reset (new Type (die->GetOffset(),
- this,
- type_name_const_str,
- byte_size,
- NULL,
- LLDB_INVALID_UID,
- Type::eEncodingIsUID,
- &decl,
- clang_type,
- Type::eResolveStateForward));
-
- m_die_to_type[die] = type_sp.get();
+ // Store a forward declaration to this class type in case any
+ // parameters in any class methods need it for the clang
+ // types for function prototypes.
+ m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
+ type_sp.reset (new Type (die->GetOffset(),
+ this,
+ type_name_const_str,
+ byte_size,
+ NULL,
+ LLDB_INVALID_UID,
+ Type::eEncodingIsUID,
+ &decl,
+ clang_type,
+ Type::eResolveStateForward));
- if (die->HasChildren() == false && is_forward_declaration == false)
- {
- // No children for this struct/union/class, lets finish it
- ast.StartTagDeclarationDefinition (clang_type);
- ast.CompleteTagDeclarationDefinition (clang_type);
- }
- else if (clang_type_was_created)
- {
- // Leave this as a forward declaration until we need
- // to know the details of the type. lldb_private::Type
- // will automatically call the SymbolFile virtual function
- // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
- // When the definition needs to be defined.
- m_forward_decl_die_to_clang_type[die] = clang_type;
- m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
- ClangASTContext::SetHasExternalStorage (clang_type, true);
+ m_die_to_type[die] = type_sp.get();
+
+ // Add our type to the unique type map so we don't
+ // end up creating many copies of the same type over
+ // and over in the ASTContext for our module
+// unique_ast_entry.m_type_sp = type_sp;
+// unique_ast_entry.m_die = die;
+// unique_ast_entry.m_declaration = decl;
+// m_unique_ast_type_map.Insert (type_name_const_str,
+// unique_ast_entry);
+
+ if (die->HasChildren() == false && is_forward_declaration == false)
+ {
+ // No children for this struct/union/class, lets finish it
+ ast.StartTagDeclarationDefinition (clang_type);
+ ast.CompleteTagDeclarationDefinition (clang_type);
+ }
+ else if (clang_type_was_created)
+ {
+ // Leave this as a forward declaration until we need
+ // to know the details of the type. lldb_private::Type
+ // will automatically call the SymbolFile virtual function
+ // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
+ // When the definition needs to be defined.
+ m_forward_decl_die_to_clang_type[die] = clang_type;
+ m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
+ ClangASTContext::SetHasExternalStorage (clang_type, true);
+ }
}
-
}
break;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index d0d51b17572..b46b5c95133 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -32,6 +32,7 @@
// Project includes
#include "DWARFDefines.h"
#include "NameToDIE.h"
+//#include "UniqueDWARFASTType.h"
//----------------------------------------------------------------------
@@ -350,7 +351,7 @@ protected:
m_is_external_ast_source:1;
std::auto_ptr<DWARFDebugRanges> m_ranges;
-
+// UniqueDWARFASTTypeMap m_unique_ast_type_map;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
new file mode 100644
index 00000000000..446cfeb2ab0
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -0,0 +1,41 @@
+//===-- UniqueDWARFASTType.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UniqueDWARFASTType.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Symbol/Declaration.h"
+
+#include "DWARFDebugInfoEntry.h"
+
+bool
+UniqueDWARFASTTypeList::Find
+(
+ const DWARFDebugInfoEntry *die,
+ const lldb_private::Declaration &decl,
+ UniqueDWARFASTType &entry
+) const
+{
+ collection::const_iterator pos, end = m_collection.end();
+ for (pos = m_collection.begin(); pos != end; ++pos)
+ {
+ if (pos->m_die->Tag() == die->Tag())
+ {
+ if (pos->m_declaration == decl)
+ {
+ entry = *pos;
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
new file mode 100644
index 00000000000..53de120f7a5
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -0,0 +1,151 @@
+//===-- UniqueDWARFASTType.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_UniqueDWARFASTType_h_
+#define lldb_UniqueDWARFASTType_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/DenseMap.h"
+
+// Project includes
+#include "lldb/Symbol/Declaration.h"
+
+class DWARFCompileUnit;
+class DWARFDebugInfoEntry;
+class SymbolFileDWARF;
+
+class UniqueDWARFASTType
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ UniqueDWARFASTType () :
+ m_type_sp (),
+ m_die (NULL),
+ m_declaration ()
+ {
+ }
+
+ UniqueDWARFASTType (lldb::TypeSP &type_sp,
+ DWARFDebugInfoEntry *die,
+ const lldb_private::Declaration &decl) :
+ m_type_sp (type_sp),
+ m_die (die),
+ m_declaration (decl)
+ {
+ }
+
+ UniqueDWARFASTType (const UniqueDWARFASTType &rhs) :
+ m_type_sp (rhs.m_type_sp),
+ m_die (rhs.m_die),
+ m_declaration (rhs.m_declaration)
+ {
+ }
+
+ ~UniqueDWARFASTType()
+ {
+ }
+
+ UniqueDWARFASTType &
+ operator= (const UniqueDWARFASTType &rhs)
+ {
+ if (this != &rhs)
+ {
+ m_type_sp = rhs.m_type_sp;
+ m_die = rhs.m_die;
+ m_declaration = rhs.m_declaration;
+ }
+ return *this;
+ }
+
+ lldb::TypeSP m_type_sp;
+ const DWARFDebugInfoEntry *m_die;
+ lldb_private::Declaration m_declaration;
+};
+
+class UniqueDWARFASTTypeList
+{
+public:
+ UniqueDWARFASTTypeList () :
+ m_collection()
+ {
+ }
+
+ ~UniqueDWARFASTTypeList ()
+ {
+ }
+
+ uint32_t
+ GetSize()
+ {
+ return (uint32_t)m_collection.size();
+ }
+
+ void
+ Append (const UniqueDWARFASTType &entry)
+ {
+ m_collection.push_back (entry);
+ }
+
+ bool
+ Find (const DWARFDebugInfoEntry *die,
+ const lldb_private::Declaration &decl,
+ UniqueDWARFASTType &entry) const;
+
+protected:
+ typedef std::vector<UniqueDWARFASTType> collection;
+ collection m_collection;
+};
+
+class UniqueDWARFASTTypeMap
+{
+public:
+ UniqueDWARFASTTypeMap () :
+ m_collection ()
+ {
+ }
+
+ ~UniqueDWARFASTTypeMap ()
+ {
+ }
+
+ void
+ Insert (const lldb_private::ConstString &name,
+ const UniqueDWARFASTType &entry)
+ {
+ m_collection[name.GetCString()].Append (entry);
+ }
+
+ bool
+ Find (const lldb_private::ConstString &name,
+ const DWARFDebugInfoEntry *die,
+ const lldb_private::Declaration &decl,
+ UniqueDWARFASTType &entry) const
+ {
+ const char *unique_name_cstr = name.GetCString();
+ collection::const_iterator pos = m_collection.find (unique_name_cstr);
+ if (pos != m_collection.end())
+ {
+ return pos->second.Find (die, decl, entry);
+ }
+ return false;
+ }
+
+protected:
+ // A unique name string should be used
+ typedef llvm::DenseMap<const char *, UniqueDWARFASTTypeList> collection;
+ collection m_collection;
+};
+
+#endif // lldb_UniqueDWARFASTType_h_
diff --git a/lldb/source/Symbol/Declaration.cpp b/lldb/source/Symbol/Declaration.cpp
index 8685d8df7cc..2b20a24e514 100644
--- a/lldb/source/Symbol/Declaration.cpp
+++ b/lldb/source/Symbol/Declaration.cpp
@@ -12,50 +12,6 @@
using namespace lldb_private;
-Declaration::Declaration() :
- m_file(),
- m_line(0),
- m_column(0)
-{
-}
-
-Declaration::Declaration(const FileSpec& f, uint32_t l, uint32_t c) :
- m_file(f),
- m_line(l),
- m_column(c)
-{
-}
-
-Declaration::Declaration(const Declaration& rhs) :
- m_file(rhs.m_file),
- m_line(rhs.m_line),
- m_column(rhs.m_column)
-{
-}
-
-Declaration::Declaration(const Declaration* decl_ptr) :
- m_file(),
- m_line(0),
- m_column(0)
-{
- if (decl_ptr != NULL)
- *this = *decl_ptr;
-}
-
-bool
-Declaration::IsValid() const
-{
- return m_file && m_line != 0;
-}
-
-void
-Declaration::Clear()
-{
- m_file.Clear();
- m_line= 0;
- m_column = 0;
-}
-
void
Declaration::Dump(Stream *s, bool show_fullpaths) const
{
@@ -68,19 +24,25 @@ Declaration::Dump(Stream *s, bool show_fullpaths) const
*s << m_file.GetFilename();
if (m_line > 0)
s->Printf(":%u", m_line);
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
if (m_column > 0)
s->Printf(":%u", m_column);
+#endif
}
else
{
if (m_line > 0)
{
s->Printf(", line = %u", m_line);
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
if (m_column > 0)
s->Printf(":%u", m_column);
+#endif
}
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
else if (m_column > 0)
s->Printf(", column = %u", m_column);
+#endif
}
}
@@ -96,67 +58,27 @@ Declaration::DumpStopContext (Stream *s, bool show_fullpaths) const
if (m_line > 0)
s->Printf(":%u", m_line);
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
if (m_column > 0)
s->Printf(":%u", m_column);
+#endif
}
else
{
s->Printf(" line %u", m_line);
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
if (m_column > 0)
s->Printf(":%u", m_column);
+#endif
}
}
-uint32_t
-Declaration::GetColumn() const
-{
- return m_column;
-}
-
-FileSpec&
-Declaration::GetFile()
-{
- return m_file;
-}
-
-const FileSpec&
-Declaration::GetFile() const
-{
- return m_file;
-}
-
-uint32_t
-Declaration::GetLine() const
-{
- return m_line;
-}
-
size_t
Declaration::MemorySize() const
{
return sizeof(Declaration);
}
-void
-Declaration::SetColumn(uint32_t col)
-{
- m_column = col;
-}
-
-void
-Declaration::SetFile(const FileSpec& file)
-{
- m_file = file;
-}
-
-void
-Declaration::SetLine(uint32_t line)
-{
- m_line = line;
-}
-
-
-
int
Declaration::Compare(const Declaration& a, const Declaration& b)
{
@@ -167,9 +89,26 @@ Declaration::Compare(const Declaration& a, const Declaration& b)
return -1;
else if (a.m_line > b.m_line)
return 1;
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
if (a.m_column < b.m_column)
return -1;
else if (a.m_column > b.m_column)
return 1;
+#endif
return 0;
}
+
+bool
+lldb_private::operator == (const Declaration &lhs, const Declaration &rhs)
+{
+#ifdef LLDB_ENABLE_DECLARATION_COLUMNS
+ if (lhs.GetColumn () == rhs.GetColumn ())
+ if (lhs.GetLine () == rhs.GetLine ())
+ return lhs.GetFile() == rhs.GetFile();
+#else
+ if (lhs.GetLine () == rhs.GetLine ())
+ return lhs.GetFile() == rhs.GetFile();
+#endif
+ return false;
+}
+
diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp
index ac281a269bc..83acbd0d663 100644
--- a/lldb/source/lldb.cpp
+++ b/lldb/source/lldb.cpp
@@ -11,6 +11,7 @@
#include "lldb/lldb-private-log.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Mutex.h"
@@ -97,6 +98,8 @@ lldb_private::Initialize ()
ProcessLinux::Initialize();
DynamicLoaderLinuxDYLD::Initialize();
#endif
+ // Scan for any system or user LLDB plug-ins
+ PluginManager::Initialize();
}
}
@@ -110,6 +113,10 @@ void
lldb_private::Terminate ()
{
Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+
+ // Terminate and unload and loaded system or user LLDB plug-ins
+ PluginManager::Terminate();
+
DisassemblerLLVM::Terminate();
ObjectContainerBSDArchive::Terminate();
ObjectFileELF::Terminate();
OpenPOWER on IntegriCloud