[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