forked from OSchip/llvm-project
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. llvm-svn: 145526
This commit is contained in:
parent
9430e284a9
commit
09ab4b777c
|
@ -195,6 +195,15 @@ public:
|
|||
static lldb::clang_type_t
|
||||
GetVoidPtrType(clang::ASTContext *ast, bool is_const);
|
||||
|
||||
static clang::DeclContext *
|
||||
GetTranslationUnitDecl (clang::ASTContext *ast);
|
||||
|
||||
clang::DeclContext *
|
||||
GetTranslationUnitDecl ()
|
||||
{
|
||||
return GetTranslationUnitDecl (getASTContext());
|
||||
}
|
||||
|
||||
static lldb::clang_type_t
|
||||
CopyType(clang::ASTContext *dest_context,
|
||||
clang::ASTContext *source_context,
|
||||
|
|
|
@ -30,14 +30,15 @@ public:
|
|||
TypeAcceleratorTable = (1 << 3),
|
||||
MacroInformation = (1 << 4),
|
||||
CallFrameInformation = (1 << 5),
|
||||
CompileUnits = (1 << 6),
|
||||
LineTables = (1 << 7),
|
||||
LineColumns = (1 << 8),
|
||||
Functions = (1 << 9),
|
||||
Blocks = (1 << 10),
|
||||
GlobalVariables = (1 << 11),
|
||||
LocalVariables = (1 << 12),
|
||||
VariableTypes = (1 << 13)
|
||||
RuntimeTypes = (1 << 6),
|
||||
CompileUnits = (1 << 7),
|
||||
LineTables = (1 << 8),
|
||||
LineColumns = (1 << 9),
|
||||
Functions = (1 << 10),
|
||||
Blocks = (1 << 11),
|
||||
GlobalVariables = (1 << 12),
|
||||
LocalVariables = (1 << 13),
|
||||
VariableTypes = (1 << 14),
|
||||
};
|
||||
|
||||
static SymbolFile *
|
||||
|
|
|
@ -87,6 +87,12 @@ public:
|
|||
virtual ObjCISA
|
||||
GetParentClass(ObjCISA isa) = 0;
|
||||
|
||||
virtual SymbolVendor *
|
||||
GetSymbolVendor()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Finds the byte offset of the child_type ivar in parent_type. If it can't find the
|
||||
// offset, returns LLDB_INVALID_IVAR_OFFSET.
|
||||
|
||||
|
|
|
@ -393,6 +393,7 @@
|
|||
49A71FE8141FFACF00D59478 /* DataEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 268ED0A4140FF54200DE830F /* DataEncoder.cpp */; };
|
||||
49C8507C1384A786007DB519 /* ProcessDataAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49C850781384A0CA007DB519 /* ProcessDataAllocator.cpp */; };
|
||||
49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D8FB3513B558DE00411094 /* ClangASTImporter.cpp */; };
|
||||
49DA65031485C92A005FF180 /* AppleObjCSymbolVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA65021485C92A005FF180 /* AppleObjCSymbolVendor.cpp */; };
|
||||
4CAA56131422D96A001FFA01 /* BreakpointResolverFileRegex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAA56121422D96A001FFA01 /* BreakpointResolverFileRegex.h */; };
|
||||
4CAA56151422D986001FFA01 /* BreakpointResolverFileRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */; };
|
||||
4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */; };
|
||||
|
@ -1171,6 +1172,8 @@
|
|||
49D7072811B5AD11001AD875 /* ClangASTSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTSource.cpp; path = source/Expression/ClangASTSource.cpp; sourceTree = "<group>"; };
|
||||
49D8FB3513B558DE00411094 /* ClangASTImporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTImporter.cpp; path = source/Symbol/ClangASTImporter.cpp; sourceTree = "<group>"; };
|
||||
49D8FB3713B5594900411094 /* ClangASTImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTImporter.h; path = include/lldb/Symbol/ClangASTImporter.h; sourceTree = "<group>"; };
|
||||
49DA65021485C92A005FF180 /* AppleObjCSymbolVendor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppleObjCSymbolVendor.cpp; sourceTree = "<group>"; };
|
||||
49DA65041485C942005FF180 /* AppleObjCSymbolVendor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleObjCSymbolVendor.h; sourceTree = "<group>"; };
|
||||
49E45FA911F660DC008F7B28 /* ClangASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTType.h; path = include/lldb/Symbol/ClangASTType.h; sourceTree = "<group>"; };
|
||||
49E45FAD11F660FE008F7B28 /* ClangASTType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTType.cpp; path = source/Symbol/ClangASTType.cpp; sourceTree = "<group>"; };
|
||||
49EC3E98118F90AC00B1265E /* ThreadPlanCallFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallFunction.cpp; path = source/Target/ThreadPlanCallFunction.cpp; sourceTree = "<group>"; };
|
||||
|
@ -2761,6 +2764,8 @@
|
|||
4CCA644513B40B82003BDF98 /* AppleObjCRuntimeV1.h */,
|
||||
4CCA644613B40B82003BDF98 /* AppleObjCRuntimeV2.cpp */,
|
||||
4CCA644713B40B82003BDF98 /* AppleObjCRuntimeV2.h */,
|
||||
49DA65041485C942005FF180 /* AppleObjCSymbolVendor.h */,
|
||||
49DA65021485C92A005FF180 /* AppleObjCSymbolVendor.cpp */,
|
||||
4CCA644813B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp */,
|
||||
4CCA644913B40B82003BDF98 /* AppleObjCTrampolineHandler.h */,
|
||||
4CCA644A13B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */,
|
||||
|
@ -3515,6 +3520,7 @@
|
|||
B207C4931429607D00F36E4E /* CommandObjectWatchpoint.cpp in Sources */,
|
||||
49A1CAC51430E8DE00306AC9 /* ExpressionSourceCode.cpp in Sources */,
|
||||
494260DA14579144003C1C78 /* VerifyDecl.cpp in Sources */,
|
||||
49DA65031485C92A005FF180 /* AppleObjCSymbolVendor.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -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 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
|
|||
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 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
|
|||
|
||||
context.AddTypeDecl(copied_type);
|
||||
}
|
||||
|
||||
} while(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ AppleObjCRuntimeV2::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -96,6 +96,9 @@ public:
|
|||
virtual ObjCLanguageRuntime::ObjCISA
|
||||
GetParentClass(ObjCLanguageRuntime::ObjCISA isa);
|
||||
|
||||
virtual SymbolVendor *
|
||||
GetSymbolVendor();
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
@ -123,6 +126,8 @@ private:
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
|
@ -63,7 +63,8 @@ SymbolFileSymtab::SymbolFileSymtab(ObjectFile* obj_file) :
|
|||
m_func_indexes(),
|
||||
m_code_indexes(),
|
||||
m_data_indexes(),
|
||||
m_addr_indexes()
|
||||
m_addr_indexes(),
|
||||
m_has_objc_symbols(eLazyBoolCalculate)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -71,6 +72,27 @@ SymbolFileSymtab::~SymbolFileSymtab()
|
|||
{
|
||||
}
|
||||
|
||||
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 @@ SymbolFileSymtab::GetAbilities ()
|
|||
symtab->SortSymbolIndexesByValue(m_data_indexes, true);
|
||||
abilities |= GlobalVariables;
|
||||
}
|
||||
|
||||
if (HasObjCSymbols())
|
||||
{
|
||||
abilities |= RuntimeTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
return abilities;
|
||||
|
@ -352,6 +379,42 @@ SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, const lldb_p
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -119,12 +119,19 @@ public:
|
|||
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);
|
||||
};
|
||||
|
|
|
@ -980,6 +980,12 @@ ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
|
|||
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,
|
||||
|
|
|
@ -233,10 +233,10 @@ class ObjCDataFormatterTestCase(TestBase):
|
|||
self.expect('frame variable dyn_test', matching=False,
|
||||
substrs = ['Process Name: a.out Process Id:'])
|
||||
self.expect('frame variable dyn_test -d run-target -T',
|
||||
substrs = ['(id, dynamic type:',
|
||||
substrs = ['(__NSCFString *, dynamic type:',
|
||||
'Process Name: a.out Process Id:'])
|
||||
self.expect('frame variable dyn_test -d run-target',
|
||||
substrs = ['(id)',
|
||||
substrs = ['(__NSCFString *)',
|
||||
'Process Name: a.out Process Id:'])
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue