Skip to content

Commit 3065dd1

Browse files
ttreyerJakeHillion
authored andcommitted
Maintain type/name of Incomplete type
1 parent 3799114 commit 3065dd1

File tree

9 files changed

+108
-31
lines changed

9 files changed

+108
-31
lines changed

oi/type_graph/DrgnParser.cpp

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -87,43 +87,55 @@ Type& DrgnParser::enumerateType(struct drgn_type* type) {
8787
if (auto it = drgn_types_.find(type); it != drgn_types_.end())
8888
return it->second;
8989

90-
if (!drgn_utils::isSizeComplete(type) &&
91-
drgn_type_kind(type) != DRGN_TYPE_VOID) {
92-
return makeType<Primitive>(nullptr, Primitive::Kind::Incomplete);
93-
}
90+
bool isTypeIncomplete = !drgn_utils::isSizeComplete(type) &&
91+
drgn_type_kind(type) != DRGN_TYPE_VOID;
9492

9593
enum drgn_type_kind kind = drgn_type_kind(type);
9694
Type* t = nullptr;
9795
depth_++;
98-
switch (kind) {
99-
case DRGN_TYPE_CLASS:
100-
case DRGN_TYPE_STRUCT:
101-
case DRGN_TYPE_UNION:
102-
t = &enumerateClass(type);
103-
break;
104-
case DRGN_TYPE_ENUM:
105-
t = &enumerateEnum(type);
106-
break;
107-
case DRGN_TYPE_TYPEDEF:
108-
t = &enumerateTypedef(type);
109-
break;
110-
case DRGN_TYPE_POINTER:
111-
t = &enumeratePointer(type);
112-
break;
113-
case DRGN_TYPE_ARRAY:
114-
t = &enumerateArray(type);
115-
break;
116-
case DRGN_TYPE_INT:
117-
case DRGN_TYPE_BOOL:
118-
case DRGN_TYPE_FLOAT:
119-
case DRGN_TYPE_VOID:
120-
t = &enumeratePrimitive(type);
121-
break;
122-
default:
123-
throw DrgnParserError{"Unknown drgn type kind: " + std::to_string(kind)};
96+
try {
97+
switch (kind) {
98+
case DRGN_TYPE_CLASS:
99+
case DRGN_TYPE_STRUCT:
100+
case DRGN_TYPE_UNION:
101+
t = &enumerateClass(type);
102+
break;
103+
case DRGN_TYPE_ENUM:
104+
t = &enumerateEnum(type);
105+
break;
106+
case DRGN_TYPE_TYPEDEF:
107+
t = &enumerateTypedef(type);
108+
break;
109+
case DRGN_TYPE_POINTER:
110+
t = &enumeratePointer(type);
111+
break;
112+
case DRGN_TYPE_ARRAY:
113+
t = &enumerateArray(type);
114+
break;
115+
case DRGN_TYPE_INT:
116+
case DRGN_TYPE_BOOL:
117+
case DRGN_TYPE_FLOAT:
118+
case DRGN_TYPE_VOID:
119+
t = &enumeratePrimitive(type);
120+
break;
121+
default:
122+
throw DrgnParserError{"Unknown drgn type kind: " +
123+
std::to_string(kind)};
124+
}
125+
} catch (const DrgnParserError& e) {
126+
if (isTypeIncomplete) {
127+
t = &makeType<Primitive>(type, Primitive::Kind::Incomplete);
128+
} else {
129+
depth_--;
130+
throw e;
131+
}
124132
}
125133
depth_--;
126134

135+
if (isTypeIncomplete) {
136+
return makeType<Incomplete>(nullptr, *t);
137+
}
138+
127139
return *t;
128140
}
129141

oi/type_graph/EnforceCompatibility.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ void EnforceCompatibility::visit(Class& c) {
7878
return true;
7979

8080
if (auto* ptr = dynamic_cast<Pointer*>(&member.type())) {
81+
if (auto* incomplete = dynamic_cast<Incomplete*>(&ptr->pointeeType())) {
82+
// This is a pointer to an incomplete type. CodeGen v1 does not record
83+
// the pointer's address in this case.
84+
return true;
85+
}
86+
8187
if (auto* primitive = dynamic_cast<Primitive*>(&ptr->pointeeType())) {
8288
if (primitive->kind() == Primitive::Kind::Incomplete) {
8389
// This is a pointer to an incomplete type. CodeGen v1 does not record

oi/type_graph/Printer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ void Printer::print(const Type& type) {
3636
depth_--;
3737
}
3838

39+
void Printer::visit(const Incomplete& i) {
40+
prefix();
41+
out_ << "Incomplete:" << std::endl;
42+
print(i.underlyingType());
43+
}
44+
3945
void Printer::visit(const Class& c) {
4046
if (prefix(c))
4147
return;

oi/type_graph/Printer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class Printer : public ConstVisitor {
3232

3333
void print(const Type& type);
3434

35+
void visit(const Incomplete& i) override;
3536
void visit(const Class& c) override;
3637
void visit(const Container& c) override;
3738
void visit(const Primitive& p) override;

oi/type_graph/Types.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ namespace oi::detail::type_graph {
2929
OI_TYPE_LIST
3030
#undef X
3131

32+
const std::string Incomplete::kName = "void";
33+
3234
std::string Primitive::getName(Kind kind) {
3335
switch (kind) {
3436
case Kind::Int8:

oi/type_graph/Types.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "oi/EnumBitset.h"
4141

4242
#define OI_TYPE_LIST \
43+
X(Incomplete) \
4344
X(Class) \
4445
X(Container) \
4546
X(Primitive) \
@@ -184,6 +185,49 @@ struct TemplateParam {
184185
std::optional<std::string> value;
185186
};
186187

188+
/*
189+
* Incomplete
190+
*
191+
* A wrapper around a type we couldn't determine the size of.
192+
*/
193+
class Incomplete : public Type {
194+
public:
195+
Incomplete(Type& underlyingType) : underlyingType_(underlyingType) {
196+
}
197+
198+
static inline constexpr bool has_node_id = false;
199+
200+
DECLARE_ACCEPT
201+
202+
const std::string& name() const override {
203+
return kName;
204+
}
205+
206+
std::string_view inputName() const override {
207+
return underlyingType_.inputName();
208+
}
209+
210+
size_t size() const override {
211+
return 0;
212+
}
213+
214+
uint64_t align() const override {
215+
return 0;
216+
}
217+
218+
NodeId id() const override {
219+
return -1;
220+
}
221+
222+
Type& underlyingType() const {
223+
return underlyingType_;
224+
}
225+
226+
private:
227+
Type& underlyingType_;
228+
static const std::string kName;
229+
};
230+
187231
/*
188232
* Class
189233
*

oi/type_graph/Visitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class RecursiveVisitor : public Visitor {
7171
if (type)
7272
accept(*type);
7373
}
74+
virtual void visit(Incomplete&) {
75+
}
7476
virtual void visit(Class& c) {
7577
for (const auto& param : c.templateParams) {
7678
accept(param.type());

test/TypeGraphParser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
211211
std::to_string(refId)};
212212

213213
type = &it->second.get();
214+
} else if (nodeTypeName == "Incomplete") {
215+
auto& underlyingType = parseType(input, indent + 2);
216+
type = &typeGraph_.makeType<Incomplete>(underlyingType);
214217
} else if (nodeTypeName == "Class" || nodeTypeName == "Struct" ||
215218
nodeTypeName == "Union") {
216219
// Format: "Class: MyClass (size: 12)"

test/test_drgn_parser.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,8 @@ TEST_F(DrgnParserTest, PointerNoFollow) {
367367
TEST_F(DrgnParserTest, PointerIncomplete) {
368368
test("oid_test_case_pointers_incomplete_raw", R"(
369369
[0] Pointer
370-
Primitive: void (incomplete)
370+
Incomplete:
371+
Primitive: void (incomplete)
371372
)");
372373
}
373374

0 commit comments

Comments
 (0)