Skip to content
This repository was archived by the owner on May 21, 2019. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ae2ae94

Browse files
author
Enrico Granata
committedSep 4, 2012
<rdar://problem/11485744> Implement important data formatters in C++. Have the Objective-C language runtime plugin expose class descriptors objects akin to the objc_runtime.py Pythonic implementation. Rewrite the data formatters for some core Cocoa classes in C++ instead of Python.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@163155 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 4793e94 commit ae2ae94

File tree

20 files changed

+1176
-216
lines changed

20 files changed

+1176
-216
lines changed
 

‎examples/summaries/cocoa/CFArray.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
This file is distributed under the University of Illinois Open Source
66
License. See LICENSE.TXT for details.
77
"""
8-
# synthetic children provider for NSArray
8+
# example summary provider for NSArray
9+
# the real summary is now C++ code built into LLDB
910
import lldb
1011
import ctypes
1112
import lldb.runtime.objc.objc_runtime

‎examples/summaries/cocoa/CFDictionary.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
This file is distributed under the University of Illinois Open Source
66
License. See LICENSE.TXT for details.
77
"""
8-
# summary provider for NSDictionary
8+
# example summary provider for NSDictionary
9+
# the real summary is now C++ code built into LLDB
910
import lldb
1011
import ctypes
1112
import lldb.runtime.objc.objc_runtime

‎examples/summaries/cocoa/NSData.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
This file is distributed under the University of Illinois Open Source
66
License. See LICENSE.TXT for details.
77
"""
8-
# summary provider for NSData
8+
# example summary provider for NSData
9+
# the real summary is now C++ code built into LLDB
910
import lldb
1011
import ctypes
1112
import lldb.runtime.objc.objc_runtime

‎examples/summaries/cocoa/NSNumber.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
This file is distributed under the University of Illinois Open Source
66
License. See LICENSE.TXT for details.
77
"""
8-
# summary provider for NSNumber
8+
# example summary provider for NSNumber
9+
# the real summary is now C++ code built into LLDB
910
import lldb
1011
import ctypes
1112
import lldb.runtime.objc.objc_runtime

‎include/lldb/Core/FormatClasses.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,14 @@ class TypeSummaryImpl
10911091
uint32_t m_flags;
10921092
};
10931093

1094+
typedef enum Type
1095+
{
1096+
eTypeUnknown,
1097+
eTypeString,
1098+
eTypeScript,
1099+
eTypeCallback
1100+
} Type;
1101+
10941102
TypeSummaryImpl (const TypeSummaryImpl::Flags& flags);
10951103

10961104
bool
@@ -1205,6 +1213,9 @@ class TypeSummaryImpl
12051213
virtual bool
12061214
IsScripted() = 0;
12071215

1216+
virtual Type
1217+
GetType () = 0;
1218+
12081219
uint32_t&
12091220
GetRevision ()
12101221
{
@@ -1265,9 +1276,89 @@ struct StringSummaryFormat : public TypeSummaryImpl
12651276
}
12661277

12671278

1279+
virtual Type
1280+
GetType ()
1281+
{
1282+
return TypeSummaryImpl::eTypeString;
1283+
}
1284+
12681285
private:
12691286
DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat);
12701287
};
1288+
1289+
// summaries implemented via a C++ function
1290+
struct CXXFunctionSummaryFormat : public TypeSummaryImpl
1291+
{
1292+
1293+
// we should convert these to SBValue and SBStream if we ever cross
1294+
// the boundary towards the external world
1295+
typedef bool (*Callback)(ValueObject& valobj,
1296+
Stream& dest);
1297+
1298+
1299+
Callback m_impl;
1300+
std::string m_description;
1301+
1302+
CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags& flags,
1303+
Callback impl,
1304+
const char* description);
1305+
1306+
Callback
1307+
GetBackendFunction () const
1308+
{
1309+
return m_impl;
1310+
}
1311+
1312+
const char*
1313+
GetTextualInfo () const
1314+
{
1315+
return m_description.c_str();
1316+
}
1317+
1318+
void
1319+
SetBackendFunction (Callback cb_func)
1320+
{
1321+
m_impl = cb_func;
1322+
}
1323+
1324+
void
1325+
SetTextualInfo (const char* descr)
1326+
{
1327+
if (descr)
1328+
m_description.assign(descr);
1329+
else
1330+
m_description.clear();
1331+
}
1332+
1333+
virtual
1334+
~CXXFunctionSummaryFormat()
1335+
{
1336+
}
1337+
1338+
virtual bool
1339+
FormatObject(ValueObject *valobj,
1340+
std::string& dest);
1341+
1342+
virtual std::string
1343+
GetDescription();
1344+
1345+
virtual bool
1346+
IsScripted()
1347+
{
1348+
return false;
1349+
}
1350+
1351+
virtual Type
1352+
GetType ()
1353+
{
1354+
return TypeSummaryImpl::eTypeCallback;
1355+
}
1356+
1357+
typedef STD_SHARED_PTR(CXXFunctionSummaryFormat) SharedPointer;
1358+
1359+
private:
1360+
DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat);
1361+
};
12711362

12721363
#ifndef LLDB_DISABLE_PYTHON
12731364

@@ -1331,6 +1422,12 @@ struct ScriptSummaryFormat : public TypeSummaryImpl
13311422
return true;
13321423
}
13331424

1425+
virtual Type
1426+
GetType ()
1427+
{
1428+
return TypeSummaryImpl::eTypeScript;
1429+
}
1430+
13341431
typedef STD_SHARED_PTR(ScriptSummaryFormat) SharedPointer;
13351432

13361433

‎include/lldb/Core/Module.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,9 @@ class Module :
571571
//------------------------------------------------------------------
572572
virtual ObjectFile *
573573
GetObjectFile ();
574+
575+
uint32_t
576+
GetVersion (uint32_t *versions, uint32_t num_versions);
574577

575578
// Load an object file from memory.
576579
ObjectFile *

‎include/lldb/Target/ObjCLanguageRuntime.h

Lines changed: 146 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,145 @@ class ObjCLanguageRuntime :
2929
public LanguageRuntime
3030
{
3131
public:
32+
33+
typedef lldb::addr_t ObjCISA;
34+
35+
class ClassDescriptor;
36+
typedef STD_SHARED_PTR(ClassDescriptor) ClassDescriptorSP;
37+
38+
// the information that we want to support retrieving from an ObjC class
39+
// this needs to be pure virtual since there are at least 2 different implementations
40+
// of the runtime, and more might come
41+
class ClassDescriptor
42+
{
43+
public:
44+
45+
ClassDescriptor() :
46+
m_is_kvo(eLazyBoolCalculate),
47+
m_is_cf(eLazyBoolCalculate)
48+
{}
49+
50+
ClassDescriptor (ObjCISA isa, lldb::ProcessSP process) :
51+
m_is_kvo(eLazyBoolCalculate),
52+
m_is_cf(eLazyBoolCalculate)
53+
{}
54+
55+
virtual ConstString
56+
GetClassName () = 0;
57+
58+
virtual ClassDescriptorSP
59+
GetSuperclass () = 0;
60+
61+
// virtual if any implementation has some other version-specific rules
62+
// but for the known v1/v2 this is all that needs to be done
63+
virtual bool
64+
IsKVO ()
65+
{
66+
if (m_is_kvo == eLazyBoolCalculate)
67+
{
68+
const char* class_name = GetClassName().AsCString();
69+
m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name);
70+
}
71+
return (m_is_kvo == eLazyBoolYes);
72+
}
73+
74+
// virtual if any implementation has some other version-specific rules
75+
// but for the known v1/v2 this is all that needs to be done
76+
virtual bool
77+
IsCFType ()
78+
{
79+
if (m_is_cf == eLazyBoolCalculate)
80+
{
81+
const char* class_name = GetClassName().AsCString();
82+
m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 ||
83+
strcmp(class_name,"NSCFType") == 0);
84+
}
85+
return (m_is_cf == eLazyBoolYes);
86+
}
87+
88+
virtual bool
89+
IsValid () = 0;
90+
91+
virtual bool
92+
IsTagged () = 0;
93+
94+
virtual uint64_t
95+
GetInstanceSize () = 0;
96+
97+
// use to implement version-specific additional constraints on pointers
98+
virtual bool
99+
CheckPointer (lldb::addr_t value,
100+
uint32_t ptr_size)
101+
{
102+
return true;
103+
}
104+
105+
virtual ObjCISA
106+
GetISA () = 0;
107+
108+
virtual
109+
~ClassDescriptor ()
110+
{}
111+
112+
protected:
113+
bool
114+
IsPointerValid (lldb::addr_t value,
115+
uint32_t ptr_size,
116+
bool allow_NULLs = false,
117+
bool allow_tagged = false,
118+
bool check_version_specific = false);
119+
120+
private:
121+
LazyBool m_is_kvo;
122+
LazyBool m_is_cf;
123+
};
124+
125+
// a convenience subclass of ClassDescriptor meant to represent invalid objects
126+
class ClassDescriptor_Invalid : public ClassDescriptor
127+
{
128+
public:
129+
ClassDescriptor_Invalid() {}
130+
131+
virtual ConstString
132+
GetClassName () { return ConstString(""); }
133+
134+
virtual ClassDescriptorSP
135+
GetSuperclass () { return ClassDescriptorSP(new ClassDescriptor_Invalid()); }
136+
137+
virtual bool
138+
IsValid () { return false; }
139+
140+
virtual bool
141+
IsTagged () { return false; }
142+
143+
virtual uint64_t
144+
GetInstanceSize () { return 0; }
145+
146+
virtual ObjCISA
147+
GetISA () { return 0; }
148+
149+
virtual bool
150+
CheckPointer (lldb::addr_t value,
151+
uint32_t ptr_size) { return false; }
152+
153+
virtual
154+
~ClassDescriptor_Invalid ()
155+
{}
156+
157+
};
158+
159+
virtual ClassDescriptorSP
160+
GetClassDescriptor (ValueObject& in_value)
161+
{
162+
return ClassDescriptorSP();
163+
}
164+
165+
virtual ClassDescriptorSP
166+
GetClassDescriptor (ObjCISA isa)
167+
{
168+
return ClassDescriptorSP();
169+
}
170+
32171
virtual
33172
~ObjCLanguageRuntime();
34173

@@ -77,19 +216,17 @@ class ObjCLanguageRuntime :
77216
return eObjC_VersionUnknown;
78217
}
79218

80-
typedef lldb::addr_t ObjCISA;
81-
82219
virtual bool
83220
IsValidISA(ObjCISA isa) = 0;
84221

85222
virtual ObjCISA
86223
GetISA(ValueObject& valobj) = 0;
87224

88225
virtual ConstString
89-
GetActualTypeName(ObjCISA isa) = 0;
226+
GetActualTypeName(ObjCISA isa);
90227

91228
virtual ObjCISA
92-
GetParentClass(ObjCISA isa) = 0;
229+
GetParentClass(ObjCISA isa);
93230

94231
virtual SymbolVendor *
95232
GetSymbolVendor()
@@ -267,6 +404,11 @@ class ObjCLanguageRuntime :
267404

268405
LazyBool m_has_new_literals_and_indexing;
269406
protected:
407+
408+
typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
409+
typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
410+
ISAToDescriptorMap m_isa_to_descriptor_cache;
411+
270412
typedef std::map<lldb::addr_t,TypeAndOrName> ClassNameMap;
271413
typedef ClassNameMap::iterator ClassNameIterator;
272414
ClassNameMap m_class_name_cache;

‎lldb.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@
529529
9475C18F14E5F858001BFC6D /* SBTypeNameSpecifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 9475C18C14E5F826001BFC6D /* SBTypeNameSpecifier.h */; settings = {ATTRIBUTES = (Public, ); }; };
530530
949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */; };
531531
94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; };
532+
94CDEB9D15F0258500DD2A7A /* CXXFormatterFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CDEB9C15F0258400DD2A7A /* CXXFormatterFunctions.cpp */; };
532533
94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */; };
533534
94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */; };
534535
9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1535,6 +1536,8 @@
15351536
94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatClasses.cpp; path = source/Core/FormatClasses.cpp; sourceTree = "<group>"; };
15361537
94B6E76013D8833C005F417F /* ValueObjectSyntheticFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectSyntheticFilter.h; path = include/lldb/Core/ValueObjectSyntheticFilter.h; sourceTree = "<group>"; };
15371538
94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectSyntheticFilter.cpp; path = source/Core/ValueObjectSyntheticFilter.cpp; sourceTree = "<group>"; };
1539+
94CDEB9A15F0226900DD2A7A /* CXXFormatterFunctions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CXXFormatterFunctions.h; path = include/lldb/Core/CXXFormatterFunctions.h; sourceTree = "<group>"; };
1540+
94CDEB9C15F0258400DD2A7A /* CXXFormatterFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CXXFormatterFunctions.cpp; path = source/Core/CXXFormatterFunctions.cpp; sourceTree = "<group>"; };
15381541
94E367CC140C4EC4001C7A5A /* modify-python-lldb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "modify-python-lldb.py"; sourceTree = "<group>"; };
15391542
94E367CE140C4EEA001C7A5A /* python-typemaps.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-typemaps.swig"; sourceTree = "<group>"; };
15401543
94EA1D5A15E6C99B00D4171A /* PythonDataObjects.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonDataObjects.h; path = include/lldb/Interpreter/PythonDataObjects.h; sourceTree = "<group>"; };
@@ -2455,6 +2458,8 @@
24552458
266603C91345B5A8004DA8B6 /* ConnectionSharedMemory.cpp */,
24562459
26BC7D7C10F1B77400F91463 /* ConstString.h */,
24572460
26BC7E9410F1B85900F91463 /* ConstString.cpp */,
2461+
94CDEB9A15F0226900DD2A7A /* CXXFormatterFunctions.h */,
2462+
94CDEB9C15F0258400DD2A7A /* CXXFormatterFunctions.cpp */,
24582463
26BC7D5910F1B77400F91463 /* DataBuffer.h */,
24592464
26BC7D5B10F1B77400F91463 /* DataBufferHeap.h */,
24602465
26BC7E7210F1B85900F91463 /* DataBufferHeap.cpp */,
@@ -4111,6 +4116,7 @@
41114116
2697A39315E404B1003E682C /* OptionValueArch.cpp in Sources */,
41124117
94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */,
41134118
2698699B15E6CBD0002415FF /* OperatingSystemPython.cpp in Sources */,
4119+
94CDEB9D15F0258500DD2A7A /* CXXFormatterFunctions.cpp in Sources */,
41144120
);
41154121
runOnlyForDeploymentPostprocessing = 0;
41164122
};

0 commit comments

Comments
 (0)
This repository has been archived.