Skip to content

Commit 15f7423

Browse files
committed
TypeGraph: Switch from pointers to references
References must always have a value, so are semantically clearer than pointers for variables which must always be set. No functional changes.
1 parent 66ea2cb commit 15f7423

28 files changed

+439
-404
lines changed

oi/CodeGen.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ void CodeGen::genDefsThrift(const TypeGraph& typeGraph, std::string& code) {
219219
if (const auto* c = dynamic_cast<const Class*>(&t)) {
220220
const Member* issetMember = nullptr;
221221
for (const auto& member : c->members) {
222-
if (const auto* container = dynamic_cast<const Container*>(member.type);
222+
if (const auto* container =
223+
dynamic_cast<const Container*>(&member.type());
223224
container && container->containerInfo_.ctype == THRIFT_ISSET_TYPE) {
224225
issetMember = &member;
225226
break;
@@ -247,7 +248,7 @@ void genDefsClass(const Class& c, std::string& code) {
247248

248249
code += c.name() + " {\n";
249250
for (const auto& mem : c.members) {
250-
code += " " + mem.type->name() + " " + mem.name;
251+
code += " " + mem.type().name() + " " + mem.name;
251252
if (mem.bitsize) {
252253
code += " : " + std::to_string(mem.bitsize);
253254
}
@@ -257,7 +258,7 @@ void genDefsClass(const Class& c, std::string& code) {
257258
}
258259

259260
void genDefsTypedef(const Typedef& td, std::string& code) {
260-
code += "using " + td.name() + " = " + td.underlyingType()->name() + ";\n";
261+
code += "using " + td.name() + " = " + td.underlyingType().name() + ";\n";
261262
}
262263

263264
void genDefs(const TypeGraph& typeGraph, std::string& code) {
@@ -705,8 +706,8 @@ void CodeGen::addDrgnRoot(struct drgn_type* drgnType,
705706
type_graph::TypeGraph& typeGraph) {
706707
type_graph::DrgnParser drgnParser{
707708
typeGraph, containerInfos_, config_.features[Feature::ChaseRawPointers]};
708-
Type* parsedRoot = drgnParser.parse(drgnType);
709-
typeGraph.addRoot(*parsedRoot);
709+
Type& parsedRoot = drgnParser.parse(drgnType);
710+
typeGraph.addRoot(parsedRoot);
710711
}
711712

712713
void CodeGen::transform(type_graph::TypeGraph& typeGraph) {

oi/CodeGen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class SymbolService;
3131

3232
namespace type_graph {
3333
class Class;
34-
struct Member;
34+
class Member;
3535
class TypeGraph;
3636
} // namespace type_graph
3737

oi/type_graph/AddChildren.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ void AddChildren::visit(Type& type) {
5353

5454
void AddChildren::visit(Class& c) {
5555
for (auto& param : c.templateParams) {
56-
visit(param.type);
56+
visit(param.type());
5757
}
5858
for (auto& member : c.members) {
59-
visit(*member.type);
59+
visit(member.type());
6060
}
6161

6262
if (!c.isDynamic()) {
@@ -70,10 +70,10 @@ void AddChildren::visit(Class& c) {
7070

7171
const auto& drgnChildren = it->second;
7272
for (drgn_type* drgnChild : drgnChildren) {
73-
Type* childType = drgnParser_.parse(drgnChild);
73+
Type& childType = drgnParser_.parse(drgnChild);
7474
auto* childClass =
75-
dynamic_cast<Class*>(childType); // TODO don't use dynamic_cast
76-
if (!childClass) // TODO dodgy error handling
75+
dynamic_cast<Class*>(&childType); // TODO don't use dynamic_cast
76+
if (!childClass) // TODO dodgy error handling
7777
abort();
7878
c.children.push_back(*childClass);
7979

oi/type_graph/AddPadding.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ void AddPadding::visit(Class& c) {
5050
assert(c.parents.empty());
5151

5252
for (auto& param : c.templateParams) {
53-
visit(param.type);
53+
visit(param.type());
5454
}
5555
for (auto& member : c.members) {
56-
visit(*member.type);
56+
visit(member.type());
5757
}
5858

5959
if (c.kind() == Class::Kind::Union) {
@@ -86,7 +86,7 @@ void AddPadding::addPadding(const Member& prevMember,
8686
std::vector<Member>& paddedMembers) {
8787
uint64_t prevMemberSizeBits;
8888
if (prevMember.bitsize == 0) {
89-
prevMemberSizeBits = prevMember.type->size() * 8;
89+
prevMemberSizeBits = prevMember.type().size() * 8;
9090
} else {
9191
prevMemberSizeBits = prevMember.bitsize;
9292
}
@@ -98,12 +98,12 @@ void AddPadding::addPadding(const Member& prevMember,
9898

9999
if (paddingBits % 8 == 0) {
100100
// Pad with an array of bytes
101-
auto* primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8);
102-
auto* paddingArray = typeGraph_.makeType<Array>(primitive, paddingBits / 8);
101+
auto& primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8);
102+
auto& paddingArray = typeGraph_.makeType<Array>(primitive, paddingBits / 8);
103103
paddedMembers.emplace_back(paddingArray, MemberPrefix, prevMemberEndBits);
104104
} else {
105105
// Pad with a bitfield
106-
auto* primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int64);
106+
auto& primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int64);
107107
paddedMembers.emplace_back(primitive, MemberPrefix, prevMemberEndBits,
108108
paddingBits);
109109
}

oi/type_graph/AlignmentCalc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ void AlignmentCalc::visit(Class& c) {
5858
if (member.align == 0) {
5959
// If the member does not have an explicit alignment, calculate it from
6060
// the member's type.
61-
visit(*member.type);
62-
member.align = member.type->align();
61+
visit(member.type());
62+
member.align = member.type().align();
6363
}
6464
alignment = std::max(alignment, member.align);
6565
}

oi/type_graph/DrgnParser.cpp

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ Primitive::Kind primitiveFloatKind(struct drgn_type* type) {
7575

7676
// TODO type stubs
7777

78-
Type* DrgnParser::parse(struct drgn_type* root) {
78+
Type& DrgnParser::parse(struct drgn_type* root) {
7979
depth_ = 0;
8080
return enumerateType(root);
8181
}
8282

83-
Type* DrgnParser::enumerateType(struct drgn_type* type) {
83+
Type& DrgnParser::enumerateType(struct drgn_type* type) {
8484
// Avoid re-enumerating an already-processsed type
8585
if (auto it = drgn_types_.find(type); it != drgn_types_.end())
8686
return it->second;
@@ -96,34 +96,40 @@ Type* DrgnParser::enumerateType(struct drgn_type* type) {
9696
case DRGN_TYPE_CLASS:
9797
case DRGN_TYPE_STRUCT:
9898
case DRGN_TYPE_UNION:
99-
t = enumerateClass(type);
99+
t = &enumerateClass(type);
100100
break;
101101
case DRGN_TYPE_ENUM:
102-
t = enumerateEnum(type);
102+
t = &enumerateEnum(type);
103103
break;
104104
case DRGN_TYPE_TYPEDEF:
105-
t = enumerateTypedef(type);
105+
t = &enumerateTypedef(type);
106106
break;
107107
case DRGN_TYPE_POINTER:
108-
t = enumeratePointer(type);
108+
t = &enumeratePointer(type);
109109
break;
110110
case DRGN_TYPE_ARRAY:
111-
t = enumerateArray(type);
111+
t = &enumerateArray(type);
112112
break;
113113
case DRGN_TYPE_INT:
114114
case DRGN_TYPE_BOOL:
115115
case DRGN_TYPE_FLOAT:
116116
case DRGN_TYPE_VOID:
117-
t = enumeratePrimitive(type);
117+
t = &enumeratePrimitive(type);
118118
break;
119119
default:
120120
throw DrgnParserError{"Unknown drgn type kind: " + std::to_string(kind)};
121121
}
122122
depth_--;
123123

124-
return t;
124+
return *t;
125125
}
126126

127+
/*
128+
* enumerateContainer
129+
*
130+
* Attempts to parse a drgn_type as a Container. Returns nullptr if not
131+
* sucessful.
132+
*/
127133
Container* DrgnParser::enumerateContainer(struct drgn_type* type,
128134
const std::string& fqName) {
129135
auto size = get_drgn_type_size(type);
@@ -135,14 +141,14 @@ Container* DrgnParser::enumerateContainer(struct drgn_type* type,
135141

136142
VLOG(2) << "Matching container `" << containerInfo.typeName << "` from `"
137143
<< fqName << "`" << std::endl;
138-
auto* c = makeType<Container>(type, containerInfo, size);
139-
enumerateClassTemplateParams(type, c->templateParams);
140-
return c;
144+
auto& c = makeType<Container>(type, containerInfo, size);
145+
enumerateClassTemplateParams(type, c.templateParams);
146+
return &c;
141147
}
142148
return nullptr;
143149
}
144150

145-
Type* DrgnParser::enumerateClass(struct drgn_type* type) {
151+
Type& DrgnParser::enumerateClass(struct drgn_type* type) {
146152
std::string fqName;
147153
char* nameStr = nullptr;
148154
size_t length = 0;
@@ -153,7 +159,7 @@ Type* DrgnParser::enumerateClass(struct drgn_type* type) {
153159

154160
auto* container = enumerateContainer(type, fqName);
155161
if (container)
156-
return container;
162+
return *container;
157163

158164
std::string name;
159165
const char* type_tag = drgn_type_tag(type);
@@ -183,13 +189,13 @@ Type* DrgnParser::enumerateClass(struct drgn_type* type) {
183189
std::to_string(drgn_type_kind(type))};
184190
}
185191

186-
auto c = makeType<Class>(type, kind, std::move(name), std::move(fqName), size,
187-
virtuality);
192+
auto& c = makeType<Class>(type, kind, std::move(name), std::move(fqName),
193+
size, virtuality);
188194

189-
enumerateClassTemplateParams(type, c->templateParams);
190-
enumerateClassParents(type, c->parents);
191-
enumerateClassMembers(type, c->members);
192-
enumerateClassFunctions(type, c->functions);
195+
enumerateClassTemplateParams(type, c.templateParams);
196+
enumerateClassParents(type, c.parents);
197+
enumerateClassMembers(type, c.members);
198+
enumerateClassFunctions(type, c.functions);
193199

194200
return c;
195201
}
@@ -211,9 +217,9 @@ void DrgnParser::enumerateClassParents(struct drgn_type* type,
211217
"Error looking up parent type (" + std::to_string(i) + ")", err};
212218
}
213219

214-
auto ptype = enumerateType(parent_qual_type.type);
220+
auto& ptype = enumerateType(parent_qual_type.type);
215221
uint64_t poffset = drgn_parents[i].bit_offset;
216-
Parent p(ptype, poffset);
222+
Parent p{ptype, poffset};
217223
parents.push_back(p);
218224
}
219225

@@ -258,7 +264,7 @@ void DrgnParser::enumerateClassMembers(struct drgn_type* type,
258264
if (drgn_members[i].name)
259265
member_name = drgn_members[i].name;
260266

261-
auto mtype = enumerateType(member_type);
267+
auto& mtype = enumerateType(member_type);
262268
uint64_t moffset = drgn_members[i].bit_offset;
263269

264270
Member m{mtype, member_name, moffset, bit_field_size};
@@ -297,7 +303,7 @@ void DrgnParser::enumerateTemplateParam(drgn_type_template_parameter* tparams,
297303
qualifiers[Qualifier::Const] =
298304
(tparamQualType.qualifiers & DRGN_QUALIFIER_CONST);
299305

300-
auto ttype = enumerateType(tparamType);
306+
auto& ttype = enumerateType(tparamType);
301307
params.emplace_back(ttype, qualifiers);
302308
} else {
303309
// This template parameter is a value
@@ -411,7 +417,7 @@ void DrgnParser::enumerateClassFunctions(struct drgn_type* type,
411417
}
412418
}
413419

414-
Enum* DrgnParser::enumerateEnum(struct drgn_type* type) {
420+
Enum& DrgnParser::enumerateEnum(struct drgn_type* type) {
415421
// TODO anonymous enums
416422
// TODO incomplete enum?
417423
std::string name = drgn_type_tag(type);
@@ -420,16 +426,16 @@ Enum* DrgnParser::enumerateEnum(struct drgn_type* type) {
420426
return makeType<Enum>(type, name, size);
421427
}
422428

423-
Typedef* DrgnParser::enumerateTypedef(struct drgn_type* type) {
429+
Typedef& DrgnParser::enumerateTypedef(struct drgn_type* type) {
424430
std::string name = drgn_type_name(type);
425431
// TODO anonymous typedefs?
426432

427433
struct drgn_type* underlyingType = drgn_type_type(type).type;
428-
auto t = enumerateType(underlyingType);
434+
auto& t = enumerateType(underlyingType);
429435
return makeType<Typedef>(type, name, t);
430436
}
431437

432-
Type* DrgnParser::enumeratePointer(struct drgn_type* type) {
438+
Type& DrgnParser::enumeratePointer(struct drgn_type* type) {
433439
if (!chasePointer()) {
434440
// TODO dodgy nullptr - primitives should be handled as singletons
435441
return makeType<Primitive>(nullptr, Primitive::Kind::UIntPtr);
@@ -439,18 +445,18 @@ Type* DrgnParser::enumeratePointer(struct drgn_type* type) {
439445

440446
// TODO why was old CodeGen following funciton pointers?
441447

442-
Type* t = enumerateType(pointeeType);
448+
Type& t = enumerateType(pointeeType);
443449
return makeType<Pointer>(type, t);
444450
}
445451

446-
Array* DrgnParser::enumerateArray(struct drgn_type* type) {
452+
Array& DrgnParser::enumerateArray(struct drgn_type* type) {
447453
struct drgn_type* elementType = drgn_type_type(type).type;
448454
uint64_t len = drgn_type_length(type);
449-
auto t = enumerateType(elementType);
455+
auto& t = enumerateType(elementType);
450456
return makeType<Array>(type, t, len);
451457
}
452458

453-
Primitive* DrgnParser::enumeratePrimitive(struct drgn_type* type) {
459+
Primitive& DrgnParser::enumeratePrimitive(struct drgn_type* type) {
454460
Primitive::Kind kind;
455461
switch (drgn_type_kind(type)) {
456462
case DRGN_TYPE_INT:

oi/type_graph/DrgnParser.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,18 @@ class DrgnParser {
3838
containers_(containers),
3939
chaseRawPointers_(chaseRawPointers) {
4040
}
41-
Type* parse(struct drgn_type* root);
41+
Type& parse(struct drgn_type* root);
4242

4343
private:
44-
Type* enumerateType(struct drgn_type* type);
44+
Type& enumerateType(struct drgn_type* type);
4545
Container* enumerateContainer(struct drgn_type* type,
4646
const std::string& fqName);
47-
Type* enumerateClass(struct drgn_type* type);
48-
Enum* enumerateEnum(struct drgn_type* type);
49-
Typedef* enumerateTypedef(struct drgn_type* type);
50-
Type* enumeratePointer(struct drgn_type* type);
51-
Array* enumerateArray(struct drgn_type* type);
52-
Primitive* enumeratePrimitive(struct drgn_type* type);
47+
Type& enumerateClass(struct drgn_type* type);
48+
Enum& enumerateEnum(struct drgn_type* type);
49+
Typedef& enumerateTypedef(struct drgn_type* type);
50+
Type& enumeratePointer(struct drgn_type* type);
51+
Array& enumerateArray(struct drgn_type* type);
52+
Primitive& enumeratePrimitive(struct drgn_type* type);
5353

5454
void enumerateTemplateParam(drgn_type_template_parameter* tparams,
5555
size_t i,
@@ -65,13 +65,14 @@ class DrgnParser {
6565

6666
// Store a mapping of drgn types to type graph nodes for deduplication during
6767
// parsing. This stops us getting caught in cycles.
68-
std::unordered_map<struct drgn_type*, Type*> drgn_types_;
68+
std::unordered_map<struct drgn_type*, std::reference_wrapper<Type>>
69+
drgn_types_;
6970

7071
template <typename T, typename... Args>
71-
T* makeType(struct drgn_type* type, Args&&... args) {
72-
auto* type_raw_ptr = typeGraph_.makeType<T>(std::forward<Args>(args)...);
73-
drgn_types_.insert({type, type_raw_ptr});
74-
return type_raw_ptr;
72+
T& makeType(struct drgn_type* drgnType, Args&&... args) {
73+
auto& newType = typeGraph_.makeType<T>(std::forward<Args>(args)...);
74+
drgn_types_.insert({drgnType, newType});
75+
return newType;
7576
}
7677
bool chasePointer() const;
7778

0 commit comments

Comments
 (0)