[Lldb-commits] [lldb] r216026 - This is a fairly bulky patch, but a lot of it involves rearranging existing code
Zachary Turner
zturner at google.com
Tue Aug 19 17:00:15 PDT 2014
clang on Linux gives me this warning:
[2287/2447] Building CXX object
tools/lldb/source/Plugins/LanguageRunt...eFiles/lldbPluginAppleObjCRuntime.dir/AppleObjCClassDescriptorV2.cpp.o
In file included from
../../tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp:10:
../../tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h:73:5:
warning: 'lldb_private::ClassDescriptorV2::Describe' hides overloaded
virtual function [-Woverloaded-virtual]
Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const
&superclass_func,
^
../../tools/lldb/include/lldb/Target/ObjCLanguageRuntime.h:222:9: note:
hidden overloaded virtual function
'lldb_private::ObjCLanguageRuntime::ClassDescriptor::Describe' declared
here: different qualifiers (none vs const)
Describe (std::function <void (ObjCISA)> const &superclass_func,
^
1 warning generated.
Doesn't seem entirely benign, so I figured I would let you know in case
this is a real bug.
On Tue, Aug 19, 2014 at 2:46 PM, Enrico Granata <egranata at apple.com> wrote:
> Author: enrico
> Date: Tue Aug 19 16:46:37 2014
> New Revision: 216026
>
> URL: http://llvm.org/viewvc/llvm-project?rev=216026&view=rev
> Log:
> This is a fairly bulky patch, but a lot of it involves rearranging
> existing code
> What it does:
>
> - it introduces a concept of EncodingToType to the ObjCLanguageRuntime
> The ObjC runtime has a "type encoding" feature that describes types as
> strings
> The EncodingToType is a decoder for that format, making types out of
> type encoding strings
> This feature already existed in some shape as we were using it to create
> method signatures out of the runtime, but this checkin extends the parser
> to support the full syntax, and moves things so that more parts of LLDB
> have access to this decoder
>
> - it splits the ClassDescriptorV2 object to its own file, it was starting
> to grow too large
>
> - it adds to the ClassDescriptor mechanism a notion of ivar storage; the
> ObjC runtime vends ivar information as well as method information
> While ivar information is not ready for prime type (i.e. we don't want to
> add it to the runtime generated types for expression evaluator usage),
> there are potentially useful scenarios in which realizing ivar types could
> be useful. For now, the ClassDescriptor is going to hold ivar information
> directly. Existing code already allows describing ivars, this patch hooks
> those moving parts up so that one can actually ask a ClassDescriptor about
> ivars for the class it represents
>
> and as a couple minor niceties:
> - it makes it possible to retrieve the LLDB ClangASTContext that is
> associated to a clang::ASTContext
> - it extends the ValueObject-to-ClassDescriptor API in the language
> runtime to deal correctly with base-class hierarchies
>
>
> Added:
>
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
>
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
>
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
>
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
> Modified:
> lldb/trunk/include/lldb/Symbol/ClangASTContext.h
> lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
> lldb/trunk/lldb.xcodeproj/project.pbxproj
>
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
>
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
>
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
>
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h
> lldb/trunk/source/Symbol/ClangASTContext.cpp
> lldb/trunk/source/Target/ObjCLanguageRuntime.cpp
>
> Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
> +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Aug 19 16:46:37
> 2014
> @@ -43,6 +43,9 @@ public:
> ClangASTContext (const char *triple = NULL);
>
> ~ClangASTContext();
> +
> + static ClangASTContext*
> + GetASTContext (clang::ASTContext* ast_ctx);
>
> clang::ASTContext *
> getASTContext();
>
> Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> --- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
> +++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Tue Aug 19
> 16:46:37 2014
> @@ -20,6 +20,7 @@
> // Project includes
> #include "lldb/lldb-private.h"
> #include "lldb/Core/PluginInterface.h"
> +#include "lldb/Symbol/ClangASTType.h"
> #include "lldb/Symbol/Type.h"
> #include "lldb/Symbol/TypeVendor.h"
> #include "lldb/Target/LanguageRuntime.h"
> @@ -238,6 +239,25 @@ public:
> m_type_wp = type_sp;
> }
>
> + struct iVarDescriptor {
> + ConstString m_name;
> + ClangASTType m_type;
> + uint64_t m_size;
> + int32_t m_offset;
> + };
> +
> + virtual size_t
> + GetNumIVars ()
> + {
> + return 0;
> + }
> +
> + virtual iVarDescriptor
> + GetIVarAtIndex (size_t idx)
> + {
> + return iVarDescriptor();
> + }
> +
> protected:
> bool
> IsPointerValid (lldb::addr_t value,
> @@ -252,6 +272,25 @@ public:
> lldb::TypeWP m_type_wp;
> };
>
> + class EncodingToType
> + {
> + public:
> + virtual ClangASTType RealizeType (ClangASTContext& ast_ctx, const
> char* name, bool allow_unknownanytype);
> + virtual ClangASTType RealizeType (const char* name, bool
> allow_unknownanytype);
> +
> + virtual ClangASTType RealizeType (clang::ASTContext& ast_ctx,
> const char* name, bool allow_unknownanytype) = 0;
> +
> + virtual ~EncodingToType();
> +
> + protected:
> + std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_ap;
> + };
> +
> + typedef std::shared_ptr<EncodingToType> EncodingToTypeSP;
> +
> + virtual EncodingToTypeSP
> + GetEncodingToType ();
> +
> virtual ClassDescriptorSP
> GetClassDescriptor (ValueObject& in_value);
>
>
> Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
> +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Aug 19 16:46:37 2014
> @@ -664,6 +664,8 @@
> 94CD704E16F8DDEA00CF1E42 /* Cocoa.cpp in Sources */ = {isa
> = PBXBuildFile; fileRef = 94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */; };
> 94CD705016F8DF1C00CF1E42 /* LibCxxList.cpp in Sources */ =
> {isa = PBXBuildFile; fileRef = 94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp
> */; };
> 94CD705216F8F5BC00CF1E42 /* LibCxxMap.cpp in Sources */ =
> {isa = PBXBuildFile; fileRef = 94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp
> */; };
> + 94CD7D0919A3FBA300908B7C /* AppleObjCClassDescriptorV2.cpp
> in Sources */ = {isa = PBXBuildFile; fileRef = 94CD7D0819A3FBA300908B7C /*
> AppleObjCClassDescriptorV2.cpp */; };
> + 94CD7D0C19A3FBCE00908B7C /*
> AppleObjCTypeEncodingParser.cpp in Sources */ = {isa = PBXBuildFile;
> fileRef = 94CD7D0B19A3FBCE00908B7C /* AppleObjCTypeEncodingParser.cpp */; };
> 94D0B10C16D5535900EA9C70 /* LibCxx.cpp in Sources */ =
> {isa = PBXBuildFile; fileRef = 94D0B10A16D5535900EA9C70 /* LibCxx.cpp */; };
> 94D0B10D16D5535900EA9C70 /* LibStdcpp.cpp in Sources */ =
> {isa = PBXBuildFile; fileRef = 94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp
> */; };
> 94D6A0AA16CEB55F00833B6E /* NSArray.cpp in Sources */ =
> {isa = PBXBuildFile; fileRef = 94D6A0A716CEB55F00833B6E /* NSArray.cpp */;
> };
> @@ -1970,6 +1972,10 @@
> 94CD704C16F8DDEA00CF1E42 /* Cocoa.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> name = Cocoa.cpp; path = source/DataFormatters/Cocoa.cpp; sourceTree =
> "<group>"; };
> 94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> name = LibCxxList.cpp; path = source/DataFormatters/LibCxxList.cpp;
> sourceTree = "<group>"; };
> 94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> name = LibCxxMap.cpp; path = source/DataFormatters/LibCxxMap.cpp;
> sourceTree = "<group>"; };
> + 94CD7D0719A3FB8600908B7C /* AppleObjCClassDescriptorV2.h
> */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path =
> AppleObjCClassDescriptorV2.h; sourceTree = "<group>"; };
> + 94CD7D0819A3FBA300908B7C /* AppleObjCClassDescriptorV2.cpp
> */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
> sourcecode.cpp.cpp; path = AppleObjCClassDescriptorV2.cpp; sourceTree =
> "<group>"; };
> + 94CD7D0A19A3FBC300908B7C /* AppleObjCTypeEncodingParser.h
> */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path =
> AppleObjCTypeEncodingParser.h; sourceTree = "<group>"; };
> + 94CD7D0B19A3FBCE00908B7C /*
> AppleObjCTypeEncodingParser.cpp */ = {isa = PBXFileReference; fileEncoding
> = 4; lastKnownFileType = sourcecode.cpp.cpp; path =
> AppleObjCTypeEncodingParser.cpp; sourceTree = "<group>"; };
> 94D0B10A16D5535900EA9C70 /* LibCxx.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> name = LibCxx.cpp; path = source/DataFormatters/LibCxx.cpp; sourceTree =
> "<group>"; };
> 94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> name = LibStdcpp.cpp; path = source/DataFormatters/LibStdcpp.cpp;
> sourceTree = "<group>"; };
> 94D6A0A716CEB55F00833B6E /* NSArray.cpp */ = {isa =
> PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp;
> name = NSArray.cpp; path = source/DataFormatters/NSArray.cpp; sourceTree =
> "<group>"; };
> @@ -4045,6 +4051,8 @@
> 4CCA644113B40B82003BDF98 /* AppleObjCRuntime */ = {
> isa = PBXGroup;
> children = (
> + 94CD7D0719A3FB8600908B7C /*
> AppleObjCClassDescriptorV2.h */,
> + 94CD7D0819A3FBA300908B7C /*
> AppleObjCClassDescriptorV2.cpp */,
> 4CCA644213B40B82003BDF98 /*
> AppleObjCRuntime.cpp */,
> 4CCA644313B40B82003BDF98 /*
> AppleObjCRuntime.h */,
> 4CCA644413B40B82003BDF98 /*
> AppleObjCRuntimeV1.cpp */,
> @@ -4053,6 +4061,8 @@
> 4CCA644713B40B82003BDF98 /*
> AppleObjCRuntimeV2.h */,
> 4CCA644813B40B82003BDF98 /*
> AppleObjCTrampolineHandler.cpp */,
> 4CCA644913B40B82003BDF98 /*
> AppleObjCTrampolineHandler.h */,
> + 94CD7D0A19A3FBC300908B7C /*
> AppleObjCTypeEncodingParser.h */,
> + 94CD7D0B19A3FBCE00908B7C /*
> AppleObjCTypeEncodingParser.cpp */,
> 49DA65041485C942005FF180 /*
> AppleObjCTypeVendor.h */,
> 49DA65021485C92A005FF180 /*
> AppleObjCTypeVendor.cpp */,
> 4CCA644A13B40B82003BDF98 /*
> AppleThreadPlanStepThroughObjCTrampoline.cpp */,
> @@ -5143,11 +5153,13 @@
> 26957D9813D381C900670048 /*
> RegisterContextDarwin_arm.cpp in Sources */,
> 26957D9A13D381C900670048 /*
> RegisterContextDarwin_i386.cpp in Sources */,
> 26957D9C13D381C900670048 /*
> RegisterContextDarwin_x86_64.cpp in Sources */,
> + 94CD7D0919A3FBA300908B7C /*
> AppleObjCClassDescriptorV2.cpp in Sources */,
> 265205A813D3E3F700132FE2 /*
> RegisterContextKDP_arm.cpp in Sources */,
> 265205AA13D3E3F700132FE2 /*
> RegisterContextKDP_i386.cpp in Sources */,
> 265205AC13D3E3F700132FE2 /*
> RegisterContextKDP_x86_64.cpp in Sources */,
> 2628A4D513D4977900F5487A /* ThreadKDP.cpp
> in Sources */,
> 26D7E45D13D5E30A007FD12B /*
> SocketAddress.cpp in Sources */,
> + 94CD7D0C19A3FBCE00908B7C /*
> AppleObjCTypeEncodingParser.cpp in Sources */,
> 94B6E76213D88365005F417F /*
> ValueObjectSyntheticFilter.cpp in Sources */,
> 262D24E613FB8710002D1960 /*
> RegisterContextMemory.cpp in Sources */,
> 26F4A21C13FBA31A0064B613 /*
> ThreadMemory.cpp in Sources */,
>
> Added:
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp?rev=216026&view=auto
>
> ==============================================================================
> ---
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
> (added)
> +++
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
> Tue Aug 19 16:46:37 2014
> @@ -0,0 +1,526 @@
> +//===-- AppleObjCClassDescriptorV2.cpp -----------------------------*-
> C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AppleObjCClassDescriptorV2.h"
> +
> +using namespace lldb;
> +using namespace lldb_private;
> +
> +bool
> +ClassDescriptorV2::Read_objc_class (Process* process,
> std::unique_ptr<objc_class_t> &objc_class) const
> +{
> + objc_class.reset(new objc_class_t);
> +
> + bool ret = objc_class->Read (process, m_objc_class_ptr);
> +
> + if (!ret)
> + objc_class.reset();
> +
> + return ret;
> +}
> +
> +bool
> +ClassDescriptorV2::objc_class_t::Read(Process *process, lldb::addr_t addr)
> +{
> + size_t ptr_size = process->GetAddressByteSize();
> +
> + size_t objc_class_size = ptr_size // uintptr_t isa;
> + + ptr_size // Class superclass;
> + + ptr_size // void *cache;
> + + ptr_size // IMP *vtable;
> + + ptr_size; // uintptr_t data_NEVER_USE;
> +
> + DataBufferHeap objc_class_buf (objc_class_size, '\0');
> + Error error;
> +
> + process->ReadMemory(addr, objc_class_buf.GetBytes(), objc_class_size,
> error);
> + if (error.Fail())
> + {
> + return false;
> + }
> +
> + DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size,
> process->GetByteOrder(), process->GetAddressByteSize());
> +
> + lldb::offset_t cursor = 0;
> +
> + m_isa = extractor.GetAddress_unchecked(&cursor); //
> uintptr_t isa;
> + m_superclass = extractor.GetAddress_unchecked(&cursor); // Class
> superclass;
> + m_cache_ptr = extractor.GetAddress_unchecked(&cursor); // void
> *cache;
> + m_vtable_ptr = extractor.GetAddress_unchecked(&cursor); // IMP
> *vtable;
> + lldb::addr_t data_NEVER_USE =
> extractor.GetAddress_unchecked(&cursor); // uintptr_t data_NEVER_USE;
> +
> + m_flags = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3);
> + m_data_ptr = data_NEVER_USE & ~(lldb::addr_t)3;
> +
> + return true;
> +}
> +
> +bool
> +ClassDescriptorV2::class_rw_t::Read(Process *process, lldb::addr_t addr)
> +{
> + size_t ptr_size = process->GetAddressByteSize();
> +
> + size_t size = sizeof(uint32_t) // uint32_t flags;
> + + sizeof(uint32_t) // uint32_t version;
> + + ptr_size // const class_ro_t *ro;
> + + ptr_size // union { method_list_t **method_lists;
> method_list_t *method_list; };
> + + ptr_size // struct chained_property_list *properties;
> + + ptr_size // const protocol_list_t **protocols;
> + + ptr_size // Class firstSubclass;
> + + ptr_size; // Class nextSiblingClass;
> +
> + DataBufferHeap buffer (size, '\0');
> + Error error;
> +
> + process->ReadMemory(addr, buffer.GetBytes(), size, error);
> + if (error.Fail())
> + {
> + return false;
> + }
> +
> + DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> +
> + lldb::offset_t cursor = 0;
> +
> + m_flags = extractor.GetU32_unchecked(&cursor);
> + m_version = extractor.GetU32_unchecked(&cursor);
> + m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_firstSubclass = extractor.GetAddress_unchecked(&cursor);
> + m_nextSiblingClass = extractor.GetAddress_unchecked(&cursor);
> +
> + return true;
> +}
> +
> +bool
> +ClassDescriptorV2::class_ro_t::Read(Process *process, lldb::addr_t addr)
> +{
> + size_t ptr_size = process->GetAddressByteSize();
> +
> + size_t size = sizeof(uint32_t) // uint32_t flags;
> + + sizeof(uint32_t) // uint32_t instanceStart;
> + + sizeof(uint32_t) // uint32_t instanceSize;
> + + (ptr_size == 8 ? sizeof(uint32_t) : 0) // uint32_t reserved; //
> __LP64__ only
> + + ptr_size // const uint8_t
> *ivarLayout;
> + + ptr_size // const char *name;
> + + ptr_size // const method_list_t
> *baseMethods;
> + + ptr_size // const protocol_list_t
> *baseProtocols;
> + + ptr_size // const ivar_list_t
> *ivars;
> + + ptr_size // const uint8_t
> *weakIvarLayout;
> + + ptr_size; // const property_list_t
> *baseProperties;
> +
> + DataBufferHeap buffer (size, '\0');
> + Error error;
> +
> + process->ReadMemory(addr, buffer.GetBytes(), size, error);
> + if (error.Fail())
> + {
> + return false;
> + }
> +
> + DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> +
> + lldb::offset_t cursor = 0;
> +
> + m_flags = extractor.GetU32_unchecked(&cursor);
> + m_instanceStart = extractor.GetU32_unchecked(&cursor);
> + m_instanceSize = extractor.GetU32_unchecked(&cursor);
> + if (ptr_size == 8)
> + m_reserved = extractor.GetU32_unchecked(&cursor);
> + else
> + m_reserved = 0;
> + m_ivarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_name_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_baseMethods_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_baseProtocols_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_ivars_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_weakIvarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_baseProperties_ptr = extractor.GetAddress_unchecked(&cursor);
> +
> + DataBufferHeap name_buf(1024, '\0');
> +
> + process->ReadCStringFromMemory(m_name_ptr,
> (char*)name_buf.GetBytes(), name_buf.GetByteSize(), error);
> +
> + if (error.Fail())
> + {
> + return false;
> + }
> +
> + m_name.assign((char*)name_buf.GetBytes());
> +
> + return true;
> +}
> +
> +bool
> +ClassDescriptorV2::Read_class_row (Process* process, const objc_class_t
> &objc_class, std::unique_ptr<class_ro_t> &class_ro,
> std::unique_ptr<class_rw_t> &class_rw) const
> +{
> + class_ro.reset();
> + class_rw.reset();
> +
> + Error error;
> + uint32_t class_row_t_flags =
> process->ReadUnsignedIntegerFromMemory(objc_class.m_data_ptr,
> sizeof(uint32_t), 0, error);
> + if (!error.Success())
> + return false;
> +
> + if (class_row_t_flags & RW_REALIZED)
> + {
> + class_rw.reset(new class_rw_t);
> +
> + if (!class_rw->Read(process, objc_class.m_data_ptr))
> + {
> + class_rw.reset();
> + return false;
> + }
> +
> + class_ro.reset(new class_ro_t);
> +
> + if (!class_ro->Read(process, class_rw->m_ro_ptr))
> + {
> + class_rw.reset();
> + class_ro.reset();
> + return false;
> + }
> + }
> + else
> + {
> + class_ro.reset(new class_ro_t);
> +
> + if (!class_ro->Read(process, objc_class.m_data_ptr))
> + {
> + class_ro.reset();
> + return false;
> + }
> + }
> +
> + return true;
> +}
> +
> +bool
> +ClassDescriptorV2::method_list_t::Read(Process *process, lldb::addr_t
> addr)
> +{
> + size_t size = sizeof(uint32_t) // uint32_t entsize_NEVER_USE;
> + + sizeof(uint32_t); // uint32_t count;
> +
> + DataBufferHeap buffer (size, '\0');
> + Error error;
> +
> + process->ReadMemory(addr, buffer.GetBytes(), size, error);
> + if (error.Fail())
> + {
> + return false;
> + }
> +
> + DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> +
> + lldb::offset_t cursor = 0;
> +
> + m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
> + m_count = extractor.GetU32_unchecked(&cursor);
> + m_first_ptr = addr + cursor;
> +
> + return true;
> +}
> +
> +bool
> +ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr)
> +{
> + size_t size = GetSize(process);
> +
> + DataBufferHeap buffer (size, '\0');
> + Error error;
> +
> + process->ReadMemory(addr, buffer.GetBytes(), size, error);
> + if (error.Fail())
> + {
> + return false;
> + }
> +
> + DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> +
> + lldb::offset_t cursor = 0;
> +
> + m_name_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_types_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
> +
> + const size_t buffer_size = 1024;
> + size_t count;
> +
> + DataBufferHeap string_buf(buffer_size, 0);
> +
> + count = process->ReadCStringFromMemory(m_name_ptr,
> (char*)string_buf.GetBytes(), buffer_size, error);
> + m_name.assign((char*)string_buf.GetBytes(), count);
> +
> + count = process->ReadCStringFromMemory(m_types_ptr,
> (char*)string_buf.GetBytes(), buffer_size, error);
> + m_types.assign((char*)string_buf.GetBytes(), count);
> +
> + return true;
> +}
> +
> +bool
> +ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr)
> +{
> + size_t size = sizeof(uint32_t) // uint32_t entsize;
> + + sizeof(uint32_t); // uint32_t count;
> +
> + DataBufferHeap buffer (size, '\0');
> + Error error;
> +
> + process->ReadMemory(addr, buffer.GetBytes(), size, error);
> + if (error.Fail())
> + {
> + return false;
> + }
> +
> + DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> +
> + lldb::offset_t cursor = 0;
> +
> + m_entsize = extractor.GetU32_unchecked(&cursor);
> + m_count = extractor.GetU32_unchecked(&cursor);
> + m_first_ptr = addr + cursor;
> +
> + return true;
> +}
> +
> +bool
> +ClassDescriptorV2::ivar_t::Read(Process *process, lldb::addr_t addr)
> +{
> + size_t size = GetSize(process);
> +
> + DataBufferHeap buffer (size, '\0');
> + Error error;
> +
> + process->ReadMemory(addr, buffer.GetBytes(), size, error);
> + if (error.Fail())
> + {
> + return false;
> + }
> +
> + DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> +
> + lldb::offset_t cursor = 0;
> +
> + m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_name_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_type_ptr = extractor.GetAddress_unchecked(&cursor);
> + m_alignment = extractor.GetU32_unchecked(&cursor);
> + m_size = extractor.GetU32_unchecked(&cursor);
> +
> + const size_t buffer_size = 1024;
> + size_t count;
> +
> + DataBufferHeap string_buf(buffer_size, 0);
> +
> + count = process->ReadCStringFromMemory(m_name_ptr,
> (char*)string_buf.GetBytes(), buffer_size, error);
> + m_name.assign((char*)string_buf.GetBytes(), count);
> +
> + count = process->ReadCStringFromMemory(m_type_ptr,
> (char*)string_buf.GetBytes(), buffer_size, error);
> + m_type.assign((char*)string_buf.GetBytes(), count);
> +
> + return true;
> +}
> +
> +bool
> +ClassDescriptorV2::Describe (std::function <void
> (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
> + std::function <bool (const char *, const
> char *)> const &instance_method_func,
> + std::function <bool (const char *, const
> char *)> const &class_method_func,
> + std::function <bool (const char *, const
> char *, lldb::addr_t, uint64_t)> const &ivar_func) const
> +{
> + lldb_private::Process *process = m_runtime.GetProcess();
> +
> + std::unique_ptr<objc_class_t> objc_class;
> + std::unique_ptr<class_ro_t> class_ro;
> + std::unique_ptr<class_rw_t> class_rw;
> +
> + if (!Read_objc_class(process, objc_class))
> + return 0;
> + if (!Read_class_row(process, *objc_class, class_ro, class_rw))
> + return 0;
> +
> + static ConstString NSObject_name("NSObject");
> +
> + if (m_name != NSObject_name && superclass_func)
> + superclass_func(objc_class->m_superclass);
> +
> + if (instance_method_func)
> + {
> + std::unique_ptr<method_list_t> base_method_list;
> +
> + base_method_list.reset(new method_list_t);
> + if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
> + return false;
> +
> + if (base_method_list->m_entsize != method_t::GetSize(process))
> + return false;
> +
> + std::unique_ptr<method_t> method;
> + method.reset(new method_t);
> +
> + for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
> + {
> + method->Read(process, base_method_list->m_first_ptr + (i *
> base_method_list->m_entsize));
> +
> + if (instance_method_func(method->m_name.c_str(),
> method->m_types.c_str()))
> + break;
> + }
> + }
> +
> + if (class_method_func)
> + {
> + ClassDescriptorV2 metaclass(m_runtime, objc_class->m_isa, NULL);
> // The metaclass is not in the cache
> +
> + // We don't care about the metaclass's superclass, or its class
> methods. Its instance methods are
> + // our class methods.
> +
> + metaclass.Describe(std::function <void
> (ObjCLanguageRuntime::ObjCISA)> (nullptr),
> + class_method_func,
> + std::function <bool (const char *, const char
> *)> (nullptr),
> + std::function <bool (const char *, const char
> *, lldb::addr_t, uint64_t)> (nullptr));
> + }
> +
> + if (ivar_func)
> + {
> + ivar_list_t ivar_list;
> + if (!ivar_list.Read(process, class_ro->m_ivars_ptr))
> + return false;
> +
> + if (ivar_list.m_entsize != ivar_t::GetSize(process))
> + return false;
> +
> + ivar_t ivar;
> +
> + for (uint32_t i = 0, e = ivar_list.m_count; i < e; ++i)
> + {
> + ivar.Read(process, ivar_list.m_first_ptr + (i *
> ivar_list.m_entsize));
> +
> + if (ivar_func(ivar.m_name.c_str(), ivar.m_type.c_str(),
> ivar.m_offset_ptr, ivar.m_size))
> + break;
> + }
> + }
> +
> + return true;
> +}
> +
> +ConstString
> +ClassDescriptorV2::GetClassName ()
> +{
> + if (!m_name)
> + {
> + lldb_private::Process *process = m_runtime.GetProcess();
> +
> + if (process)
> + {
> + std::unique_ptr<objc_class_t> objc_class;
> + std::unique_ptr<class_ro_t> class_ro;
> + std::unique_ptr<class_rw_t> class_rw;
> +
> + if (!Read_objc_class(process, objc_class))
> + return m_name;
> + if (!Read_class_row(process, *objc_class, class_ro, class_rw))
> + return m_name;
> +
> + m_name = ConstString(class_ro->m_name.c_str());
> + }
> + }
> + return m_name;
> +}
> +
> +ObjCLanguageRuntime::ClassDescriptorSP
> +ClassDescriptorV2::GetSuperclass ()
> +{
> + lldb_private::Process *process = m_runtime.GetProcess();
> +
> + if (!process)
> + return ObjCLanguageRuntime::ClassDescriptorSP();
> +
> + std::unique_ptr<objc_class_t> objc_class;
> +
> + if (!Read_objc_class(process, objc_class))
> + return ObjCLanguageRuntime::ClassDescriptorSP();
> +
> + return
> m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(objc_class->m_superclass);
> +}
> +
> +uint64_t
> +ClassDescriptorV2::GetInstanceSize ()
> +{
> + lldb_private::Process *process = m_runtime.GetProcess();
> +
> + if (process)
> + {
> + std::unique_ptr<objc_class_t> objc_class;
> + std::unique_ptr<class_ro_t> class_ro;
> + std::unique_ptr<class_rw_t> class_rw;
> +
> + if (!Read_objc_class(process, objc_class))
> + return 0;
> + if (!Read_class_row(process, *objc_class, class_ro, class_rw))
> + return 0;
> +
> + return class_ro->m_instanceSize;
> + }
> +
> + return 0;
> +}
> +
> +ClassDescriptorV2::iVarsStorage::iVarsStorage ():
> +m_filled(false),
> +m_ivars(),
> +m_mutex(Mutex::eMutexTypeRecursive)
> +{}
> +
> +size_t
> +ClassDescriptorV2::iVarsStorage::size ()
> +{
> + return m_ivars.size();
> +}
> +
> +ClassDescriptorV2::iVarDescriptor&
> +ClassDescriptorV2::iVarsStorage::operator[] (size_t idx)
> +{
> + return m_ivars[idx];
> +}
> +
> +void
> +ClassDescriptorV2::iVarsStorage::fill (AppleObjCRuntimeV2& runtime,
> ClassDescriptorV2& descriptor)
> +{
> + if (m_filled)
> + return;
> + Mutex::Locker lock(m_mutex);
> + m_filled = true;
> + ObjCLanguageRuntime::EncodingToTypeSP
> encoding_to_type_sp(runtime.GetEncodingToType());
> + Process* process(runtime.GetProcess());
> + if (!encoding_to_type_sp)
> + return;
> + descriptor.Describe(nullptr,
> + nullptr,
> + nullptr,
> + [this,process,encoding_to_type_sp](const char *
> name, const char * type, lldb::addr_t offset_ptr, uint64_t size) -> bool {
> + const bool allow_unknownanytype = false;
> + const bool stop_loop = false;
> + ClangASTType ivar_type =
> encoding_to_type_sp->RealizeType(type, allow_unknownanytype);
> + if (ivar_type)
> + {
> + Scalar offset_scalar;
> + Error error;
> + size_t read =
> process->ReadScalarIntegerFromMemory(offset_ptr, 4, true, offset_scalar,
> error);
> + if (error.Success() && 4 == read)
> + m_ivars.push_back({ ConstString(name),
> ivar_type, size, offset_scalar.SInt() });
> + }
> + return stop_loop;
> + });
> +}
> +
> +void
> +ClassDescriptorV2::GetIVarInformation ()
> +{
> + m_ivars_storage.fill(m_runtime, *this);
> +}
>
> Added:
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h?rev=216026&view=auto
>
> ==============================================================================
> ---
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
> (added)
> +++
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
> Tue Aug 19 16:46:37 2014
> @@ -0,0 +1,411 @@
> +//===-- AppleObjCClassDescriptorV2.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_AppleObjCClassDescriptorV2_h_
> +#define liblldb_AppleObjCClassDescriptorV2_h_
> +
> +// C Includes
> +// C++ Includes
> +// Other libraries and framework includes
> +
> +// Project includes
> +#include "lldb/lldb-private.h"
> +#include "lldb/Host/Mutex.h"
> +#include "lldb/Target/ObjCLanguageRuntime.h"
> +#include "AppleObjCRuntimeV2.h"
> +
> +namespace lldb_private {
> +
> +class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
> +{
> +public:
> + friend class lldb_private::AppleObjCRuntimeV2;
> +
> +private:
> + // The constructor should only be invoked by the runtime as it builds
> its caches
> + // or populates them. A ClassDescriptorV2 should only ever exist in
> a cache.
> + ClassDescriptorV2 (AppleObjCRuntimeV2 &runtime,
> ObjCLanguageRuntime::ObjCISA isa, const char *name) :
> + m_runtime (runtime),
> + m_objc_class_ptr (isa),
> + m_name (name),
> + m_ivars_storage()
> + {
> + }
> +
> +public:
> + virtual ConstString
> + GetClassName ();
> +
> + virtual ObjCLanguageRuntime::ClassDescriptorSP
> + GetSuperclass ();
> +
> + virtual bool
> + IsValid ()
> + {
> + return true; // any Objective-C v2 runtime class descriptor we
> vend is valid
> + }
> +
> + // a custom descriptor is used for tagged pointers
> + virtual bool
> + GetTaggedPointerInfo (uint64_t* info_bits = NULL,
> + uint64_t* value_bits = NULL,
> + uint64_t* payload = NULL)
> + {
> + return false;
> + }
> +
> + virtual uint64_t
> + GetInstanceSize ();
> +
> + virtual ObjCLanguageRuntime::ObjCISA
> + GetISA ()
> + {
> + return m_objc_class_ptr;
> + }
> +
> + virtual bool
> + Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const
> &superclass_func,
> + std::function <bool (const char *, const char *)> const
> &instance_method_func,
> + std::function <bool (const char *, const char *)> const
> &class_method_func,
> + std::function <bool (const char *, const char *,
> lldb::addr_t, uint64_t)> const &ivar_func) const;
> +
> + virtual
> + ~ClassDescriptorV2 ()
> + {
> + }
> +
> + virtual size_t
> + GetNumIVars ()
> + {
> + GetIVarInformation();
> + return m_ivars_storage.size();
> + }
> +
> + virtual iVarDescriptor
> + GetIVarAtIndex (size_t idx)
> + {
> + if (idx >= GetNumIVars())
> + return iVarDescriptor();
> + return m_ivars_storage[idx];
> + }
> +
> +protected:
> + void
> + GetIVarInformation ();
> +
> +private:
> + static const uint32_t RW_REALIZED = (1 << 31);
> +
> + struct objc_class_t {
> + ObjCLanguageRuntime::ObjCISA m_isa; // The
> class's metaclass.
> + ObjCLanguageRuntime::ObjCISA m_superclass;
> + lldb::addr_t m_cache_ptr;
> + lldb::addr_t m_vtable_ptr;
> + lldb::addr_t m_data_ptr;
> + uint8_t m_flags;
> +
> + objc_class_t () :
> + m_isa (0),
> + m_superclass (0),
> + m_cache_ptr (0),
> + m_vtable_ptr (0),
> + m_data_ptr (0),
> + m_flags (0)
> + {
> + }
> +
> + void
> + Clear()
> + {
> + m_isa = 0;
> + m_superclass = 0;
> + m_cache_ptr = 0;
> + m_vtable_ptr = 0;
> + m_data_ptr = 0;
> + m_flags = 0;
> + }
> +
> + bool
> + Read(Process *process, lldb::addr_t addr);
> + };
> +
> + struct class_ro_t {
> + uint32_t m_flags;
> + uint32_t m_instanceStart;
> + uint32_t m_instanceSize;
> + uint32_t m_reserved;
> +
> + lldb::addr_t m_ivarLayout_ptr;
> + lldb::addr_t m_name_ptr;
> + lldb::addr_t m_baseMethods_ptr;
> + lldb::addr_t m_baseProtocols_ptr;
> + lldb::addr_t m_ivars_ptr;
> +
> + lldb::addr_t m_weakIvarLayout_ptr;
> + lldb::addr_t m_baseProperties_ptr;
> +
> + std::string m_name;
> +
> + bool
> + Read(Process *process, lldb::addr_t addr);
> + };
> +
> + struct class_rw_t {
> + uint32_t m_flags;
> + uint32_t m_version;
> +
> + lldb::addr_t m_ro_ptr;
> + union {
> + lldb::addr_t m_method_list_ptr;
> + lldb::addr_t m_method_lists_ptr;
> + };
> + lldb::addr_t m_properties_ptr;
> + lldb::addr_t m_protocols_ptr;
> +
> + ObjCLanguageRuntime::ObjCISA m_firstSubclass;
> + ObjCLanguageRuntime::ObjCISA m_nextSiblingClass;
> +
> + bool
> + Read(Process *process, lldb::addr_t addr);
> + };
> +
> + struct method_list_t
> + {
> + uint32_t m_entsize;
> + uint32_t m_count;
> + lldb::addr_t m_first_ptr;
> +
> + bool
> + Read(Process *process, lldb::addr_t addr);
> + };
> +
> + struct method_t
> + {
> + lldb::addr_t m_name_ptr;
> + lldb::addr_t m_types_ptr;
> + lldb::addr_t m_imp_ptr;
> +
> + std::string m_name;
> + std::string m_types;
> +
> + static size_t GetSize(Process *process)
> + {
> + size_t ptr_size = process->GetAddressByteSize();
> +
> + return ptr_size // SEL name;
> + + ptr_size // const char *types;
> + + ptr_size; // IMP imp;
> + }
> +
> + bool
> + Read(Process *process, lldb::addr_t addr);
> + };
> +
> + struct ivar_list_t
> + {
> + uint32_t m_entsize;
> + uint32_t m_count;
> + lldb::addr_t m_first_ptr;
> +
> + bool Read(Process *process, lldb::addr_t addr);
> + };
> +
> + struct ivar_t
> + {
> + lldb::addr_t m_offset_ptr;
> + lldb::addr_t m_name_ptr;
> + lldb::addr_t m_type_ptr;
> + uint32_t m_alignment;
> + uint32_t m_size;
> +
> + std::string m_name;
> + std::string m_type;
> +
> + static size_t GetSize(Process *process)
> + {
> + size_t ptr_size = process->GetAddressByteSize();
> +
> + return ptr_size // uintptr_t *offset;
> + + ptr_size // const char *name;
> + + ptr_size // const char *type;
> + + sizeof(uint32_t) // uint32_t alignment;
> + + sizeof(uint32_t); // uint32_t size;
> + }
> +
> + bool
> + Read(Process *process, lldb::addr_t addr);
> + };
> +
> + class iVarsStorage
> + {
> + public:
> + iVarsStorage ();
> +
> + size_t
> + size ();
> +
> + iVarDescriptor&
> + operator[] (size_t idx);
> +
> + void
> + fill (AppleObjCRuntimeV2& runtime, ClassDescriptorV2& descriptor);
> +
> + private:
> + bool m_filled;
> + std::vector<iVarDescriptor> m_ivars;
> + Mutex m_mutex;
> + };
> +
> + bool
> + Read_objc_class (Process* process, std::unique_ptr<objc_class_t>
> &objc_class) const;
> +
> + bool
> + Read_class_row (Process* process, const objc_class_t &objc_class,
> std::unique_ptr<class_ro_t> &class_ro, std::unique_ptr<class_rw_t>
> &class_rw) const;
> +
> + AppleObjCRuntimeV2 &m_runtime; // The runtime, so we can
> read information lazily.
> + lldb::addr_t m_objc_class_ptr; // The address of the
> objc_class_t. (I.e., objects of this class type have this as their ISA)
> + ConstString m_name; // May be NULL
> + iVarsStorage m_ivars_storage;
> +};
> +
> +// tagged pointer descriptor
> +class ClassDescriptorV2Tagged : public
> ObjCLanguageRuntime::ClassDescriptor
> +{
> +public:
> + ClassDescriptorV2Tagged (ConstString class_name,
> + uint64_t payload)
> + {
> + m_name = class_name;
> + if (!m_name)
> + {
> + m_valid = false;
> + return;
> + }
> + m_valid = true;
> + m_payload = payload;
> + m_info_bits = (m_payload & 0xF0ULL) >> 4;
> + m_value_bits = (m_payload & ~0x0000000000000000FFULL) >> 8;
> + }
> +
> + ClassDescriptorV2Tagged (ObjCLanguageRuntime::ClassDescriptorSP
> actual_class_sp,
> + uint64_t payload)
> + {
> + if (!actual_class_sp)
> + {
> + m_valid = false;
> + return;
> + }
> + m_name = actual_class_sp->GetClassName();
> + if (!m_name)
> + {
> + m_valid = false;
> + return;
> + }
> + m_valid = true;
> + m_payload = payload;
> + m_info_bits = (m_payload & 0x0FULL);
> + m_value_bits = (m_payload & ~0x0FULL) >> 4;
> + }
> +
> + virtual ConstString
> + GetClassName ()
> + {
> + return m_name;
> + }
> +
> + virtual ObjCLanguageRuntime::ClassDescriptorSP
> + GetSuperclass ()
> + {
> + // tagged pointers can represent a class that has a superclass,
> but since that information is not
> + // stored in the object itself, we would have to query the
> runtime to discover the hierarchy
> + // for the time being, we skip this step in the interest of
> static discovery
> + return ObjCLanguageRuntime::ClassDescriptorSP();
> + }
> +
> + virtual bool
> + IsValid ()
> + {
> + return m_valid;
> + }
> +
> + virtual bool
> + IsKVO ()
> + {
> + return false; // tagged pointers are not KVO'ed
> + }
> +
> + virtual bool
> + IsCFType ()
> + {
> + return false; // tagged pointers are not CF objects
> + }
> +
> + virtual bool
> + GetTaggedPointerInfo (uint64_t* info_bits = NULL,
> + uint64_t* value_bits = NULL,
> + uint64_t* payload = NULL)
> + {
> + if (info_bits)
> + *info_bits = GetInfoBits();
> + if (value_bits)
> + *value_bits = GetValueBits();
> + if (payload)
> + *payload = GetPayload();
> + return true;
> + }
> +
> + virtual uint64_t
> + GetInstanceSize ()
> + {
> + return (IsValid() ? m_pointer_size : 0);
> + }
> +
> + virtual ObjCLanguageRuntime::ObjCISA
> + GetISA ()
> + {
> + return 0; // tagged pointers have no ISA
> + }
> +
> + // these calls are not part of any formal tagged pointers
> specification
> + virtual uint64_t
> + GetValueBits ()
> + {
> + return (IsValid() ? m_value_bits : 0);
> + }
> +
> + virtual uint64_t
> + GetInfoBits ()
> + {
> + return (IsValid() ? m_info_bits : 0);
> + }
> +
> + virtual uint64_t
> + GetPayload ()
> + {
> + return (IsValid() ? m_payload : 0);
> + }
> +
> + virtual
> + ~ClassDescriptorV2Tagged ()
> + {}
> +
> +private:
> + ConstString m_name;
> + uint8_t m_pointer_size;
> + bool m_valid;
> + uint64_t m_info_bits;
> + uint64_t m_value_bits;
> + uint64_t m_payload;
> +
> +};
> +
> +} // namespace lldb_private
> +
> +#endif // liblldb_AppleObjCRuntime_h_
> +
>
> Modified:
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> ---
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
> (original)
> +++
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
> Tue Aug 19 16:46:37 2014
> @@ -42,9 +42,13 @@
> #include "lldb/Target/Thread.h"
>
> #include "AppleObjCRuntimeV2.h"
> +#include "AppleObjCClassDescriptorV2.h"
> +#include "AppleObjCTypeEncodingParser.h"
> #include "AppleObjCTypeVendor.h"
> #include "AppleObjCTrampolineHandler.h"
>
> +#include "clang/AST/ASTContext.h"
> +
> #include <vector>
>
> using namespace lldb;
> @@ -348,7 +352,8 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2 (
> m_has_object_getClass (false),
> m_loaded_objc_opt (false),
>
> m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this,objc_module_sp)),
> -
> m_tagged_pointer_vendor_ap(TaggedPointerVendor::CreateInstance(*this,objc_module_sp))
> +
> m_tagged_pointer_vendor_ap(TaggedPointerVendor::CreateInstance(*this,objc_module_sp)),
> + m_encoding_to_type_sp()
> {
> static const ConstString g_gdb_object_getClass("gdb_object_getClass");
> m_has_object_getClass =
> (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass,
> eSymbolTypeCode) != NULL);
> @@ -855,757 +860,6 @@ AppleObjCRuntimeV2::HashTableSignature::
> return true;
> }
>
> -class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
> -{
> -public:
> - friend class lldb_private::AppleObjCRuntimeV2;
> -
> -private:
> - // The constructor should only be invoked by the runtime as it builds
> its caches
> - // or populates them. A ClassDescriptorV2 should only ever exist in
> a cache.
> - ClassDescriptorV2 (AppleObjCRuntimeV2 &runtime,
> ObjCLanguageRuntime::ObjCISA isa, const char *name) :
> - m_runtime (runtime),
> - m_objc_class_ptr (isa),
> - m_name (name)
> - {
> - }
> -
> -public:
> - virtual ConstString
> - GetClassName ()
> - {
> - if (!m_name)
> - {
> - lldb_private::Process *process = m_runtime.GetProcess();
> -
> - if (process)
> - {
> - std::unique_ptr<objc_class_t> objc_class;
> - std::unique_ptr<class_ro_t> class_ro;
> - std::unique_ptr<class_rw_t> class_rw;
> -
> - if (!Read_objc_class(process, objc_class))
> - return m_name;
> - if (!Read_class_row(process, *objc_class, class_ro,
> class_rw))
> - return m_name;
> -
> - m_name = ConstString(class_ro->m_name.c_str());
> - }
> - }
> - return m_name;
> - }
> -
> - virtual ObjCLanguageRuntime::ClassDescriptorSP
> - GetSuperclass ()
> - {
> - lldb_private::Process *process = m_runtime.GetProcess();
> -
> - if (!process)
> - return ObjCLanguageRuntime::ClassDescriptorSP();
> -
> - std::unique_ptr<objc_class_t> objc_class;
> -
> - if (!Read_objc_class(process, objc_class))
> - return ObjCLanguageRuntime::ClassDescriptorSP();
> -
> - return
> m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(objc_class->m_superclass);
> - }
> -
> - virtual bool
> - IsValid ()
> - {
> - return true; // any Objective-C v2 runtime class descriptor we
> vend is valid
> - }
> -
> - // a custom descriptor is used for tagged pointers
> - virtual bool
> - GetTaggedPointerInfo (uint64_t* info_bits = NULL,
> - uint64_t* value_bits = NULL,
> - uint64_t* payload = NULL)
> - {
> - return false;
> - }
> -
> - virtual uint64_t
> - GetInstanceSize ()
> - {
> - lldb_private::Process *process = m_runtime.GetProcess();
> -
> - if (process)
> - {
> - std::unique_ptr<objc_class_t> objc_class;
> - std::unique_ptr<class_ro_t> class_ro;
> - std::unique_ptr<class_rw_t> class_rw;
> -
> - if (!Read_objc_class(process, objc_class))
> - return 0;
> - if (!Read_class_row(process, *objc_class, class_ro, class_rw))
> - return 0;
> -
> - return class_ro->m_instanceSize;
> - }
> -
> - return 0;
> - }
> -
> - virtual ObjCLanguageRuntime::ObjCISA
> - GetISA ()
> - {
> - return m_objc_class_ptr;
> - }
> -
> - virtual bool
> - Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const
> &superclass_func,
> - std::function <bool (const char *, const char *)> const
> &instance_method_func,
> - std::function <bool (const char *, const char *)> const
> &class_method_func,
> - std::function <bool (const char *, const char *,
> lldb::addr_t, uint64_t)> const &ivar_func)
> - {
> - lldb_private::Process *process = m_runtime.GetProcess();
> -
> - std::unique_ptr<objc_class_t> objc_class;
> - std::unique_ptr<class_ro_t> class_ro;
> - std::unique_ptr<class_rw_t> class_rw;
> -
> - if (!Read_objc_class(process, objc_class))
> - return 0;
> - if (!Read_class_row(process, *objc_class, class_ro, class_rw))
> - return 0;
> -
> - static ConstString NSObject_name("NSObject");
> -
> - if (m_name != NSObject_name && superclass_func)
> - superclass_func(objc_class->m_superclass);
> -
> - if (instance_method_func)
> - {
> - std::unique_ptr<method_list_t> base_method_list;
> -
> - base_method_list.reset(new method_list_t);
> - if (!base_method_list->Read(process,
> class_ro->m_baseMethods_ptr))
> - return false;
> -
> - if (base_method_list->m_entsize != method_t::GetSize(process))
> - return false;
> -
> - std::unique_ptr<method_t> method;
> - method.reset(new method_t);
> -
> - for (uint32_t i = 0, e = base_method_list->m_count; i < e;
> ++i)
> - {
> - method->Read(process, base_method_list->m_first_ptr + (i
> * base_method_list->m_entsize));
> -
> - if (instance_method_func(method->m_name.c_str(),
> method->m_types.c_str()))
> - break;
> - }
> - }
> -
> - if (class_method_func)
> - {
> - ClassDescriptorV2 metaclass(m_runtime, objc_class->m_isa,
> NULL); // The metaclass is not in the cache
> -
> - // We don't care about the metaclass's superclass, or its
> class methods. Its instance methods are
> - // our class methods.
> -
> - metaclass.Describe(std::function <void
> (ObjCLanguageRuntime::ObjCISA)> (nullptr),
> - class_method_func,
> - std::function <bool (const char *, const
> char *)> (nullptr),
> - std::function <bool (const char *, const
> char *, lldb::addr_t, uint64_t)> (nullptr));
> - }
> -
> - if (ivar_func)
> - {
> - ivar_list_t ivar_list;
> - if (!ivar_list.Read(process, class_ro->m_ivars_ptr))
> - return false;
> -
> - if (ivar_list.m_entsize != ivar_t::GetSize(process))
> - return false;
> -
> - ivar_t ivar;
> -
> - for (uint32_t i = 0, e = ivar_list.m_count; i < e; ++i)
> - {
> - ivar.Read(process, ivar_list.m_first_ptr + (i *
> ivar_list.m_entsize));
> -
> - if (ivar_func(ivar.m_name.c_str(), ivar.m_type.c_str(),
> ivar.m_offset_ptr, ivar.m_size))
> - break;
> - }
> - }
> -
> - return true;
> - }
> -
> - virtual
> - ~ClassDescriptorV2 ()
> - {
> - }
> -
> -private:
> - static const uint32_t RW_REALIZED = (1 << 31);
> -
> - struct objc_class_t {
> - ObjCLanguageRuntime::ObjCISA m_isa; // The
> class's metaclass.
> - ObjCLanguageRuntime::ObjCISA m_superclass;
> - lldb::addr_t m_cache_ptr;
> - lldb::addr_t m_vtable_ptr;
> - lldb::addr_t m_data_ptr;
> - uint8_t m_flags;
> -
> - objc_class_t () :
> - m_isa (0),
> - m_superclass (0),
> - m_cache_ptr (0),
> - m_vtable_ptr (0),
> - m_data_ptr (0),
> - m_flags (0)
> - {
> - }
> -
> - void
> - Clear()
> - {
> - m_isa = 0;
> - m_superclass = 0;
> - m_cache_ptr = 0;
> - m_vtable_ptr = 0;
> - m_data_ptr = 0;
> - m_flags = 0;
> - }
> -
> - bool Read(Process *process, lldb::addr_t addr)
> - {
> - size_t ptr_size = process->GetAddressByteSize();
> -
> - size_t objc_class_size = ptr_size // uintptr_t isa;
> - + ptr_size // Class superclass;
> - + ptr_size // void *cache;
> - + ptr_size // IMP *vtable;
> - + ptr_size; // uintptr_t data_NEVER_USE;
> -
> - DataBufferHeap objc_class_buf (objc_class_size, '\0');
> - Error error;
> -
> - process->ReadMemory(addr, objc_class_buf.GetBytes(),
> objc_class_size, error);
> - if (error.Fail())
> - {
> - return false;
> - }
> -
> - DataExtractor extractor(objc_class_buf.GetBytes(),
> objc_class_size, process->GetByteOrder(), process->GetAddressByteSize());
> -
> - lldb::offset_t cursor = 0;
> -
> - m_isa = extractor.GetAddress_unchecked(&cursor);
> // uintptr_t isa;
> - m_superclass = extractor.GetAddress_unchecked(&cursor);
> // Class superclass;
> - m_cache_ptr = extractor.GetAddress_unchecked(&cursor);
> // void *cache;
> - m_vtable_ptr = extractor.GetAddress_unchecked(&cursor);
> // IMP *vtable;
> - lldb::addr_t data_NEVER_USE =
> extractor.GetAddress_unchecked(&cursor); // uintptr_t data_NEVER_USE;
> -
> - m_flags = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3);
> - m_data_ptr = data_NEVER_USE & ~(lldb::addr_t)3;
> -
> - return true;
> - }
> - };
> -
> - struct class_ro_t {
> - uint32_t m_flags;
> - uint32_t m_instanceStart;
> - uint32_t m_instanceSize;
> - uint32_t m_reserved;
> -
> - lldb::addr_t m_ivarLayout_ptr;
> - lldb::addr_t m_name_ptr;
> - lldb::addr_t m_baseMethods_ptr;
> - lldb::addr_t m_baseProtocols_ptr;
> - lldb::addr_t m_ivars_ptr;
> -
> - lldb::addr_t m_weakIvarLayout_ptr;
> - lldb::addr_t m_baseProperties_ptr;
> -
> - std::string m_name;
> -
> - bool Read(Process *process, lldb::addr_t addr)
> - {
> - size_t ptr_size = process->GetAddressByteSize();
> -
> - size_t size = sizeof(uint32_t) // uint32_t flags;
> - + sizeof(uint32_t) // uint32_t
> instanceStart;
> - + sizeof(uint32_t) // uint32_t
> instanceSize;
> - + (ptr_size == 8 ? sizeof(uint32_t) : 0) // uint32_t
> reserved; // __LP64__ only
> - + ptr_size // const uint8_t
> *ivarLayout;
> - + ptr_size // const char
> *name;
> - + ptr_size // const
> method_list_t *baseMethods;
> - + ptr_size // const
> protocol_list_t *baseProtocols;
> - + ptr_size // const
> ivar_list_t *ivars;
> - + ptr_size // const uint8_t
> *weakIvarLayout;
> - + ptr_size; // const
> property_list_t *baseProperties;
> -
> - DataBufferHeap buffer (size, '\0');
> - Error error;
> -
> - process->ReadMemory(addr, buffer.GetBytes(), size, error);
> - if (error.Fail())
> - {
> - return false;
> - }
> -
> - DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> -
> - lldb::offset_t cursor = 0;
> -
> - m_flags = extractor.GetU32_unchecked(&cursor);
> - m_instanceStart = extractor.GetU32_unchecked(&cursor);
> - m_instanceSize = extractor.GetU32_unchecked(&cursor);
> - if (ptr_size == 8)
> - m_reserved = extractor.GetU32_unchecked(&cursor);
> - else
> - m_reserved = 0;
> - m_ivarLayout_ptr =
> extractor.GetAddress_unchecked(&cursor);
> - m_name_ptr =
> extractor.GetAddress_unchecked(&cursor);
> - m_baseMethods_ptr =
> extractor.GetAddress_unchecked(&cursor);
> - m_baseProtocols_ptr =
> extractor.GetAddress_unchecked(&cursor);
> - m_ivars_ptr =
> extractor.GetAddress_unchecked(&cursor);
> - m_weakIvarLayout_ptr =
> extractor.GetAddress_unchecked(&cursor);
> - m_baseProperties_ptr =
> extractor.GetAddress_unchecked(&cursor);
> -
> - DataBufferHeap name_buf(1024, '\0');
> -
> - process->ReadCStringFromMemory(m_name_ptr,
> (char*)name_buf.GetBytes(), name_buf.GetByteSize(), error);
> -
> - if (error.Fail())
> - {
> - return false;
> - }
> -
> - m_name.assign((char*)name_buf.GetBytes());
> -
> - return true;
> - }
> - };
> -
> - struct class_rw_t {
> - uint32_t m_flags;
> - uint32_t m_version;
> -
> - lldb::addr_t m_ro_ptr;
> - union {
> - lldb::addr_t m_method_list_ptr;
> - lldb::addr_t m_method_lists_ptr;
> - };
> - lldb::addr_t m_properties_ptr;
> - lldb::addr_t m_protocols_ptr;
> -
> - ObjCLanguageRuntime::ObjCISA m_firstSubclass;
> - ObjCLanguageRuntime::ObjCISA m_nextSiblingClass;
> -
> - bool Read(Process *process, lldb::addr_t addr)
> - {
> - size_t ptr_size = process->GetAddressByteSize();
> -
> - size_t size = sizeof(uint32_t) // uint32_t flags;
> - + sizeof(uint32_t) // uint32_t version;
> - + ptr_size // const class_ro_t *ro;
> - + ptr_size // union { method_list_t **method_lists;
> method_list_t *method_list; };
> - + ptr_size // struct chained_property_list
> *properties;
> - + ptr_size // const protocol_list_t **protocols;
> - + ptr_size // Class firstSubclass;
> - + ptr_size; // Class nextSiblingClass;
> -
> - DataBufferHeap buffer (size, '\0');
> - Error error;
> -
> - process->ReadMemory(addr, buffer.GetBytes(), size, error);
> - if (error.Fail())
> - {
> - return false;
> - }
> -
> - DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> -
> - lldb::offset_t cursor = 0;
> -
> - m_flags = extractor.GetU32_unchecked(&cursor);
> - m_version = extractor.GetU32_unchecked(&cursor);
> - m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
> - m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
> - m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
> - m_firstSubclass = extractor.GetAddress_unchecked(&cursor);
> - m_nextSiblingClass = extractor.GetAddress_unchecked(&cursor);
> -
> - return true;
> - }
> - };
> -
> - struct method_list_t
> - {
> - uint32_t m_entsize;
> - uint32_t m_count;
> - lldb::addr_t m_first_ptr;
> -
> - bool Read(Process *process, lldb::addr_t addr)
> - {
> - size_t size = sizeof(uint32_t) // uint32_t entsize_NEVER_USE;
> - + sizeof(uint32_t); // uint32_t count;
> -
> - DataBufferHeap buffer (size, '\0');
> - Error error;
> -
> - process->ReadMemory(addr, buffer.GetBytes(), size, error);
> - if (error.Fail())
> - {
> - return false;
> - }
> -
> - DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> -
> - lldb::offset_t cursor = 0;
> -
> - m_entsize = extractor.GetU32_unchecked(&cursor) &
> ~(uint32_t)3;
> - m_count = extractor.GetU32_unchecked(&cursor);
> - m_first_ptr = addr + cursor;
> -
> - return true;
> - }
> - };
> -
> - struct method_t
> - {
> - lldb::addr_t m_name_ptr;
> - lldb::addr_t m_types_ptr;
> - lldb::addr_t m_imp_ptr;
> -
> - std::string m_name;
> - std::string m_types;
> -
> - static size_t GetSize(Process *process)
> - {
> - size_t ptr_size = process->GetAddressByteSize();
> -
> - return ptr_size // SEL name;
> - + ptr_size // const char *types;
> - + ptr_size; // IMP imp;
> - }
> -
> - bool Read(Process *process, lldb::addr_t addr)
> - {
> - size_t size = GetSize(process);
> -
> - DataBufferHeap buffer (size, '\0');
> - Error error;
> -
> - process->ReadMemory(addr, buffer.GetBytes(), size, error);
> - if (error.Fail())
> - {
> - return false;
> - }
> -
> - DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> -
> - lldb::offset_t cursor = 0;
> -
> - m_name_ptr = extractor.GetAddress_unchecked(&cursor);
> - m_types_ptr = extractor.GetAddress_unchecked(&cursor);
> - m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
> -
> - const size_t buffer_size = 1024;
> - size_t count;
> -
> - DataBufferHeap string_buf(buffer_size, 0);
> -
> - count = process->ReadCStringFromMemory(m_name_ptr,
> (char*)string_buf.GetBytes(), buffer_size, error);
> - m_name.assign((char*)string_buf.GetBytes(), count);
> -
> - count = process->ReadCStringFromMemory(m_types_ptr,
> (char*)string_buf.GetBytes(), buffer_size, error);
> - m_types.assign((char*)string_buf.GetBytes(), count);
> -
> - return true;
> - }
> - };
> -
> - struct ivar_list_t
> - {
> - uint32_t m_entsize;
> - uint32_t m_count;
> - lldb::addr_t m_first_ptr;
> -
> - bool Read(Process *process, lldb::addr_t addr)
> - {
> - size_t size = sizeof(uint32_t) // uint32_t entsize;
> - + sizeof(uint32_t); // uint32_t count;
> -
> - DataBufferHeap buffer (size, '\0');
> - Error error;
> -
> - process->ReadMemory(addr, buffer.GetBytes(), size, error);
> - if (error.Fail())
> - {
> - return false;
> - }
> -
> - DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> -
> - lldb::offset_t cursor = 0;
> -
> - m_entsize = extractor.GetU32_unchecked(&cursor);
> - m_count = extractor.GetU32_unchecked(&cursor);
> - m_first_ptr = addr + cursor;
> -
> - return true;
> - }
> - };
> -
> - struct ivar_t
> - {
> - lldb::addr_t m_offset_ptr;
> - lldb::addr_t m_name_ptr;
> - lldb::addr_t m_type_ptr;
> - uint32_t m_alignment;
> - uint32_t m_size;
> -
> - std::string m_name;
> - std::string m_type;
> -
> - static size_t GetSize(Process *process)
> - {
> - size_t ptr_size = process->GetAddressByteSize();
> -
> - return ptr_size // uintptr_t *offset;
> - + ptr_size // const char *name;
> - + ptr_size // const char *type;
> - + sizeof(uint32_t) // uint32_t alignment;
> - + sizeof(uint32_t); // uint32_t size;
> - }
> -
> - bool Read(Process *process, lldb::addr_t addr)
> - {
> - size_t size = GetSize(process);
> -
> - DataBufferHeap buffer (size, '\0');
> - Error error;
> -
> - process->ReadMemory(addr, buffer.GetBytes(), size, error);
> - if (error.Fail())
> - {
> - return false;
> - }
> -
> - DataExtractor extractor(buffer.GetBytes(), size,
> process->GetByteOrder(), process->GetAddressByteSize());
> -
> - lldb::offset_t cursor = 0;
> -
> - m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
> - m_name_ptr = extractor.GetAddress_unchecked(&cursor);
> - m_type_ptr = extractor.GetAddress_unchecked(&cursor);
> - m_alignment = extractor.GetU32_unchecked(&cursor);
> - m_size = extractor.GetU32_unchecked(&cursor);
> -
> - const size_t buffer_size = 1024;
> - size_t count;
> -
> - DataBufferHeap string_buf(buffer_size, 0);
> -
> - count = process->ReadCStringFromMemory(m_name_ptr,
> (char*)string_buf.GetBytes(), buffer_size, error);
> - m_name.assign((char*)string_buf.GetBytes(), count);
> -
> - count = process->ReadCStringFromMemory(m_type_ptr,
> (char*)string_buf.GetBytes(), buffer_size, error);
> - m_type.assign((char*)string_buf.GetBytes(), count);
> -
> - return true;
> - }
> - };
> -
> - bool Read_objc_class (Process* process, std::unique_ptr<objc_class_t>
> &objc_class)
> - {
> - objc_class.reset(new objc_class_t);
> -
> - bool ret = objc_class->Read (process, m_objc_class_ptr);
> -
> - if (!ret)
> - objc_class.reset();
> -
> - return ret;
> - }
> -
> - bool Read_class_row (Process* process, const objc_class_t
> &objc_class, std::unique_ptr<class_ro_t> &class_ro,
> std::unique_ptr<class_rw_t> &class_rw)
> - {
> - class_ro.reset();
> - class_rw.reset();
> -
> - Error error;
> - uint32_t class_row_t_flags =
> process->ReadUnsignedIntegerFromMemory(objc_class.m_data_ptr,
> sizeof(uint32_t), 0, error);
> - if (!error.Success())
> - return false;
> -
> - if (class_row_t_flags & RW_REALIZED)
> - {
> - class_rw.reset(new class_rw_t);
> -
> - if (!class_rw->Read(process, objc_class.m_data_ptr))
> - {
> - class_rw.reset();
> - return false;
> - }
> -
> - class_ro.reset(new class_ro_t);
> -
> - if (!class_ro->Read(process, class_rw->m_ro_ptr))
> - {
> - class_rw.reset();
> - class_ro.reset();
> - return false;
> - }
> - }
> - else
> - {
> - class_ro.reset(new class_ro_t);
> -
> - if (!class_ro->Read(process, objc_class.m_data_ptr))
> - {
> - class_ro.reset();
> - return false;
> - }
> - }
> -
> - return true;
> - }
> -
> - AppleObjCRuntimeV2 &m_runtime; // The runtime, so we can
> read information lazily.
> - lldb::addr_t m_objc_class_ptr; // The address of the
> objc_class_t. (I.e., objects of this class type have this as their ISA)
> - ConstString m_name; // May be NULL
> -};
> -
> -// tagged pointer descriptor
> -class ClassDescriptorV2Tagged : public
> ObjCLanguageRuntime::ClassDescriptor
> -{
> -public:
> - ClassDescriptorV2Tagged (ConstString class_name,
> - uint64_t payload)
> - {
> - m_name = class_name;
> - if (!m_name)
> - {
> - m_valid = false;
> - return;
> - }
> - m_valid = true;
> - m_payload = payload;
> - m_info_bits = (m_payload & 0xF0ULL) >> 4;
> - m_value_bits = (m_payload & ~0x0000000000000000FFULL) >> 8;
> - }
> -
> - ClassDescriptorV2Tagged (ObjCLanguageRuntime::ClassDescriptorSP
> actual_class_sp,
> - uint64_t payload)
> - {
> - if (!actual_class_sp)
> - {
> - m_valid = false;
> - return;
> - }
> - m_name = actual_class_sp->GetClassName();
> - if (!m_name)
> - {
> - m_valid = false;
> - return;
> - }
> - m_valid = true;
> - m_payload = payload;
> - m_info_bits = (m_payload & 0x0FULL);
> - m_value_bits = (m_payload & ~0x0FULL) >> 4;
> - }
> -
> - virtual ConstString
> - GetClassName ()
> - {
> - return m_name;
> - }
> -
> - virtual ObjCLanguageRuntime::ClassDescriptorSP
> - GetSuperclass ()
> - {
> - // tagged pointers can represent a class that has a superclass,
> but since that information is not
> - // stored in the object itself, we would have to query the
> runtime to discover the hierarchy
> - // for the time being, we skip this step in the interest of
> static discovery
> - return ObjCLanguageRuntime::ClassDescriptorSP();
> - }
> -
> - virtual bool
> - IsValid ()
> - {
> - return m_valid;
> - }
> -
> - virtual bool
> - IsKVO ()
> - {
> - return false; // tagged pointers are not KVO'ed
> - }
> -
> - virtual bool
> - IsCFType ()
> - {
> - return false; // tagged pointers are not CF objects
> - }
> -
> - virtual bool
> - GetTaggedPointerInfo (uint64_t* info_bits = NULL,
> - uint64_t* value_bits = NULL,
> - uint64_t* payload = NULL)
> - {
> - if (info_bits)
> - *info_bits = GetInfoBits();
> - if (value_bits)
> - *value_bits = GetValueBits();
> - if (payload)
> - *payload = GetPayload();
> - return true;
> - }
> -
> - virtual uint64_t
> - GetInstanceSize ()
> - {
> - return (IsValid() ? m_pointer_size : 0);
> - }
> -
> - virtual ObjCLanguageRuntime::ObjCISA
> - GetISA ()
> - {
> - return 0; // tagged pointers have no ISA
> - }
> -
> - // these calls are not part of any formal tagged pointers
> specification
> - virtual uint64_t
> - GetValueBits ()
> - {
> - return (IsValid() ? m_value_bits : 0);
> - }
> -
> - virtual uint64_t
> - GetInfoBits ()
> - {
> - return (IsValid() ? m_info_bits : 0);
> - }
> -
> - virtual uint64_t
> - GetPayload ()
> - {
> - return (IsValid() ? m_payload : 0);
> - }
> -
> - virtual
> - ~ClassDescriptorV2Tagged ()
> - {}
> -
> -private:
> - ConstString m_name;
> - uint8_t m_pointer_size;
> - bool m_valid;
> - uint64_t m_info_bits;
> - uint64_t m_value_bits;
> - uint64_t m_payload;
> -
> -};
> -
> ObjCLanguageRuntime::ClassDescriptorSP
> AppleObjCRuntimeV2::GetClassDescriptorFromISA (ObjCISA isa)
> {
> @@ -1621,6 +875,18 @@ ObjCLanguageRuntime::ClassDescriptorSP
> AppleObjCRuntimeV2::GetClassDescriptor (ValueObject& valobj)
> {
> ClassDescriptorSP objc_class_sp;
> + if (valobj.IsBaseClass())
> + {
> + ValueObject *parent = valobj.GetParent();
> + // if I am my own parent, bail out of here fast..
> + if (parent && parent != &valobj)
> + {
> + ClassDescriptorSP parent_descriptor_sp =
> GetClassDescriptor(*parent);
> + if (parent_descriptor_sp)
> + return parent_descriptor_sp->GetSuperclass();
> + }
> + return nullptr;
> + }
> // if we get an invalid VO (which might still happen when playing
> around
> // with pointers returned by the expression parser, don't consider
> this
> // a valid ObjC object)
> @@ -2651,3 +1917,11 @@ AppleObjCRuntimeV2::NonPointerISACache::
> }
> return false;
> }
> +
> +ObjCLanguageRuntime::EncodingToTypeSP
> +AppleObjCRuntimeV2::GetEncodingToType ()
> +{
> + if (!m_encoding_to_type_sp)
> + m_encoding_to_type_sp.reset(new
> AppleObjCTypeEncodingParser(*this));
> + return m_encoding_to_type_sp;
> +}
>
> Modified:
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> ---
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
> (original)
> +++
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
> Tue Aug 19 16:46:37 2014
> @@ -105,6 +105,9 @@ public:
> virtual lldb::addr_t
> LookupRuntimeSymbol (const ConstString &name);
>
> + virtual EncodingToTypeSP
> + GetEncodingToType ();
> +
> protected:
> virtual lldb::BreakpointResolverSP
> CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool
> throw_bp);
> @@ -277,6 +280,7 @@ private:
> bool m_loaded_objc_opt;
> std::unique_ptr<NonPointerISACache> m_non_pointer_isa_cache_ap;
> std::unique_ptr<TaggedPointerVendor> m_tagged_pointer_vendor_ap;
> + EncodingToTypeSP m_encoding_to_type_sp;
> };
>
> } // namespace lldb_private
>
> Added:
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp?rev=216026&view=auto
>
> ==============================================================================
> ---
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
> (added)
> +++
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
> Tue Aug 19 16:46:37 2014
> @@ -0,0 +1,275 @@
> +//===-- AppleObjCTypeEncodingParser.cpp -------------------------*- C++
> -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "AppleObjCTypeEncodingParser.h"
> +
> +#include "lldb/Symbol/ClangASTContext.h"
> +#include "lldb/Symbol/ClangASTType.h"
> +#include "lldb/Target/Process.h"
> +#include "lldb/Target/Target.h"
> +#include "lldb/Utility/StringLexer.h"
> +
> +#include <vector>
> +
> +using namespace lldb_private;
> +using namespace lldb_utility;
> +
> +AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser
> (ObjCLanguageRuntime& runtime) :
> +ObjCLanguageRuntime::EncodingToType()
> +{
> + if (!m_scratch_ast_ctx_ap)
> + m_scratch_ast_ctx_ap.reset(new
> ClangASTContext(runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple().str().c_str()));
> +}
> +
> +std::string
> +AppleObjCTypeEncodingParser::ReadStructName(lldb_utility::StringLexer&
> type)
> +{
> + StreamString buffer;
> + while (type.HasAtLeast(1) && type.Peek() != '=')
> + buffer.Printf("%c",type.Next());
> + return buffer.GetString();
> +}
> +
> +std::string
> +AppleObjCTypeEncodingParser::ReadStructElementName(lldb_utility::StringLexer&
> type)
> +{
> + StreamString buffer;
> + while (type.HasAtLeast(1) && type.Peek() != '"')
> + buffer.Printf("%c",type.Next());
> + return buffer.GetString();
> +}
> +
> +uint
> +AppleObjCTypeEncodingParser::ReadNumber (lldb_utility::StringLexer& type)
> +{
> + uint total = 0;
> + while (type.HasAtLeast(1) && isdigit(type.Peek()))
> + total = 10*total + (type.Next() - '0');
> + return total;
> +}
> +
> +// as an extension to the published grammar recent runtimes emit structs
> like this:
> +//
> "{CGRect=\"origin\"{CGPoint=\"x\"d\"y\"d}\"size\"{CGSize=\"width\"d\"height\"d}}"
> +
> +AppleObjCTypeEncodingParser::StructElement::StructElement() :
> +name(""),
> +type(clang::QualType()),
> +bitfield(0)
> +{}
> +
> +AppleObjCTypeEncodingParser::StructElement
> +AppleObjCTypeEncodingParser::ReadStructElement (clang::ASTContext
> &ast_ctx, lldb_utility::StringLexer& type, bool allow_unknownanytype)
> +{
> + StructElement retval;
> + if (type.NextIf('"'))
> + retval.name = ReadStructElementName(type);
> + if (!type.NextIf('"'))
> + return retval;
> + uint32_t bitfield_size = 0;
> + retval.type = BuildType(ast_ctx, type, allow_unknownanytype,
> &bitfield_size);
> + retval.bitfield = bitfield_size;
> + return retval;
> +}
> +
> +clang::QualType
> +AppleObjCTypeEncodingParser::BuildStruct (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype)
> +{
> + return BuildAggregate(ast_ctx, type, allow_unknownanytype, '{', '}',
> clang::TTK_Struct);
> +}
> +
> +clang::QualType
> +AppleObjCTypeEncodingParser::BuildUnion (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype)
> +{
> + return BuildAggregate(ast_ctx, type, allow_unknownanytype, '(', ')',
> clang::TTK_Union);
> +}
> +
> +clang::QualType
> +AppleObjCTypeEncodingParser::BuildAggregate (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype, char opener,
> char closer, uint kind)
> +{
> + if (!type.NextIf(opener))
> + return clang::QualType();
> + std::string name(ReadStructName(type));
> + if (!type.NextIf('='))
> + return clang::QualType();
> + bool in_union = true;
> + std::vector<StructElement> elements;
> + while (in_union && type.HasAtLeast(1))
> + {
> + if (type.NextIf(closer))
> + {
> + in_union = false;
> + break;
> + }
> + else
> + {
> + auto element = ReadStructElement(ast_ctx, type,
> allow_unknownanytype);
> + if (element.type.isNull())
> + break;
> + else
> + elements.push_back(element);
> + }
> + }
> + if (in_union)
> + return clang::QualType();
> + ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
> + if (!lldb_ctx)
> + return clang::QualType();
> + ClangASTType union_type(lldb_ctx->CreateRecordType(nullptr,
> lldb::eAccessPublic, name.c_str(), kind, lldb::eLanguageTypeC));
> + if (union_type)
> + {
> + union_type.StartTagDeclarationDefinition();
> +
> + unsigned int count = 0;
> + for (auto element: elements)
> + {
> + if (element.name.empty())
> + {
> + StreamString elem_name;
> + elem_name.Printf("__unnamed_%u",count);
> + element.name = std::string(elem_name.GetData());
> + }
> + union_type.AddFieldToRecordType(element.name.c_str(),
> ClangASTType(&ast_ctx,element.type.getAsOpaquePtr()), lldb::eAccessPublic,
> element.bitfield);
> + ++count;
> + }
> +
> + union_type.CompleteTagDeclarationDefinition();
> + }
> + return union_type.GetQualType();
> +}
> +
> +clang::QualType
> +AppleObjCTypeEncodingParser::BuildArray (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype)
> +{
> + if (!type.NextIf('['))
> + return clang::QualType();
> + uint size = ReadNumber(type);
> + clang::QualType element_type(BuildType(ast_ctx, type,
> allow_unknownanytype));
> + if (!type.NextIf(']'))
> + return clang::QualType();
> + ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
> + if (!lldb_ctx)
> + return clang::QualType();
> + ClangASTType
> array_type(lldb_ctx->CreateArrayType(ClangASTType(&ast_ctx,element_type.getAsOpaquePtr()),
> size, false));
> + return array_type.GetQualType();
> +}
> +
> +clang::QualType
> +AppleObjCTypeEncodingParser::BuildType (clang::ASTContext &ast_ctx,
> StringLexer& type, bool allow_unknownanytype, uint32_t *bitfield_bit_size)
> +{
> + if (!type.HasAtLeast(1))
> + return clang::QualType();
> +
> + if (type.NextIf('c'))
> + return ast_ctx.CharTy;
> + if (type.NextIf('i'))
> + return ast_ctx.IntTy;
> + if (type.NextIf('s'))
> + return ast_ctx.ShortTy;
> + if (type.NextIf('l'))
> + {
> + ClangASTContext *lldb_ctx =
> ClangASTContext::GetASTContext(&ast_ctx);
> + if (!lldb_ctx)
> + return clang::QualType();
> + return lldb_ctx->GetIntTypeFromBitSize(32, true).GetQualType();
> + }
> + if (type.NextIf('q'))
> + return ast_ctx.LongLongTy;
> + if (type.NextIf('C'))
> + return ast_ctx.UnsignedCharTy;
> + if (type.NextIf('I'))
> + return ast_ctx.UnsignedIntTy;
> + if (type.NextIf('S'))
> + return ast_ctx.UnsignedShortTy;
> + if (type.NextIf('L'))
> + {
> + ClangASTContext *lldb_ctx =
> ClangASTContext::GetASTContext(&ast_ctx);
> + if (!lldb_ctx)
> + return clang::QualType();
> + return lldb_ctx->GetIntTypeFromBitSize(32, false).GetQualType();
> + }
> + if (type.NextIf('Q'))
> + return ast_ctx.UnsignedLongLongTy;
> + if (type.NextIf('f'))
> + return ast_ctx.FloatTy;
> + if (type.NextIf('d'))
> + return ast_ctx.DoubleTy;
> + if (type.NextIf('B'))
> + return ast_ctx.BoolTy;
> + if (type.NextIf('v'))
> + return ast_ctx.VoidTy;
> + if (type.NextIf('*'))
> + return ast_ctx.getPointerType(ast_ctx.CharTy);
> + if (type.NextIf('@'))
> + return ast_ctx.getObjCIdType();
> + if (type.NextIf('#'))
> + return ast_ctx.getObjCClassType();
> + if (type.NextIf(':'))
> + return ast_ctx.getObjCSelType();
> +
> + if (type.NextIf('b'))
> + {
> + uint size = ReadNumber(type);
> + if (bitfield_bit_size)
> + {
> + *bitfield_bit_size = size;
> + return ast_ctx.UnsignedIntTy; // FIXME: the spec is fairly
> vague here.
> + }
> + else
> + return clang::QualType();
> + }
> +
> + if (type.NextIf('r'))
> + {
> + clang::QualType target_type = BuildType(ast_ctx, type,
> allow_unknownanytype);
> + if (target_type.isNull())
> + return clang::QualType();
> + else if (target_type == ast_ctx.UnknownAnyTy)
> + return ast_ctx.UnknownAnyTy;
> + else
> + return ast_ctx.getConstType(target_type);
> + }
> +
> + if (type.NextIf('^'))
> + {
> + clang::QualType target_type = BuildType(ast_ctx, type,
> allow_unknownanytype);
> + if (target_type.isNull())
> + return clang::QualType();
> + else if (target_type == ast_ctx.UnknownAnyTy)
> + return ast_ctx.UnknownAnyTy;
> + else
> + return ast_ctx.getPointerType(target_type);
> + }
> +
> + if (type.NextIf('?'))
> + return allow_unknownanytype ? ast_ctx.UnknownAnyTy :
> clang::QualType();
> +
> + if (type.Peek() == '{')
> + return BuildStruct(ast_ctx, type, allow_unknownanytype);
> +
> + if (type.Peek() == '[')
> + return BuildArray(ast_ctx, type, allow_unknownanytype);
> +
> + if (type.Peek() == '(')
> + return BuildUnion(ast_ctx, type, allow_unknownanytype);
> +
> + return clang::QualType();
> +}
> +
> +ClangASTType
> +AppleObjCTypeEncodingParser::RealizeType (clang::ASTContext &ast_ctx,
> const char* name, bool allow_unknownanytype)
> +{
> + if (name && name[0])
> + {
> + StringLexer lexer(name);
> + clang::QualType qual_type = BuildType(ast_ctx, lexer,
> allow_unknownanytype);
> + return ClangASTType(&ast_ctx, qual_type.getAsOpaquePtr());
> + }
> + return ClangASTType();
> +}
> +
>
> Added:
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h?rev=216026&view=auto
>
> ==============================================================================
> ---
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
> (added)
> +++
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
> Tue Aug 19 16:46:37 2014
> @@ -0,0 +1,78 @@
> +//===-- AppleObjCTypeEncodingParser.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_AppleObjCTypeEncodingParser_h_
> +#define liblldb_AppleObjCTypeEncodingParser_h_
> +
> +// C Includes
> +// C++ Includes
> +
> +// Other libraries and framework includes
> +
> +// Project includes
> +#include "lldb/lldb-private.h"
> +#include "lldb/Target/ObjCLanguageRuntime.h"
> +
> +#include "clang/AST/ASTContext.h"
> +
> +namespace lldb_utility {
> + class StringLexer;
> +}
> +
> +namespace lldb_private {
> +
> + class AppleObjCTypeEncodingParser : public
> ObjCLanguageRuntime::EncodingToType
> + {
> + public:
> + AppleObjCTypeEncodingParser (ObjCLanguageRuntime& runtime);
> + virtual ClangASTType RealizeType (clang::ASTContext &ast_ctx,
> const char* name, bool allow_unknownanytype);
> + virtual ~AppleObjCTypeEncodingParser() {}
> +
> + private:
> + struct StructElement {
> + std::string name;
> + clang::QualType type;
> + uint32_t bitfield;
> +
> + StructElement ();
> + ~StructElement () = default;
> + };
> +
> + clang::QualType
> + BuildType (clang::ASTContext &ast_ctx, lldb_utility::StringLexer&
> type, bool allow_unknownanytype, uint32_t *bitfield_bit_size = nullptr);
> +
> + clang::QualType
> + BuildStruct (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype);
> +
> + clang::QualType
> + BuildAggregate (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype, char opener,
> char closer, uint kind);
> +
> + clang::QualType
> + BuildUnion (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype);
> +
> + clang::QualType
> + BuildArray (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype);
> +
> + std::string
> + ReadStructName(lldb_utility::StringLexer& type);
> +
> + StructElement
> + ReadStructElement (clang::ASTContext &ast_ctx,
> lldb_utility::StringLexer& type, bool allow_unknownanytype);
> +
> + std::string
> + ReadStructElementName(lldb_utility::StringLexer& type);
> +
> + uint
> + ReadNumber (lldb_utility::StringLexer& type);
> +
> + };
> +
> +} // namespace lldb_private
> +
> +#endif // liblldb_AppleObjCTypeEncodingParser_h_
>
> Modified:
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> ---
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
> (original)
> +++
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
> Tue Aug 19 16:46:37 2014
> @@ -164,7 +164,8 @@ private:
> AppleObjCTypeVendor::AppleObjCTypeVendor(ObjCLanguageRuntime &runtime) :
> TypeVendor(),
> m_runtime(runtime),
> -
> m_ast_ctx(runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple().getTriple().c_str())
> +
> m_ast_ctx(runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple().getTriple().c_str()),
> + m_type_realizer_sp(m_runtime.GetEncodingToType())
> {
> m_external_source = new AppleObjCExternalASTSource (*this);
> llvm::IntrusiveRefCntPtr<clang::ExternalASTSource>
> external_source_owning_ptr (m_external_source);
> @@ -323,7 +324,7 @@ public:
> }
> }
>
> - clang::ObjCMethodDecl *BuildMethod (clang::ObjCInterfaceDecl
> *interface_decl, const char *name, bool instance)
> + clang::ObjCMethodDecl *BuildMethod (clang::ObjCInterfaceDecl
> *interface_decl, const char *name, bool instance,
> ObjCLanguageRuntime::EncodingToTypeSP type_realizer_sp)
> {
> if (!m_is_valid || m_type_vector.size() < 3)
> return NULL;
> @@ -339,12 +340,14 @@ public:
> const bool isDefined = false;
> const clang::ObjCMethodDecl::ImplementationControl impControl =
> clang::ObjCMethodDecl::None;
> const bool HasRelatedResultType = false;
> + const bool allow_unknownanytype = true;
>
> std::vector <clang::IdentifierInfo *> selector_components;
>
> const char *name_cursor = name;
> bool is_zero_argument = true;
>
> +
> while (*name_cursor != '\0')
> {
> const char *colon_loc = strchr(name_cursor, ':');
> @@ -363,7 +366,7 @@ public:
>
> clang::Selector sel =
> ast_ctx.Selectors.getSelector(is_zero_argument ? 0 :
> selector_components.size(), selector_components.data());
>
> - clang::QualType ret_type = BuildType(ast_ctx,
> m_type_vector[0].c_str());
> + clang::QualType ret_type =
> type_realizer_sp->RealizeType(interface_decl->getASTContext(),
> m_type_vector[0].c_str(), allow_unknownanytype).GetQualType();
>
> if (ret_type.isNull())
> return NULL;
> @@ -389,7 +392,8 @@ public:
> ai != ae;
> ++ai)
> {
> - clang::QualType arg_type = BuildType(ast_ctx,
> m_type_vector[ai].c_str());
> + const bool allow_unknownanytype = true;
> + clang::QualType arg_type =
> type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(),
> allow_unknownanytype).GetQualType();
>
> if (arg_type.isNull())
> return NULL; // well, we just wasted a bunch of time.
> Wish we could delete the stuff we'd just made!
> @@ -410,81 +414,6 @@ public:
> return ret;
> }
> private:
> - clang::QualType BuildType (clang::ASTContext &ast_ctx, const char
> *type)
> - {
> - if (!type)
> - return clang::QualType();
> -
> - switch (*type)
> - {
> - default:
> - return ast_ctx.UnknownAnyTy;
> - case 'r':
> - {
> - clang::QualType target_type = BuildType(ast_ctx, type+1);
> - if (target_type.isNull())
> - return clang::QualType();
> - else if (target_type == ast_ctx.UnknownAnyTy)
> - return ast_ctx.UnknownAnyTy;
> - else
> - return ast_ctx.getConstType(target_type);
> - }
> - case '^':
> - {
> - clang::QualType target_type = BuildType(ast_ctx, type+1);
> - if (target_type.isNull())
> - return clang::QualType();
> - else if (target_type == ast_ctx.UnknownAnyTy)
> - return ast_ctx.UnknownAnyTy;
> - else
> - return ast_ctx.getPointerType(target_type);
> - }
> - case 'c':
> - return ast_ctx.CharTy;
> - case 'i':
> - return ast_ctx.IntTy;
> - case 's':
> - return ast_ctx.ShortTy;
> - case 'l':
> - if (ast_ctx.getTypeSize(ast_ctx.VoidTy) == 64)
> - return ast_ctx.IntTy;
> - else
> - return ast_ctx.LongTy;
> - case 'q':
> - return ast_ctx.LongLongTy;
> - case 'C':
> - return ast_ctx.UnsignedCharTy;
> - case 'I':
> - return ast_ctx.UnsignedIntTy;
> - case 'S':
> - return ast_ctx.UnsignedShortTy;
> - case 'L':
> - if (ast_ctx.getTypeSize(ast_ctx.VoidTy) == 64)
> - return ast_ctx.UnsignedIntTy;
> - else
> - return ast_ctx.UnsignedLongTy;
> - case 'Q':
> - return ast_ctx.UnsignedLongLongTy;
> - case 'f':
> - return ast_ctx.FloatTy;
> - case 'd':
> - return ast_ctx.DoubleTy;
> - case 'B':
> - return ast_ctx.BoolTy;
> - case 'v':
> - return ast_ctx.VoidTy;
> - case '*':
> - return ast_ctx.getPointerType(ast_ctx.CharTy);
> - case '@':
> - return ast_ctx.getObjCIdType();
> - case '#':
> - return ast_ctx.getObjCClassType();
> - case ':':
> - return ast_ctx.getObjCSelType();
> - }
> - return clang::QualType();
> - }
> -
> typedef std::vector <std::string> TypeVector;
>
> TypeVector m_type_vector;
> @@ -532,7 +461,7 @@ AppleObjCTypeVendor::FinishDecl(clang::O
>
> ObjCRuntimeMethodType method_type(types);
>
> - clang::ObjCMethodDecl *method_decl = method_type.BuildMethod
> (interface_decl, name, true);
> + clang::ObjCMethodDecl *method_decl = method_type.BuildMethod
> (interface_decl, name, true, m_type_realizer_sp);
>
> if (log)
> log->Printf("[ AOTV::FD] Instance method [%s] [%s]", name,
> types);
> @@ -550,7 +479,7 @@ AppleObjCTypeVendor::FinishDecl(clang::O
>
> ObjCRuntimeMethodType method_type(types);
>
> - clang::ObjCMethodDecl *method_decl = method_type.BuildMethod
> (interface_decl, name, false);
> + clang::ObjCMethodDecl *method_decl = method_type.BuildMethod
> (interface_decl, name, false, m_type_realizer_sp);
>
> if (log)
> log->Printf("[ AOTV::FD] Class method [%s] [%s]", name,
> types);
>
> Modified:
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> ---
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h
> (original)
> +++
> lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h
> Tue Aug 19 16:46:37 2014
> @@ -51,6 +51,7 @@ private:
>
> ObjCLanguageRuntime &m_runtime;
> ClangASTContext m_ast_ctx;
> + ObjCLanguageRuntime::EncodingToTypeSP m_type_realizer_sp;
> AppleObjCExternalASTSource *m_external_source;
>
> typedef llvm::DenseMap<ObjCLanguageRuntime::ObjCISA,
> clang::ObjCInterfaceDecl *> ISAToInterfaceMap;
>
> Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
> +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Aug 19 16:46:37 2014
> @@ -79,6 +79,16 @@ using namespace lldb_private;
> using namespace llvm;
> using namespace clang;
>
> +typedef llvm::DenseMap<clang::ASTContext *, ClangASTContext*> ClangASTMap;
> +
> +static ClangASTMap &
> +GetASTMap()
> +{
> + static ClangASTMap g_map;
> + return g_map;
> +}
> +
> +
> clang::AccessSpecifier
> ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access)
> {
> @@ -291,6 +301,11 @@ ClangASTContext::ClangASTContext (const
> //----------------------------------------------------------------------
> ClangASTContext::~ClangASTContext()
> {
> + if (m_ast_ap.get())
> + {
> + GetASTMap().erase(m_ast_ap.get());
> + }
> +
> m_builtins_ap.reset();
> m_selector_table_ap.reset();
> m_identifier_table_ap.reset();
> @@ -393,10 +408,19 @@ ClangASTContext::getASTContext()
> }
>
> m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(),
> false);
> +
> + GetASTMap().insert(std::make_pair(m_ast_ap.get(), this));
> }
> return m_ast_ap.get();
> }
>
> +ClangASTContext*
> +ClangASTContext::GetASTContext (clang::ASTContext* ast)
> +{
> + ClangASTContext *clang_ast = GetASTMap().lookup(ast);
> + return clang_ast;
> +}
> +
> Builtin::Context *
> ClangASTContext::getBuiltinContext()
> {
>
> Modified: lldb/trunk/source/Target/ObjCLanguageRuntime.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ObjCLanguageRuntime.cpp?rev=216026&r1=216025&r2=216026&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Target/ObjCLanguageRuntime.cpp (original)
> +++ lldb/trunk/source/Target/ObjCLanguageRuntime.cpp Tue Aug 19 16:46:37
> 2014
> @@ -602,4 +602,27 @@ ObjCLanguageRuntime::GetNonKVOClassDescr
> }
>
>
> +ClangASTType
> +ObjCLanguageRuntime::EncodingToType::RealizeType (const char* name, bool
> allow_unknownanytype)
> +{
> + if (m_scratch_ast_ctx_ap)
> + return RealizeType(*m_scratch_ast_ctx_ap, name,
> allow_unknownanytype);
> + return ClangASTType();
> +}
> +
> +ClangASTType
> +ObjCLanguageRuntime::EncodingToType::RealizeType (ClangASTContext&
> ast_ctx, const char* name, bool allow_unknownanytype)
> +{
> + clang::ASTContext *clang_ast = ast_ctx.getASTContext();
> + if (!clang_ast)
> + return ClangASTType();
> + return RealizeType(*clang_ast, name, allow_unknownanytype);
> +}
>
> +ObjCLanguageRuntime::EncodingToType::~EncodingToType() {}
> +
> +ObjCLanguageRuntime::EncodingToTypeSP
> +ObjCLanguageRuntime::GetEncodingToType ()
> +{
> + return nullptr;
> +}
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20140819/d419dc79/attachment.html>
More information about the lldb-commits
mailing list