Added support to the Objective-C language runtime
to find Objective-C class types by looking in the
symbol tables for the individual object files.
I did this as follows:
- I added code to SymbolFileSymtab that vends
Clang types for symbols matching the pattern
"_OBJC_CLASS_$_NSMyClassName," making them
appear as Objective-C classes. This only occurs
in modules that do not have debug information,
since otherwise SymbolFileDWARF would be in
charge of looking up types.
- I made a new SymbolVendor subclass for the
Apple Objective-C runtime that is in charge of
making global lookups of Objective-C types. It
currently just sends out type lookup requests to
the appropriate SymbolFiles, but in the future we
will probably extend it to query the runtime more
completely.
I also modified a testcase whose behavior is changed
by the fact that we now actually return an Objective-C
type for __NSCFString.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@145526 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangASTSource.cpp b/source/Expression/ClangASTSource.cpp
index 5f3c8b1..db08539 100644
--- a/source/Expression/ClangASTSource.cpp
+++ b/source/Expression/ClangASTSource.cpp
@@ -17,6 +17,7 @@
#include "lldb/Expression/ClangExpression.h"
#include "lldb/Symbol/ClangNamespaceDecl.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
using namespace clang;
@@ -460,11 +461,29 @@
SymbolContext null_sc;
if (module_sp && namespace_decl)
+ {
module_sp->FindTypes(null_sc, name, &namespace_decl, true, 1, types);
+ }
else if(name != id_name && name != Class_name)
+ {
m_target->GetImages().FindTypes (null_sc, name, true, 1, types);
+
+ if (!types.GetSize())
+ {
+ lldb::ProcessSP process = m_target->GetProcessSP();
+
+ if (process && process->GetObjCLanguageRuntime())
+ {
+ SymbolVendor *objc_symbol_vendor = process->GetObjCLanguageRuntime()->GetSymbolVendor();
+
+ objc_symbol_vendor->FindTypes(null_sc, name, NULL, true, 1, types);
+ }
+ }
+ }
else
+ {
break;
+ }
if (types.GetSize())
{
@@ -484,6 +503,7 @@
context.AddTypeDecl(copied_type);
}
+
} while(0);
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 1b72409..d79eb75 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -38,9 +38,9 @@
#include "lldb/Target/Thread.h"
#include "AppleObjCRuntimeV2.h"
+#include "AppleObjCSymbolVendor.h"
#include "AppleObjCTrampolineHandler.h"
-
#include <vector>
using namespace lldb;
@@ -769,3 +769,11 @@
return parent_isa;
}
+SymbolVendor *
+AppleObjCRuntimeV2::GetSymbolVendor()
+{
+ if (!m_symbol_vendor_ap.get())
+ m_symbol_vendor_ap.reset(new AppleObjCSymbolVendor(m_process));
+
+ return m_symbol_vendor_ap.get();
+}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 64ef444..cf4bf3f 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -96,6 +96,9 @@
virtual ObjCLanguageRuntime::ObjCISA
GetParentClass(ObjCLanguageRuntime::ObjCISA isa);
+ virtual SymbolVendor *
+ GetSymbolVendor();
+
protected:
private:
@@ -123,6 +126,8 @@
ISAToNameCache m_isa_to_name_cache;
ISAToParentCache m_isa_to_parent_cache;
+ std::auto_ptr<SymbolVendor> m_symbol_vendor_ap;
+
static const char *g_find_class_name_function_name;
static const char *g_find_class_name_function_body;
static const char *g_objc_class_symbol_prefix;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp
new file mode 100644
index 0000000..b7c7a1d
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp
@@ -0,0 +1,76 @@
+//===-- AppleObjCSymbolVendor.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AppleObjCSymbolVendor.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "clang/AST/ASTContext.h"
+
+using namespace lldb_private;
+
+AppleObjCSymbolVendor::AppleObjCSymbolVendor(Process *process) :
+ SymbolVendor(NULL),
+ m_process(process->GetSP()),
+ m_ast_ctx(process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str())
+{
+}
+
+uint32_t
+AppleObjCSymbolVendor::FindTypes (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ uint32_t max_matches,
+ TypeList& types)
+{
+ lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); // FIXME - a more appropriate log channel?
+
+ if (log)
+ log->Printf("ObjC SymbolVendor asked for '%s'",
+ name.AsCString());
+
+ if (!append)
+ types.Clear();
+
+ uint32_t ret = 0;
+
+ ModuleList &images = m_process->GetTarget().GetImages();
+
+ for (size_t image_index = 0, end_index = images.GetSize();
+ image_index < end_index;
+ ++image_index)
+ {
+ Module *image = images.GetModulePointerAtIndex(image_index);
+
+ if (!image)
+ continue;
+
+ SymbolVendor *symbol_vendor = image->GetSymbolVendor();
+
+ if (!symbol_vendor)
+ continue;
+
+ SymbolFile *symbol_file = image->GetSymbolVendor()->GetSymbolFile();
+
+ if (!symbol_file || !(symbol_file->GetAbilities() & SymbolFile::RuntimeTypes))
+ continue;
+
+ const bool inferior_append = true;
+
+ ret += symbol_file->FindTypes (sc, name, namespace_decl, inferior_append, max_matches - ret, types);
+
+ if (ret >= max_matches)
+ break;
+ }
+
+ return ret;
+}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h
new file mode 100644
index 0000000..b426de5
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h
@@ -0,0 +1,47 @@
+//===-- AppleObjCSymbolVendor.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_AppleObjCSymbolVendor_h_
+#define liblldb_AppleObjCSymbolVendor_h_
+
+// C Includes
+// C++ Includes
+
+#include <map>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/SymbolFile.h"
+
+namespace lldb_private {
+
+class AppleObjCSymbolVendor : public SymbolVendor
+{
+public:
+ AppleObjCSymbolVendor(Process* process);
+
+ virtual uint32_t
+ FindTypes (const SymbolContext& sc,
+ const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ uint32_t max_matches,
+ TypeList& types);
+
+private:
+ lldb::ProcessSP m_process;
+ ClangASTContext m_ast_ctx;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_AppleObjCSymbolVendor_h_
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index c3e02d7..a824267 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -63,7 +63,8 @@
m_func_indexes(),
m_code_indexes(),
m_data_indexes(),
- m_addr_indexes()
+ m_addr_indexes(),
+ m_has_objc_symbols(eLazyBoolCalculate)
{
}
@@ -71,6 +72,27 @@
{
}
+ClangASTContext &
+SymbolFileSymtab::GetClangASTContext ()
+{
+ ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
+
+ return ast;
+}
+
+bool
+SymbolFileSymtab::HasObjCSymbols ()
+{
+ if (m_has_objc_symbols == eLazyBoolCalculate)
+ {
+ if (m_obj_file->GetSectionList()->FindSectionByName(ConstString("__objc_data")))
+ m_has_objc_symbols = eLazyBoolYes;
+ else
+ m_has_objc_symbols = eLazyBoolNo;
+ }
+
+ return m_has_objc_symbols == eLazyBoolYes;
+}
uint32_t
SymbolFileSymtab::GetAbilities ()
@@ -113,6 +135,11 @@
symtab->SortSymbolIndexesByValue(m_data_indexes, true);
abilities |= GlobalVariables;
}
+
+ if (HasObjCSymbols())
+ {
+ abilities |= RuntimeTypes;
+ }
}
}
return abilities;
@@ -352,6 +379,42 @@
{
if (!append)
types.Clear();
+
+ if (HasObjCSymbols())
+ {
+ std::string symbol_name("OBJC_CLASS_$_");
+ symbol_name.append(name.AsCString());
+ ConstString symbol_const_string(symbol_name.c_str());
+
+ std::vector<uint32_t> indices;
+
+ if (m_obj_file->GetSymtab()->FindAllSymbolsWithNameAndType(symbol_const_string, lldb::eSymbolTypeRuntime, indices) == 0)
+ return 0;
+
+ const bool isForwardDecl = false;
+ const bool isInternal = true;
+
+ ClangASTContext &clang_ast_ctx = GetClangASTContext();
+
+ lldb::clang_type_t objc_object_type = clang_ast_ctx.CreateObjCClass(name.AsCString(), clang_ast_ctx.GetTranslationUnitDecl(), isForwardDecl, isInternal);
+
+ Declaration decl;
+
+ lldb::TypeSP type(new Type (indices[0],
+ this,
+ name,
+ 0 /*byte_size*/,
+ NULL /*SymbolContextScope*/,
+ 0 /*encoding_uid*/,
+ Type::eEncodingInvalid,
+ decl,
+ objc_object_type,
+ Type::eResolveStateForward));
+
+ types.Insert(type);
+
+ return 1;
+ }
return 0;
}
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index ba43a30..d7e58af 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -119,12 +119,19 @@
GetPluginVersion();
protected:
+ lldb_private::LazyBool m_has_objc_symbols;
std::vector<uint32_t> m_source_indexes;
std::vector<uint32_t> m_func_indexes;
std::vector<uint32_t> m_code_indexes;
std::vector<uint32_t> m_data_indexes;
std::vector<uint32_t> m_addr_indexes; // Anything that needs to go into an search by address
+ bool
+ HasObjCSymbols ();
+
+ lldb_private::ClangASTContext &
+ GetClangASTContext ();
+
private:
DISALLOW_COPY_AND_ASSIGN (SymbolFileSymtab);
};
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index fda35d9..8acf79d 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -980,6 +980,12 @@
return void_ptr_type.getAsOpaquePtr();
}
+clang::DeclContext *
+ClangASTContext::GetTranslationUnitDecl (clang::ASTContext *ast)
+{
+ return ast->getTranslationUnitDecl();
+}
+
clang_type_t
ClangASTContext::CopyType (ASTContext *dst_ast,
ASTContext *src_ast,