CXXFormatterFunctions.cpp revision 5f35a4be95aed0e5b2cb36f7d785bcbfc67284ae
1caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata//===-- CXXFormatterFunctions.cpp---------------------------------*- C++ -*-===//
2caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata//
3caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata//                     The LLVM Compiler Infrastructure
4caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata//
5caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata// This file is distributed under the University of Illinois Open Source
6caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata// License. See LICENSE.TXT for details.
7caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata//
8caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata//===----------------------------------------------------------------------===//
9caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
10caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata#include "lldb/Core/CXXFormatterFunctions.h"
11caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
12caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata// needed to get ConvertUTF16/32ToUTF8
13caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata#define CLANG_NEEDS_THESE_ONE_DAY
14caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata#include "clang/Basic/ConvertUTF.h"
15caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
16f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata#include "lldb/Core/DataBufferHeap.h"
17f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata#include "lldb/Core/Error.h"
18caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata#include "lldb/Core/Stream.h"
19caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata#include "lldb/Core/ValueObject.h"
20f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata#include "lldb/Core/ValueObjectConstResult.h"
21f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata#include "lldb/Host/Endian.h"
22db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata#include "lldb/Symbol/ClangASTContext.h"
23caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata#include "lldb/Target/ObjCLanguageRuntime.h"
24caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata#include "lldb/Target/Target.h"
25caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
26caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatausing namespace lldb;
27caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatausing namespace lldb_private;
28caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatausing namespace lldb_private::formatters;
29caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
30caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatabool
31f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
32f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                          const char* target_type,
33f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                          const char* selector,
34f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                          uint64_t &value)
35caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata{
36caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!target_type || !*target_type)
37caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
38caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!selector || !*selector)
39caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
40caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    StreamString expr_path_stream;
41caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    valobj.GetExpressionPath(expr_path_stream, false);
42caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    StreamString expr;
43caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    expr.Printf("(%s)[%s %s]",target_type,expr_path_stream.GetData(),selector);
44caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
45caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    lldb::ValueObjectSP result_sp;
46caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    Target* target = exe_ctx.GetTargetPtr();
47caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    StackFrame* stack_frame = exe_ctx.GetFramePtr();
48caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!target || !stack_frame)
49caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
50d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata
5147beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham    EvaluateExpressionOptions options;
52d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata    options.SetCoerceToId(false)
53d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata    .SetUnwindOnError(true)
54d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata    .SetKeepInMemory(true)
55d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata    .SetUseDynamic(lldb::eDynamicCanRunTarget);
56d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata
57caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    target->EvaluateExpression(expr.GetData(),
58caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                               stack_frame,
59d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata                               result_sp,
60d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata                               options);
61caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!result_sp)
62caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
63caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    value = result_sp->GetValueAsUnsigned(0);
64caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    return true;
65caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata}
66caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
67f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb::ValueObjectSP
68f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
69f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                const char* return_type,
70f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                const char* selector,
71f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                uint64_t index)
72f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
73f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::ValueObjectSP valobj_sp;
74f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!return_type || !*return_type)
75f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return valobj_sp;
76f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!selector || !*selector)
77f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return valobj_sp;
78f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StreamString expr_path_stream;
79f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    valobj.GetExpressionPath(expr_path_stream, false);
80f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StreamString expr;
815f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    expr.Printf("(%s)[%s %s:%" PRId64 "]",return_type,expr_path_stream.GetData(),selector,index);
82f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
83f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::ValueObjectSP result_sp;
84f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    Target* target = exe_ctx.GetTargetPtr();
85f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StackFrame* stack_frame = exe_ctx.GetFramePtr();
86f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!target || !stack_frame)
87f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return valobj_sp;
88f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
8947beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham    EvaluateExpressionOptions options;
90f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    options.SetCoerceToId(false)
91f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    .SetUnwindOnError(true)
92f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    .SetKeepInMemory(true)
93f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    .SetUseDynamic(lldb::eDynamicCanRunTarget);
94f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
95f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    target->EvaluateExpression(expr.GetData(),
96f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                               stack_frame,
97f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                               valobj_sp,
98f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                               options);
99f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return valobj_sp;
100f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
101f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
102f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb::ValueObjectSP
103f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
104f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                const char* return_type,
105f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                const char* selector,
106f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                const char* key)
107f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
108f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::ValueObjectSP valobj_sp;
109f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!return_type || !*return_type)
110f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return valobj_sp;
111f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!selector || !*selector)
112f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return valobj_sp;
113f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!key || !*key)
114f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return valobj_sp;
115f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StreamString expr_path_stream;
116f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    valobj.GetExpressionPath(expr_path_stream, false);
117f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StreamString expr;
118f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
119f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
120f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::ValueObjectSP result_sp;
121f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    Target* target = exe_ctx.GetTargetPtr();
122f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StackFrame* stack_frame = exe_ctx.GetFramePtr();
123f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!target || !stack_frame)
124f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return valobj_sp;
125f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
12647beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham    EvaluateExpressionOptions options;
127f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    options.SetCoerceToId(false)
128f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    .SetUnwindOnError(true)
129f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    .SetKeepInMemory(true)
130f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    .SetUseDynamic(lldb::eDynamicCanRunTarget);
131f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
132f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    target->EvaluateExpression(expr.GetData(),
133f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                               stack_frame,
134f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                               valobj_sp,
135f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                               options);
136f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return valobj_sp;
137f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
138f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
139caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatatemplate<bool name_entries>
140caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatabool
141f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
142caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata{
143caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ProcessSP process_sp = valobj.GetProcessSP();
144caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!process_sp)
145caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
146caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
147caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
148caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
149caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!runtime)
150caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
151caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
152caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
153caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
154caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!descriptor.get() || !descriptor->IsValid())
155caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
156caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
157caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint32_t ptr_size = process_sp->GetAddressByteSize();
158caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    bool is_64bit = (ptr_size == 8);
159caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
160caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
161caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
162caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!valobj_addr)
163caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
164caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
165caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint64_t value = 0;
166caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
167caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    const char* class_name = descriptor->GetClassName().GetCString();
1687685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
1697685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata    if (!class_name || !*class_name)
1707685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata        return false;
1717685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
172caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!strcmp(class_name,"__NSDictionaryI"))
173caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
174caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Error error;
175caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
176caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
177caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
178caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
179caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
180caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else if (!strcmp(class_name,"__NSDictionaryM"))
181caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
182caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Error error;
183caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
184caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
185caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
186caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
187caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
188caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else if (!strcmp(class_name,"__NSCFDictionary"))
189caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
190caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Error error;
191caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), ptr_size, 0, error);
192caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
193caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
194caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (is_64bit)
195caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            value &= ~0x0f1f000000000000UL;
196caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            }
197caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else
198caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
199f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
200caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
201caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
202caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
2035f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    stream.Printf("%s%" PRIu64 " %s%s",
204caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  (name_entries ? "@\"" : ""),
205caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  value,
206caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")),
207caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  (name_entries ? "\"" : ""));
208caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    return true;
209caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata}
210caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
211caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatabool
212f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream)
213caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata{
214caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ProcessSP process_sp = valobj.GetProcessSP();
215caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!process_sp)
216caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
217caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
218caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
219caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
220caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!runtime)
221caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
222caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
223caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
224caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
225caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!descriptor.get() || !descriptor->IsValid())
226caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
227caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
228caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint32_t ptr_size = process_sp->GetAddressByteSize();
229caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
230caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
231caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
232caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!valobj_addr)
233caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
234caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
235caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint64_t value = 0;
236caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
237caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    const char* class_name = descriptor->GetClassName().GetCString();
2387685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
2397685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata    if (!class_name || !*class_name)
2407685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata        return false;
2417685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
242caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!strcmp(class_name,"__NSArrayI"))
243caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
244caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Error error;
245caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
246caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
247caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
248caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
249caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else if (!strcmp(class_name,"__NSArrayM"))
250caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
251caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Error error;
252caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
253caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
254caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
255caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
256caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else if (!strcmp(class_name,"__NSCFArray"))
257caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
258caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Error error;
259caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
260caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
261caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
262caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
263caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else
264caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
265f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
266caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
267caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
268caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
2695f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    stream.Printf("@\"%" PRIu64 " object%s\"",
270caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  value,
271caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  value == 1 ? "" : "s");
272caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    return true;
273caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata}
274caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
275caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatatemplate<bool needs_at>
276caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatabool
277f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream)
278caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata{
279caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ProcessSP process_sp = valobj.GetProcessSP();
280caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!process_sp)
281caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
282caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
283caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
284caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
285caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!runtime)
286caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
287caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
288caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
289caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
290caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!descriptor.get() || !descriptor->IsValid())
291caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
292caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
293caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    bool is_64bit = (process_sp->GetAddressByteSize() == 8);
294caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
295caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
296caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!valobj_addr)
297caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
298caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
299caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint64_t value = 0;
300caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
301caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    const char* class_name = descriptor->GetClassName().GetCString();
3027685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
3037685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata    if (!class_name || !*class_name)
3047685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata        return false;
3057685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
306caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!strcmp(class_name,"NSConcreteData") ||
307caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        !strcmp(class_name,"NSConcreteMutableData") ||
308caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        !strcmp(class_name,"__NSCFData"))
309caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
310caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        uint32_t offset = (is_64bit ? 16 : 8);
311caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Error error;
312caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
313caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
314caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
315caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
316caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else
317caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
318f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        if (!ExtractValueFromObjCExpression(valobj, "int", "length", value))
319caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
320caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
321caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
3225f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    stream.Printf("%s%" PRIu64 " byte%s%s",
323caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  (needs_at ? "@\"" : ""),
324caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  value,
325caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  (value > 1 ? "s" : ""),
326caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                  (needs_at ? "\"" : ""));
327caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
328caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    return true;
329caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata}
330caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
331caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatabool
332f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
333caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata{
334caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ProcessSP process_sp = valobj.GetProcessSP();
335caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!process_sp)
336caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
337caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
338caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
339caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
340caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!runtime)
341caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
342caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
343caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
344caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
345caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!descriptor.get() || !descriptor->IsValid())
346caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
347caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
348caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint32_t ptr_size = process_sp->GetAddressByteSize();
349caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
350caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
351caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
352caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!valobj_addr)
353caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
354caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
355caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    const char* class_name = descriptor->GetClassName().GetCString();
356caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
3577685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata    if (!class_name || !*class_name)
3587685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata        return false;
3597685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
360caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
361caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
362caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (descriptor->IsTagged())
363caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        {
364caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them
365caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8;
366caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            uint64_t i_bits = (valobj_addr & 0xF0) >> 4;
367caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
368caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            switch (i_bits)
369caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            {
370caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 0:
371caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("(char)%hhd",(char)value);
372caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
373caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 4:
374caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("(short)%hd",(short)value);
375caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
376caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 8:
377caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("(int)%d",(int)value);
378caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
379caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 12:
3805f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                    stream.Printf("(long)%" PRId64,value);
381caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
382caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                default:
3835f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                    stream.Printf("absurd value:(info=%" PRIu64 ", value=%" PRIu64,i_bits,value);
384caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
385caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            }
386caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return true;
387caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        }
388caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        else
389caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        {
390caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            Error error;
391caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
392caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            uint64_t data_location = valobj_addr + 2*ptr_size;
393caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            uint64_t value = 0;
394caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            if (error.Fail())
395caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                return false;
396caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            switch (data_type)
397caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            {
398caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 1: // 0B00001
399caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
400caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    if (error.Fail())
401caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                        return false;
402caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("(char)%hhd",(char)value);
403caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
404caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 2: // 0B0010
405caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
406caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    if (error.Fail())
407caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                        return false;
408caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("(short)%hd",(short)value);
409caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
410caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 3: // 0B0011
411caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
412caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    if (error.Fail())
413caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                        return false;
414caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("(int)%d",(int)value);
415caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
416caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 17: // 0B10001
417caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    data_location += 8;
418caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 4: // 0B0100
419caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
420caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    if (error.Fail())
421caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                        return false;
4225f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                    stream.Printf("(long)%" PRId64,value);
423caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
424caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 5: // 0B0101
425caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                {
426caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
427caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    if (error.Fail())
428caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                        return false;
429caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    float flt_value = *((float*)&flt_as_int);
430caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("(float)%f",flt_value);
431caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
432caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                }
433caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                case 6: // 0B0110
434caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                {
435caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
436caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    if (error.Fail())
437caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                        return false;
438caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    double dbl_value = *((double*)&dbl_as_lng);
439caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("(double)%g",dbl_value);
440caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
441caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                }
442caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                default:
443caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    stream.Printf("absurd: dt=%d",data_type);
444caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                    break;
445caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            }
446caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return true;
447caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        }
448caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
449caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else
450caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
451f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        // similar to ExtractValueFromObjCExpression but uses summary instead of value
452caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        StreamString expr_path_stream;
453caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        valobj.GetExpressionPath(expr_path_stream, false);
454caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        StreamString expr;
455caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        expr.Printf("(NSString*)[%s stringValue]",expr_path_stream.GetData());
456caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
457caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        lldb::ValueObjectSP result_sp;
458caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Target* target = exe_ctx.GetTargetPtr();
459caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        StackFrame* stack_frame = exe_ctx.GetFramePtr();
460caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (!target || !stack_frame)
461caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
462d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata
46347beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham        EvaluateExpressionOptions options;
464d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata        options.SetCoerceToId(false)
465d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata        .SetUnwindOnError(true)
466d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata        .SetKeepInMemory(true)
467d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata        .SetUseDynamic(lldb::eDynamicCanRunTarget);
468d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata
469caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        target->EvaluateExpression(expr.GetData(),
470caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                                   stack_frame,
471d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata                                   result_sp,
472d27026e46d8430fb451d85ac161a8492e1930245Enrico Granata                                   options);
473caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (!result_sp)
474caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
475caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        stream.Printf("%s",result_sp->GetSummaryAsCString());
476caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return true;
477caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
478caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata}
479caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
480b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granatastatic bool
481b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico GranataReadUTFBufferAndDumpToStream (uint64_t location,
482b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                              const ProcessSP& process_sp,
483b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                              Stream& stream)
484b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata{
485b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    Error error;
486b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
487b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    size_t data_read = process_sp->ReadMemoryFromInferior(location, (char*)buffer_sp->GetBytes(), 1024, error);
488b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    if (error.Fail())
489b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    {
490b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        stream.Printf("unable to read data");
491b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        return true;
492b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    }
493b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    else
494b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        stream.Printf("@\"");
495b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    if (data_read)
496b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    {
497b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        UTF16 *data_ptr = (UTF16*)buffer_sp->GetBytes();
498b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        UTF16 *data_end_ptr = data_ptr + 256;
499b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata
500b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        while (data_ptr < data_end_ptr)
501b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        {
502b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata            if (!*data_ptr)
503b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata            {
504b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                data_end_ptr = data_ptr;
505b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                break;
506b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata            }
507b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata            data_ptr++;
508b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        }
509b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata
510b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        *data_ptr = 0;
511b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        data_ptr = (UTF16*)buffer_sp->GetBytes();
512b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata
513b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        lldb::DataBufferSP utf8_data_buffer_sp(new DataBufferHeap(1024,0));
514b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        UTF8* utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes();
515b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        UTF8* utf8_data_end_ptr = utf8_data_ptr + 1024;
516b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata
517b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        ConvertUTF16toUTF8	(	(const UTF16**)&data_ptr,
518b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                             data_end_ptr,
519b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                             &utf8_data_ptr,
520b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                             utf8_data_end_ptr,
521b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                             lenientConversion);
522b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes();
523b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++)
524b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        {
525b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata            if (!*utf8_data_ptr)
526b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata                break;
527b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata            stream.Printf("%c",*utf8_data_ptr);
528b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        }
529b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        stream.Printf("\"");
530b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        return true;
531b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    }
532b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    stream.Printf("\"");
533b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata    return true;
534b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata}
535b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata
536caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatabool
537f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream)
538caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata{
539caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ProcessSP process_sp = valobj.GetProcessSP();
540caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!process_sp)
541caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
542caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
543caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
544caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
545caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!runtime)
546caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
547caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
548caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
549caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
550caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!descriptor.get() || !descriptor->IsValid())
551caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
552caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
553caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint32_t ptr_size = process_sp->GetAddressByteSize();
554caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
555caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
556caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
557caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (!valobj_addr)
558caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
559caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
560caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    const char* class_name = descriptor->GetClassName().GetCString();
561caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
56225c9adecf763053ff953b4d437b022075d30dd13Enrico Granata    if (!class_name || !*class_name)
56325c9adecf763053ff953b4d437b022075d30dd13Enrico Granata        return false;
56425c9adecf763053ff953b4d437b022075d30dd13Enrico Granata
565caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint64_t info_bits_location = valobj_addr + ptr_size;
566caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
567caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        info_bits_location += 3;
568caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
569caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        Error error;
570caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
571caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
572caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (error.Fail())
573caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
574caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
575caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    bool is_mutable = (info_bits & 1) == 1;
576caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    bool is_inline = (info_bits & 0x60) == 0;
577caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    bool has_explicit_length = (info_bits & (1 | 4)) != 4;
578caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    bool is_unicode = (info_bits & 0x10) == 0x10;
579caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    bool is_special = strcmp(class_name,"NSPathStore2") == 0;
580caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
581caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (strcmp(class_name,"NSString") &&
582caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        strcmp(class_name,"CFStringRef") &&
583caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        strcmp(class_name,"CFMutableStringRef") &&
584caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        strcmp(class_name,"__NSCFConstantString") &&
585caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        strcmp(class_name,"__NSCFString") &&
586caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        strcmp(class_name,"NSCFConstantString") &&
587caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        strcmp(class_name,"NSCFString") &&
588caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        strcmp(class_name,"NSPathStore2"))
589caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
590caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        // probably not one of us - bail out
591caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        return false;
592caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
593caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
594caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    if (is_mutable)
595caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
596caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        uint64_t location = 2 * ptr_size + valobj_addr;
597caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        location = process_sp->ReadPointerFromMemory(location, error);
598caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
599caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
600caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (has_explicit_length and is_unicode)
601b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata            return ReadUTFBufferAndDumpToStream (location, process_sp, stream);
602caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        else
603caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        {
604caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            location++;
605caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
606caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
607caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            if (error.Fail())
608caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                return false;
609caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            if (data_read)
610caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
611caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                return true;
612caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        }
613caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
614caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else if (is_inline && has_explicit_length && !is_unicode && !is_special && !is_mutable)
615caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
616caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        uint64_t location = 3 * ptr_size + valobj_addr;
617caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
618caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
619caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
620caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
621caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (data_read)
622caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
623caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return true;
624caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
625caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else if (is_unicode)
626caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
627caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
628caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (is_inline)
629caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        {
630caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            if (!has_explicit_length)
631caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            {
632caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                stream.Printf("found new combo");
633caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                return true;
634caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            }
635caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            else
636caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                location += ptr_size;
637caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                }
638caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        else
639caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        {
640caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            location = process_sp->ReadPointerFromMemory(location, error);
641caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            if (error.Fail())
642caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata                return false;
643caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        }
644b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        return ReadUTFBufferAndDumpToStream (location, process_sp, stream);
645caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
646caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else if (is_special)
647caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
648caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        uint64_t location = valobj_addr + (ptr_size == 8 ? 12 : 8);
649b9bd5d11c4a8a09ce6d79c98c856aaa5d31acacfEnrico Granata        return ReadUTFBufferAndDumpToStream (location, process_sp, stream);
650caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
651caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else if (is_inline)
652caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
653caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
654caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (!has_explicit_length)
655caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            location++;
656caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
657caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
658caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
659caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
660caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (data_read)
661caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
662caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return true;
663caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
664caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    else
665caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    {
666caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
667caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        location = process_sp->ReadPointerFromMemory(location, error);
668caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
669caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
670caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
671caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
672caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (error.Fail())
673caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return false;
674caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata        if (data_read)
675caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
676caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata            return true;
677caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    }
678caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
679caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    stream.Printf("class name = %s",class_name);
680caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata    return true;
681caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
682caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata}
683caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
6849abbfba957db139beed19866f61599424ddcd37aEnrico Granatabool
6859abbfba957db139beed19866f61599424ddcd37aEnrico Granatalldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream)
6869abbfba957db139beed19866f61599424ddcd37aEnrico Granata{
6879abbfba957db139beed19866f61599424ddcd37aEnrico Granata    stream.Printf("%s",valobj.GetObjectDescription());
6889abbfba957db139beed19866f61599424ddcd37aEnrico Granata    return true;
6899abbfba957db139beed19866f61599424ddcd37aEnrico Granata}
6909abbfba957db139beed19866f61599424ddcd37aEnrico Granata
691db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatabool
692db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatalldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream)
693db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata{
694db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(),
695db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata                                                            valobj.GetClangAST(),
696db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata                                                            NULL);
697db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
698db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    ValueObjectSP real_guy_sp = valobj.GetSP();
699db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
700db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    if (type_info & ClangASTContext::eTypeIsPointer)
701db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    {
702db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        Error err;
703db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        real_guy_sp = valobj.Dereference(err);
704db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        if (err.Fail() || !real_guy_sp)
705db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata            return false;
706db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    }
707db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    else if (type_info & ClangASTContext::eTypeIsReference)
708db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    {
709db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        real_guy_sp =  valobj.GetChildAtIndex(0, true);
710db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        if (!real_guy_sp)
711db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata            return false;
712db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    }
713db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    uint64_t value = real_guy_sp->GetValueAsUnsigned(0);
714db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    if (value == 0)
715db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    {
716db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        stream.Printf("NO");
717db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        return true;
718db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    }
719db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    stream.Printf("YES");
720db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    return true;
721db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata}
722db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
723db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatatemplate <bool is_sel_ptr>
724db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatabool
725db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatalldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream)
726db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata{
727db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    lldb::addr_t data_address = LLDB_INVALID_ADDRESS;
728db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
729db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    if (is_sel_ptr)
730db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
731db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    else
732db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        data_address = valobj.GetAddressOf();
733db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
734db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    if (data_address == LLDB_INVALID_ADDRESS)
735db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata        return false;
736db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
737db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
738db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
739db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    void* char_opaque_type = valobj.GetClangAST()->CharTy.getAsOpaquePtr();
740db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    ClangASTType charstar(valobj.GetClangAST(),ClangASTType::GetPointerType(valobj.GetClangAST(), char_opaque_type));
741db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
742db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    ValueObjectSP valobj_sp(ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar));
743db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
744db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    stream.Printf("%s",valobj_sp->GetSummaryAsCString());
745db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata    return true;
746db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata}
747db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
748f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
749f91e78f58692785db4daecf8461481b95827dcf2Enrico GranataSyntheticChildrenFrontEnd(*valobj_sp.get()),
750f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatam_exe_ctx_ref(),
751f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatam_ptr_size(8),
752f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatam_data_32(NULL),
753f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatam_data_64(NULL)
754f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
755247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (valobj_sp)
756f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
757247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
758247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        Update();
759f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
760f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
761f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
762f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatauint32_t
763f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
764f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
765f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (m_data_32)
766f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return m_data_32->_used;
767f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (m_data_64)
768f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return m_data_64->_used;
769f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return 0;
770f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
771f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
772f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb::ValueObjectSP
773f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
774f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
775f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!m_data_32 && !m_data_64)
776f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return lldb::ValueObjectSP();
777f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (idx >= CalculateNumChildren())
778f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return lldb::ValueObjectSP();
779f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::addr_t object_at_idx = (m_data_32 ? m_data_32->_data : m_data_64->_data);
780f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    object_at_idx += (idx * m_ptr_size);
781f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StreamString idx_name;
782f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    idx_name.Printf("[%d]",idx);
783f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromAddress(idx_name.GetData(),
784f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                                              object_at_idx,
785f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                                              m_exe_ctx_ref,
786f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata                                                                              m_id_type);
787f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    m_children.push_back(retval_sp);
788f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return retval_sp;
789f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
790f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
791f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatabool
792f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayMSyntheticFrontEnd::Update()
793f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
794f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    m_children.clear();
795247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    ValueObjectSP valobj_sp = m_backend.GetSP();
796247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_ptr_size = 0;
797247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    delete m_data_32;
798247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_data_32 = NULL;
799247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    delete m_data_64;
800247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_data_64 = NULL;
801247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (valobj_sp->IsDynamic())
802247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        valobj_sp = valobj_sp->GetStaticValue();
803247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (!valobj_sp)
804247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        return false;
805247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
806247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    Error error;
807247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (valobj_sp->IsPointerType())
808247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    {
809247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        valobj_sp = valobj_sp->Dereference(error);
810247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        if (error.Fail() || !valobj_sp)
811247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata            return false;
812247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    }
813247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    error.Clear();
814247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
815247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (!process_sp)
816247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        return false;
817247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_ptr_size = process_sp->GetAddressByteSize();
818247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
819247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (m_ptr_size == 4)
820247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    {
821247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        m_data_32 = new DataDescriptor_32();
822247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
823247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    }
824247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    else
825247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    {
826247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        m_data_64 = new DataDescriptor_64();
827247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
828247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    }
829247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (error.Fail())
830247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        return false;
831f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return false;
832f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
833f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
834800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatabool
835800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatalldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
836800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata{
837c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata    if (!m_data_32 && !m_data_64)
838c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata        Update ();
839c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata    return CalculateNumChildren();
840800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata}
841800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata
842f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatastatic uint32_t
843f91e78f58692785db4daecf8461481b95827dcf2Enrico GranataExtractIndexFromString (const char* item_name)
844f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
845f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!item_name || !*item_name)
846f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return UINT32_MAX;
847f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (*item_name != '[')
848f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return UINT32_MAX;
849f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    item_name++;
850f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    uint32_t idx = 0;
851f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    while(*item_name)
852f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
853f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        char x = *item_name;
854f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        if (x == ']')
855f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata            break;
856f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        if (x < '0' || x > '9')
857f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata            return UINT32_MAX;
858f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        idx = 10*idx + (x-'0');
859f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        item_name++;
860f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
861f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return idx;
862f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
863f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
864f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatauint32_t
865f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
866f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
867f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!m_data_32 && !m_data_64)
868f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return UINT32_MAX;
869f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    const char* item_name = name.GetCString();
870f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    uint32_t idx = ExtractIndexFromString(item_name);
871f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (idx < UINT32_MAX && idx >= CalculateNumChildren())
872f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return UINT32_MAX;
873f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return idx;
874f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
875f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
876f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayMSyntheticFrontEnd::~NSArrayMSyntheticFrontEnd ()
877f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
878f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    delete m_data_32;
879f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    m_data_32 = NULL;
880f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    delete m_data_64;
881f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    m_data_64 = NULL;
882f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
883f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
884f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
885f91e78f58692785db4daecf8461481b95827dcf2Enrico GranataSyntheticChildrenFrontEnd(*valobj_sp.get()),
886f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatam_exe_ctx_ref(),
887f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatam_ptr_size(8),
888f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatam_items(0),
889f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatam_data_ptr(0)
890f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
891247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (valobj_sp)
892f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
893247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
894247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        Update();
895f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
896f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
897f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
898f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
899f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
900f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
901f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
902f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatauint32_t
903f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
904f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
905f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    const char* item_name = name.GetCString();
906f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    uint32_t idx = ExtractIndexFromString(item_name);
907f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (idx < UINT32_MAX && idx >= CalculateNumChildren())
908f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return UINT32_MAX;
909f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return idx;
910f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
911f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
912f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatauint32_t
913f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
914f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
915f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return m_items;
916f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
917f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
918f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatabool
919f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
920f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
921247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_ptr_size = 0;
922247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_items = 0;
923247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_data_ptr = 0;
924f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    m_children.clear();
925247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    ValueObjectSP valobj_sp = m_backend.GetSP();
926247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (valobj_sp->IsDynamic())
927247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        valobj_sp = valobj_sp->GetStaticValue();
928247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (!valobj_sp)
929247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        return false;
930247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
931247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    Error error;
932247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (valobj_sp->IsPointerType())
933247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    {
934247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        valobj_sp = valobj_sp->Dereference(error);
935247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        if (error.Fail() || !valobj_sp)
936247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata            return false;
937247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    }
938247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    error.Clear();
939247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
940247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (!process_sp)
941247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        return false;
942247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_ptr_size = process_sp->GetAddressByteSize();
943247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
944247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_items = process_sp->ReadPointerFromMemory(data_location, error);
945247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    if (error.Fail())
946247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata        return false;
947247da3363800e9420dbe06e77dfc0e5819d72b08Enrico Granata    m_data_ptr = data_location+m_ptr_size;
948f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return false;
949f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
950f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
951800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatabool
952800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatalldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren ()
953800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata{
954c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata    if (!m_data_ptr)
955c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata        Update ();
956c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata    return CalculateNumChildren();
957800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata}
958800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata
959f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb::ValueObjectSP
960f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
961f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
962f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (idx >= CalculateNumChildren())
963f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return lldb::ValueObjectSP();
964f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::addr_t object_at_idx = m_data_ptr;
965f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    object_at_idx += (idx * m_ptr_size);
966f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
967f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!process_sp)
968f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return lldb::ValueObjectSP();
969f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    Error error;
970f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    object_at_idx = process_sp->ReadPointerFromMemory(object_at_idx, error);
971f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (error.Fail())
972f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return lldb::ValueObjectSP();
973f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StreamString expr;
9745f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    expr.Printf("(id)%" PRIu64,object_at_idx);
975f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StreamString idx_name;
976f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    idx_name.Printf("[%d]",idx);
977f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
978f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    m_children.push_back(retval_sp);
979f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return retval_sp;
980f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
981f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
982f91e78f58692785db4daecf8461481b95827dcf2Enrico GranataSyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
983f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
984f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
985f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!process_sp)
986f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return NULL;
987f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
988f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!runtime)
989f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return NULL;
990f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
991f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!valobj_sp->IsPointerType())
992f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
993f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        Error error;
994f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        valobj_sp = valobj_sp->AddressOf(error);
995f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        if (error.Fail() || !valobj_sp)
996f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata            return NULL;
997f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
998f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
999f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
1000f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1001f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!descriptor.get() || !descriptor->IsValid())
1002f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return NULL;
1003f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1004f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    const char* class_name = descriptor->GetClassName().GetCString();
10057685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
10067685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata    if (!class_name || !*class_name)
10077685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata        return NULL;
10087685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
1009f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (!strcmp(class_name,"__NSArrayI"))
1010f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
1011f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return (new NSArrayISyntheticFrontEnd(valobj_sp));
1012f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
1013f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    else if (!strcmp(class_name,"__NSArrayM"))
1014f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
1015f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return (new NSArrayMSyntheticFrontEnd(valobj_sp));
1016f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
1017f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    else
1018f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    {
1019f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
1020f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    }
1021f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
1022f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1023f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
1024f91e78f58692785db4daecf8461481b95827dcf2Enrico GranataSyntheticChildrenFrontEnd(*valobj_sp.get())
1025f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{}
1026f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1027f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatauint32_t
1028f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
1029f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
1030f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    uint64_t count = 0;
1031f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
1032f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        return count;
1033f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return 0;
1034f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
1035f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1036f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb::ValueObjectSP
1037f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
1038f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
1039f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    StreamString idx_name;
1040f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    idx_name.Printf("[%d]",idx);
1041f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
1042f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    if (valobj_sp)
1043f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata        valobj_sp->SetName(ConstString(idx_name.GetData()));
1044f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return valobj_sp;
1045f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
1046f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1047f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatabool
1048f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
1049f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
1050f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return false;
1051f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
1052f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1053800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatabool
1054800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatalldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren ()
1055800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata{
1056800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata    return CalculateNumChildren() > 0;
1057800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata}
1058800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata
1059f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatauint32_t
1060f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
1061f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{
1062f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata    return 0;
1063f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata}
1064f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1065f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
1066f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata{}
1067f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
10683a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico GranataSyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
10693a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
10703a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
10713a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
10723a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!process_sp)
10733a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return NULL;
10743a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
10753a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!runtime)
10763a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return NULL;
10773a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
10783a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!valobj_sp->IsPointerType())
10793a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    {
10803a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        Error error;
10813a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        valobj_sp = valobj_sp->AddressOf(error);
10823a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        if (error.Fail() || !valobj_sp)
10833a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            return NULL;
10843a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    }
10853a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
10863a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
10873a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
10883a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!descriptor.get() || !descriptor->IsValid())
10893a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return NULL;
10903a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
10913a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    const char* class_name = descriptor->GetClassName().GetCString();
10927685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
10937685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata    if (!class_name || !*class_name)
10947685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata        return NULL;
10957685a56184b3e8639a42f26e5b8aba9e70b85647Enrico Granata
10963a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!strcmp(class_name,"__NSDictionaryI"))
10973a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    {
10983a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
10993a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    }
11003a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    else if (!strcmp(class_name,"__NSDictionaryM"))
11013a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    {
11023a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
11033a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    }
11043a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    else
11053a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    {
11063a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
11073a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    }
11083a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
11093a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11103a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
11113a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico GranataSyntheticChildrenFrontEnd(*valobj_sp.get())
11123a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{}
11133a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11143a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatauint32_t
11153a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
11163a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
11173a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    uint64_t count = 0;
11183a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
11193a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return count;
11203a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return 0;
11213a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
11223a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11233a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb::ValueObjectSP
11243a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
11253a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
11263a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    StreamString idx_name;
11273a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    idx_name.Printf("[%d]",idx);
11283a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    StreamString valobj_expr_path;
11293a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_backend.GetExpressionPath(valobj_expr_path, false);
11303a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    StreamString key_fetcher_expr;
11313a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    key_fetcher_expr.Printf("(id)[(NSArray*)[%s allKeys] objectAtIndex:%d]",valobj_expr_path.GetData(),idx);
11323a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    StreamString value_fetcher_expr;
11333a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    value_fetcher_expr.Printf("(id)[%s objectForKey:%s]",valobj_expr_path.GetData(),key_fetcher_expr.GetData());
11343a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    StreamString object_fetcher_expr;
1135fd3d28dc02a37c61354b5b687d4ce9aea53d62d3Enrico Granata    object_fetcher_expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData());
11363a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    lldb::ValueObjectSP child_sp;
11373a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
113847beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                                                EvaluateExpressionOptions().SetKeepInMemory(true));
11393a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (child_sp)
11403a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        child_sp->SetName(ConstString(idx_name.GetData()));
11413a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return child_sp;
11423a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
11433a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11443a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatabool
11453a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
11463a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
11473a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return false;
11483a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
11493a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
1150800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatabool
1151800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatalldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
1152800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata{
1153800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata    return CalculateNumChildren() > 0;
1154800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata}
1155800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata
11563a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatauint32_t
11573a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
11583a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
11593a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return 0;
11603a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
11613a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11623a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
11633a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{}
11643a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11653a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
11663a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    SyntheticChildrenFrontEnd(*valobj_sp.get()),
11673a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_exe_ctx_ref(),
11683a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_ptr_size(8),
11693a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_data_32(NULL),
11703a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_data_64(NULL)
11713a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
1172a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (valobj_sp)
1173a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        Update();
11743a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
11753a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11763a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
11773a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
11783a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    delete m_data_32;
11793a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_data_32 = NULL;
11803a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    delete m_data_64;
11813a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_data_64 = NULL;
11823a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
11833a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11843a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatauint32_t
11853a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
11863a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
11873a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    const char* item_name = name.GetCString();
11883a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    uint32_t idx = ExtractIndexFromString(item_name);
11893a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (idx < UINT32_MAX && idx >= CalculateNumChildren())
11903a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return UINT32_MAX;
11913a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return idx;
11923a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
11933a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
11943a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatauint32_t
11953a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
11963a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
11973a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!m_data_32 && !m_data_64)
11983a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return 0;
11993a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return (m_data_32 ? m_data_32->_used : m_data_64->_used);
12003a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
12013a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12023a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatabool
12033a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
12043a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
12053a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_children.clear();
1206a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    delete m_data_32;
1207a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_data_32 = NULL;
1208a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    delete m_data_64;
1209a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_data_64 = NULL;
1210a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_ptr_size = 0;
1211a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    ValueObjectSP valobj_sp = m_backend.GetSP();
1212a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (!valobj_sp)
1213a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        return false;
1214a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (valobj_sp->IsDynamic())
1215a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        valobj_sp = valobj_sp->GetStaticValue();
1216a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (!valobj_sp)
1217a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        return false;
1218a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
1219a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    Error error;
1220a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (valobj_sp->IsPointerType())
1221a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    {
1222a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        valobj_sp = valobj_sp->Dereference(error);
1223a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        if (error.Fail() || !valobj_sp)
1224a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata            return false;
1225a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    }
1226a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    error.Clear();
1227a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
1228a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (!process_sp)
1229a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        return false;
1230a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_ptr_size = process_sp->GetAddressByteSize();
1231a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
1232a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (m_ptr_size == 4)
1233a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    {
1234a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        m_data_32 = new DataDescriptor_32();
1235a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
1236a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    }
1237a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    else
1238a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    {
1239a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        m_data_64 = new DataDescriptor_64();
1240a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
1241a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    }
1242a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (error.Fail())
1243a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        return false;
1244a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_data_ptr = data_location + m_ptr_size;
12453a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return false;
12463a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
12473a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
1248800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatabool
1249800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatalldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
1250800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata{
1251c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata    if (!m_data_32 && !m_data_64)
1252c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata        Update ();
1253c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata    return CalculateNumChildren();
1254800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata}
1255800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata
12563a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb::ValueObjectSP
12573a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
12583a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
12593a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    uint32_t num_children = CalculateNumChildren();
12603a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12613a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (idx >= num_children)
12623a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return lldb::ValueObjectSP();
12633a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12643a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (m_children.empty())
12653a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    {
12663a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        // do the scan phase
12673a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        lldb::addr_t key_at_idx = 0, val_at_idx = 0;
12683a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12693a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        uint32_t tries = 0;
12703a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        uint32_t test_idx = 0;
12713a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12723a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        while(tries < num_children)
12733a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        {
12743a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
12753a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            val_at_idx = key_at_idx + m_ptr_size;
12763a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
12773a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            if (!process_sp)
12783a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata                return lldb::ValueObjectSP();
12793a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            Error error;
12803a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
12813a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            if (error.Fail())
12823a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata                return lldb::ValueObjectSP();
12833a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
12843a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            if (error.Fail())
12853a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata                return lldb::ValueObjectSP();
12863a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12873a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            test_idx++;
12883a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12893a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            if (!key_at_idx || !val_at_idx)
12903a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata                continue;
12913a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            tries++;
12923a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12933a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
12943a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12953a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            m_children.push_back(descriptor);
12963a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        }
12973a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    }
12983a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
12993a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (idx >= m_children.size()) // should never happen
13003a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return lldb::ValueObjectSP();
13013a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
13023a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    DictionaryItemDescriptor &dict_item = m_children[idx];
13033a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!dict_item.valobj_sp)
13043a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    {
13053a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        // make the new ValueObject
13063a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        StreamString expr;
13075f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%" PRIu64 " ; _lldb_valgen_item.value = (id)%" PRIu64 "; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
13083a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        StreamString idx_name;
13093a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        idx_name.Printf("[%d]",idx);
13103a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
13113a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    }
13123a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return dict_item.valobj_sp;
13133a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
13143a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
13153a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
13163a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    SyntheticChildrenFrontEnd(*valobj_sp.get()),
13173a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_exe_ctx_ref(),
13183a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_ptr_size(8),
13193a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_data_32(NULL),
13203a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_data_64(NULL)
13213a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
1322a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (valobj_sp)
1323a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        Update ();
13243a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
13253a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
13263a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
13273a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
13283a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    delete m_data_32;
13293a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_data_32 = NULL;
13303a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    delete m_data_64;
13313a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_data_64 = NULL;
13323a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
13333a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
13343a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatauint32_t
13353a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
13363a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
13373a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    const char* item_name = name.GetCString();
13383a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    uint32_t idx = ExtractIndexFromString(item_name);
13393a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (idx < UINT32_MAX && idx >= CalculateNumChildren())
13403a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return UINT32_MAX;
13413a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return idx;
13423a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
13433a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
13443a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatauint32_t
13453a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
13463a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
13473a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!m_data_32 && !m_data_64)
13483a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return 0;
13493a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return (m_data_32 ? m_data_32->_used : m_data_64->_used);
13503a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
13513a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
13523a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatabool
13533a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
13543a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
13553a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    m_children.clear();
1356a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    ValueObjectSP valobj_sp = m_backend.GetSP();
1357a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_ptr_size = 0;
1358a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    delete m_data_32;
1359a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_data_32 = NULL;
1360a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    delete m_data_64;
1361a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_data_64 = NULL;
1362a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (!valobj_sp)
1363a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        return false;
1364a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (valobj_sp->IsDynamic())
1365a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        valobj_sp = valobj_sp->GetStaticValue();
1366a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (!valobj_sp)
1367a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        return false;
1368a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
1369a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    Error error;
1370a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (valobj_sp->IsPointerType())
1371a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    {
1372a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        valobj_sp = valobj_sp->Dereference(error);
1373a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        if (error.Fail() || !valobj_sp)
1374a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata            return false;
1375a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    }
1376a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    error.Clear();
1377a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
1378a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (!process_sp)
1379a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        return false;
1380a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    m_ptr_size = process_sp->GetAddressByteSize();
1381a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
1382a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (m_ptr_size == 4)
1383a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    {
1384a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        m_data_32 = new DataDescriptor_32();
1385a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
1386a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    }
1387a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    else
1388a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    {
1389a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        m_data_64 = new DataDescriptor_64();
1390a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
1391a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    }
1392a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata    if (error.Fail())
1393a787c1ad2a5ab1d5be6be1936d776c8406bc8d53Enrico Granata        return false;
13943a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return false;
13953a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
13963a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
1397800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatabool
1398800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granatalldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
1399800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata{
1400c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata    if (!m_data_32 && !m_data_64)
1401c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata        Update ();
1402c01344c2c90c44375f39d7160c44ee3b8abce656Enrico Granata    return CalculateNumChildren();
1403800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata}
1404800332c3988c78ea002b64b698f38b58ed95d3baEnrico Granata
14053a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb::ValueObjectSP
14063a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granatalldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
14073a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata{
14083a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
14093a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
14103a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14113a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    uint32_t num_children = CalculateNumChildren();
14123a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14133a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (idx >= num_children)
14143a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return lldb::ValueObjectSP();
14153a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14163a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (m_children.empty())
14173a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    {
14183a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        // do the scan phase
14193a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        lldb::addr_t key_at_idx = 0, val_at_idx = 0;
14203a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14213a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        uint32_t tries = 0;
14223a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        uint32_t test_idx = 0;
14233a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14243a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        while(tries < num_children)
14253a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        {
14263a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
14273a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
14283a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
14293a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            if (!process_sp)
14303a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata                return lldb::ValueObjectSP();
14313a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            Error error;
14323a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
14333a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            if (error.Fail())
14343a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata                return lldb::ValueObjectSP();
14353a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
14363a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            if (error.Fail())
14373a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata                return lldb::ValueObjectSP();
14383a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14393a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            test_idx++;
14403a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14413a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            if (!key_at_idx || !val_at_idx)
14423a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata                continue;
14433a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            tries++;
14443a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14453a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
14463a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14473a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata            m_children.push_back(descriptor);
14483a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        }
14493a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    }
14503a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14513a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (idx >= m_children.size()) // should never happen
14523a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        return lldb::ValueObjectSP();
14533a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata
14543a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    DictionaryItemDescriptor &dict_item = m_children[idx];
14553a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    if (!dict_item.valobj_sp)
14563a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    {
14573a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        // make the new ValueObject
14583a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        StreamString expr;
14595f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%" PRIu64 " ; _lldb_valgen_item.value = (id)%" PRIu64 "; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
14603a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        StreamString idx_name;
14613a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        idx_name.Printf("[%d]",idx);
14623a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata        dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
14633a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    }
14643a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata    return dict_item.valobj_sp;
14653a08fd1ab40ac76a732836ee5b1b5aa23605f669Enrico Granata}
1466f91e78f58692785db4daecf8461481b95827dcf2Enrico Granata
1467caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatatemplate bool
1468f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
1469caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
1470caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatatemplate bool
1471f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
1472caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
1473caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatatemplate bool
1474f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
1475caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granata
1476caaf010fb83b4c28bf585db2288837e6611e419eEnrico Granatatemplate bool
1477f91e78f58692785db4daecf8461481b95827dcf2Enrico Granatalldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
1478db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
1479db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatatemplate bool
1480db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatalldb_private::formatters::ObjCSELSummaryProvider<true> (ValueObject&, Stream&) ;
1481db05491da80820047dc218542c88ba0d9f08fc71Enrico Granata
1482db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatatemplate bool
1483db05491da80820047dc218542c88ba0d9f08fc71Enrico Granatalldb_private::formatters::ObjCSELSummaryProvider<false> (ValueObject&, Stream&) ;
1484