Skip to content

Commit 23efc8d

Browse files
committed
TypeGraph: Add Node IDs to non-leaf types
These aren't used for anything yet, but should be useful for stable IDs when printing nodes before and after passes and for faster cycle detection than the current map of pointers.
1 parent 608880e commit 23efc8d

19 files changed

+296
-234
lines changed

oi/type_graph/AddPadding.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +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_.make_type<Primitive>(Primitive::Kind::Int8);
102-
auto* paddingArray =
103-
typeGraph_.make_type<Array>(primitive, paddingBits / 8);
101+
auto* primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8);
102+
auto* paddingArray = typeGraph_.makeType<Array>(primitive, paddingBits / 8);
104103
paddedMembers.emplace_back(paddingArray, MemberPrefix, prevMemberEndBits);
105104
} else {
106105
// Pad with a bitfield
107-
auto* primitive = typeGraph_.make_type<Primitive>(Primitive::Kind::Int64);
106+
auto* primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int64);
108107
paddedMembers.emplace_back(primitive, MemberPrefix, prevMemberEndBits,
109108
paddingBits);
110109
}

oi/type_graph/DrgnParser.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ Type* DrgnParser::enumerateType(struct drgn_type* type) {
8686
return it->second;
8787

8888
if (!drgn_utils::isSizeComplete(type)) {
89-
return make_type<Primitive>(nullptr, Primitive::Kind::Void);
89+
return makeType<Primitive>(nullptr, Primitive::Kind::Void);
9090
}
9191

9292
enum drgn_type_kind kind = drgn_type_kind(type);
@@ -135,7 +135,7 @@ Container* DrgnParser::enumerateContainer(struct drgn_type* type,
135135

136136
VLOG(2) << "Matching container `" << containerInfo.typeName << "` from `"
137137
<< fqName << "`" << std::endl;
138-
auto* c = make_type<Container>(type, containerInfo, size);
138+
auto* c = makeType<Container>(type, containerInfo, size);
139139
enumerateClassTemplateParams(type, c->templateParams);
140140
return c;
141141
}
@@ -183,8 +183,8 @@ Type* DrgnParser::enumerateClass(struct drgn_type* type) {
183183
std::to_string(drgn_type_kind(type))};
184184
}
185185

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

189189
enumerateClassTemplateParams(type, c->templateParams);
190190
enumerateClassParents(type, c->parents);
@@ -417,7 +417,7 @@ Enum* DrgnParser::enumerateEnum(struct drgn_type* type) {
417417
std::string name = drgn_type_tag(type);
418418
uint64_t size = get_drgn_type_size(type);
419419
;
420-
return make_type<Enum>(type, name, size);
420+
return makeType<Enum>(type, name, size);
421421
}
422422

423423
Typedef* DrgnParser::enumerateTypedef(struct drgn_type* type) {
@@ -426,28 +426,28 @@ Typedef* DrgnParser::enumerateTypedef(struct drgn_type* type) {
426426

427427
struct drgn_type* underlyingType = drgn_type_type(type).type;
428428
auto t = enumerateType(underlyingType);
429-
return make_type<Typedef>(type, name, t);
429+
return makeType<Typedef>(type, name, t);
430430
}
431431

432432
Type* DrgnParser::enumeratePointer(struct drgn_type* type) {
433433
if (!chasePointer()) {
434434
// TODO dodgy nullptr - primitives should be handled as singletons
435-
return make_type<Primitive>(nullptr, Primitive::Kind::UIntPtr);
435+
return makeType<Primitive>(nullptr, Primitive::Kind::UIntPtr);
436436
}
437437

438438
struct drgn_type* pointeeType = drgn_type_type(type).type;
439439

440440
// TODO why was old CodeGen following funciton pointers?
441441

442442
Type* t = enumerateType(pointeeType);
443-
return make_type<Pointer>(type, t);
443+
return makeType<Pointer>(type, t);
444444
}
445445

446446
Array* DrgnParser::enumerateArray(struct drgn_type* type) {
447447
struct drgn_type* elementType = drgn_type_type(type).type;
448448
uint64_t len = drgn_type_length(type);
449449
auto t = enumerateType(elementType);
450-
return make_type<Array>(type, t, len);
450+
return makeType<Array>(type, t, len);
451451
}
452452

453453
Primitive* DrgnParser::enumeratePrimitive(struct drgn_type* type) {
@@ -469,7 +469,7 @@ Primitive* DrgnParser::enumeratePrimitive(struct drgn_type* type) {
469469
throw DrgnParserError{"Invalid drgn type kind for primitive: " +
470470
std::to_string(drgn_type_kind(type))};
471471
}
472-
return make_type<Primitive>(type, kind);
472+
return makeType<Primitive>(type, kind);
473473
}
474474

475475
bool DrgnParser::chasePointer() const {

oi/type_graph/DrgnParser.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,8 @@ class DrgnParser {
6868
std::unordered_map<struct drgn_type*, Type*> drgn_types_;
6969

7070
template <typename T, typename... Args>
71-
T* make_type(struct drgn_type* type, Args&&... args) {
72-
auto type_unique_ptr = std::make_unique<T>(std::forward<Args>(args)...);
73-
auto type_raw_ptr = type_unique_ptr.get();
74-
typeGraph_.add(std::move(type_unique_ptr));
71+
T* makeType(struct drgn_type* type, Args&&... args) {
72+
auto* type_raw_ptr = typeGraph_.makeType<T>(std::forward<Args>(args)...);
7573
drgn_types_.insert({type, type_raw_ptr});
7674
return type_raw_ptr;
7775
}

oi/type_graph/RemoveIgnored.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ void RemoveIgnored::visit(Class& c) {
4444
if (!ignoreMember(c.name(), c.members[i].name)) {
4545
continue;
4646
}
47-
auto* primitive = typeGraph_.make_type<Primitive>(Primitive::Kind::Int8);
47+
auto* primitive = typeGraph_.makeType<Primitive>(Primitive::Kind::Int8);
4848
auto* paddingArray =
49-
typeGraph_.make_type<Array>(primitive, c.members[i].type->size());
49+
typeGraph_.makeType<Array>(primitive, c.members[i].type->size());
5050
c.members[i] =
5151
Member{paddingArray, c.members[i].name, c.members[i].bitOffset};
5252
}

oi/type_graph/TypeGraph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
namespace type_graph {
1919

2020
template <>
21-
Primitive* TypeGraph::make_type<Primitive>(Primitive::Kind kind) {
21+
Primitive* TypeGraph::makeType<Primitive>(Primitive::Kind kind) {
2222
switch (kind) {
2323
case Primitive::Kind::Int8:
2424
static Primitive pInt8{kind};

oi/type_graph/TypeGraph.h

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323

2424
namespace type_graph {
2525

26+
/*
27+
* TypeGraph
28+
*
29+
* Holds the nodes and metadata which form a type graph.
30+
*/
2631
class TypeGraph {
2732
public:
2833
size_t size() const noexcept {
@@ -42,24 +47,33 @@ class TypeGraph {
4247
rootTypes_.push_back(type);
4348
}
4449

45-
// Override of the generic make_type function that returns singleton Primitive
50+
// Override of the generic makeType function that returns singleton Primitive
4651
// objects
4752
template <typename T>
48-
Primitive* make_type(Primitive::Kind kind);
53+
Primitive* makeType(Primitive::Kind kind);
4954

5055
template <typename T, typename... Args>
51-
T* make_type(Args&&... args) {
56+
T* makeType(Args&&... args) {
5257
static_assert(!std::is_same<T, Primitive>::value,
5358
"Primitive singleton override should be used");
54-
55-
auto type_unique_ptr = std::make_unique<T>(std::forward<Args>(args)...);
56-
auto type_raw_ptr = type_unique_ptr.get();
57-
types_.push_back(std::move(type_unique_ptr));
58-
return type_raw_ptr;
59-
}
60-
61-
void add(std::unique_ptr<Type> type) {
62-
types_.push_back(std::move(type));
59+
if constexpr (std::is_same<T, Class>::value ||
60+
std::is_same<T, Container>::value ||
61+
std::is_same<T, Array>::value ||
62+
std::is_same<T, Typedef>::value ||
63+
std::is_same<T, Pointer>::value) {
64+
// Node ID required
65+
auto type_unique_ptr =
66+
std::make_unique<T>(next_id_++, std::forward<Args>(args)...);
67+
auto type_raw_ptr = type_unique_ptr.get();
68+
types_.push_back(std::move(type_unique_ptr));
69+
return type_raw_ptr;
70+
} else {
71+
// No Node ID
72+
auto type_unique_ptr = std::make_unique<T>(std::forward<Args>(args)...);
73+
auto type_raw_ptr = type_unique_ptr.get();
74+
types_.push_back(std::move(type_unique_ptr));
75+
return type_raw_ptr;
76+
}
6377
}
6478

6579
// TODO dodgy (use a getter instead to allow returning a const vector):
@@ -69,6 +83,7 @@ class TypeGraph {
6983
std::vector<std::reference_wrapper<Type>> rootTypes_;
7084
// Store all type objects in vectors for ownership. Order is not significant.
7185
std::vector<std::unique_ptr<Type>> types_;
86+
NodeId next_id_ = 0;
7287
};
7388

7489
} // namespace type_graph

oi/type_graph/TypeIdentifier.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ void TypeIdentifier::visit(Container& c) {
7474
if (std::regex_search(paramClass->fqName(), info.matcher)) {
7575
// Create dummy containers
7676
auto* dummy =
77-
typeGraph_.make_type<Container>(info, param.type->size());
77+
typeGraph_.makeType<Container>(info, param.type->size());
7878
dummy->templateParams = paramClass->templateParams;
7979
c.templateParams[i] = dummy;
8080
replaced = true;
@@ -99,11 +99,11 @@ void TypeIdentifier::visit(Container& c) {
9999
auto* allocator =
100100
dynamic_cast<Class*>(param.type); // TODO please don't do this...
101101
Type& typeToAllocate = *allocator->templateParams.at(0).type;
102-
auto* dummy = typeGraph_.make_type<DummyAllocator>(typeToAllocate, size,
103-
param.type->align());
102+
auto* dummy = typeGraph_.makeType<DummyAllocator>(typeToAllocate, size,
103+
param.type->align());
104104
c.templateParams[i] = dummy;
105105
} else {
106-
auto* dummy = typeGraph_.make_type<Dummy>(size, param.type->align());
106+
auto* dummy = typeGraph_.makeType<Dummy>(size, param.type->align());
107107
c.templateParams[i] = dummy;
108108
}
109109
}

0 commit comments

Comments
 (0)