mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-12 21:56:54 +00:00
Maintain type/name of Incomplete type
This commit is contained in:
parent
37991140da
commit
3065dd14e9
@ -87,43 +87,55 @@ Type& DrgnParser::enumerateType(struct drgn_type* type) {
|
|||||||
if (auto it = drgn_types_.find(type); it != drgn_types_.end())
|
if (auto it = drgn_types_.find(type); it != drgn_types_.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
|
|
||||||
if (!drgn_utils::isSizeComplete(type) &&
|
bool isTypeIncomplete = !drgn_utils::isSizeComplete(type) &&
|
||||||
drgn_type_kind(type) != DRGN_TYPE_VOID) {
|
drgn_type_kind(type) != DRGN_TYPE_VOID;
|
||||||
return makeType<Primitive>(nullptr, Primitive::Kind::Incomplete);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum drgn_type_kind kind = drgn_type_kind(type);
|
enum drgn_type_kind kind = drgn_type_kind(type);
|
||||||
Type* t = nullptr;
|
Type* t = nullptr;
|
||||||
depth_++;
|
depth_++;
|
||||||
switch (kind) {
|
try {
|
||||||
case DRGN_TYPE_CLASS:
|
switch (kind) {
|
||||||
case DRGN_TYPE_STRUCT:
|
case DRGN_TYPE_CLASS:
|
||||||
case DRGN_TYPE_UNION:
|
case DRGN_TYPE_STRUCT:
|
||||||
t = &enumerateClass(type);
|
case DRGN_TYPE_UNION:
|
||||||
break;
|
t = &enumerateClass(type);
|
||||||
case DRGN_TYPE_ENUM:
|
break;
|
||||||
t = &enumerateEnum(type);
|
case DRGN_TYPE_ENUM:
|
||||||
break;
|
t = &enumerateEnum(type);
|
||||||
case DRGN_TYPE_TYPEDEF:
|
break;
|
||||||
t = &enumerateTypedef(type);
|
case DRGN_TYPE_TYPEDEF:
|
||||||
break;
|
t = &enumerateTypedef(type);
|
||||||
case DRGN_TYPE_POINTER:
|
break;
|
||||||
t = &enumeratePointer(type);
|
case DRGN_TYPE_POINTER:
|
||||||
break;
|
t = &enumeratePointer(type);
|
||||||
case DRGN_TYPE_ARRAY:
|
break;
|
||||||
t = &enumerateArray(type);
|
case DRGN_TYPE_ARRAY:
|
||||||
break;
|
t = &enumerateArray(type);
|
||||||
case DRGN_TYPE_INT:
|
break;
|
||||||
case DRGN_TYPE_BOOL:
|
case DRGN_TYPE_INT:
|
||||||
case DRGN_TYPE_FLOAT:
|
case DRGN_TYPE_BOOL:
|
||||||
case DRGN_TYPE_VOID:
|
case DRGN_TYPE_FLOAT:
|
||||||
t = &enumeratePrimitive(type);
|
case DRGN_TYPE_VOID:
|
||||||
break;
|
t = &enumeratePrimitive(type);
|
||||||
default:
|
break;
|
||||||
throw DrgnParserError{"Unknown drgn type kind: " + std::to_string(kind)};
|
default:
|
||||||
|
throw DrgnParserError{"Unknown drgn type kind: " +
|
||||||
|
std::to_string(kind)};
|
||||||
|
}
|
||||||
|
} catch (const DrgnParserError& e) {
|
||||||
|
if (isTypeIncomplete) {
|
||||||
|
t = &makeType<Primitive>(type, Primitive::Kind::Incomplete);
|
||||||
|
} else {
|
||||||
|
depth_--;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
depth_--;
|
depth_--;
|
||||||
|
|
||||||
|
if (isTypeIncomplete) {
|
||||||
|
return makeType<Incomplete>(nullptr, *t);
|
||||||
|
}
|
||||||
|
|
||||||
return *t;
|
return *t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,12 @@ void EnforceCompatibility::visit(Class& c) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (auto* ptr = dynamic_cast<Pointer*>(&member.type())) {
|
if (auto* ptr = dynamic_cast<Pointer*>(&member.type())) {
|
||||||
|
if (auto* incomplete = dynamic_cast<Incomplete*>(&ptr->pointeeType())) {
|
||||||
|
// This is a pointer to an incomplete type. CodeGen v1 does not record
|
||||||
|
// the pointer's address in this case.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto* primitive = dynamic_cast<Primitive*>(&ptr->pointeeType())) {
|
if (auto* primitive = dynamic_cast<Primitive*>(&ptr->pointeeType())) {
|
||||||
if (primitive->kind() == Primitive::Kind::Incomplete) {
|
if (primitive->kind() == Primitive::Kind::Incomplete) {
|
||||||
// This is a pointer to an incomplete type. CodeGen v1 does not record
|
// This is a pointer to an incomplete type. CodeGen v1 does not record
|
||||||
|
@ -36,6 +36,12 @@ void Printer::print(const Type& type) {
|
|||||||
depth_--;
|
depth_--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Printer::visit(const Incomplete& i) {
|
||||||
|
prefix();
|
||||||
|
out_ << "Incomplete:" << std::endl;
|
||||||
|
print(i.underlyingType());
|
||||||
|
}
|
||||||
|
|
||||||
void Printer::visit(const Class& c) {
|
void Printer::visit(const Class& c) {
|
||||||
if (prefix(c))
|
if (prefix(c))
|
||||||
return;
|
return;
|
||||||
|
@ -32,6 +32,7 @@ class Printer : public ConstVisitor {
|
|||||||
|
|
||||||
void print(const Type& type);
|
void print(const Type& type);
|
||||||
|
|
||||||
|
void visit(const Incomplete& i) override;
|
||||||
void visit(const Class& c) override;
|
void visit(const Class& c) override;
|
||||||
void visit(const Container& c) override;
|
void visit(const Container& c) override;
|
||||||
void visit(const Primitive& p) override;
|
void visit(const Primitive& p) override;
|
||||||
|
@ -29,6 +29,8 @@ namespace oi::detail::type_graph {
|
|||||||
OI_TYPE_LIST
|
OI_TYPE_LIST
|
||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
|
const std::string Incomplete::kName = "void";
|
||||||
|
|
||||||
std::string Primitive::getName(Kind kind) {
|
std::string Primitive::getName(Kind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case Kind::Int8:
|
case Kind::Int8:
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "oi/EnumBitset.h"
|
#include "oi/EnumBitset.h"
|
||||||
|
|
||||||
#define OI_TYPE_LIST \
|
#define OI_TYPE_LIST \
|
||||||
|
X(Incomplete) \
|
||||||
X(Class) \
|
X(Class) \
|
||||||
X(Container) \
|
X(Container) \
|
||||||
X(Primitive) \
|
X(Primitive) \
|
||||||
@ -184,6 +185,49 @@ struct TemplateParam {
|
|||||||
std::optional<std::string> value;
|
std::optional<std::string> value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Incomplete
|
||||||
|
*
|
||||||
|
* A wrapper around a type we couldn't determine the size of.
|
||||||
|
*/
|
||||||
|
class Incomplete : public Type {
|
||||||
|
public:
|
||||||
|
Incomplete(Type& underlyingType) : underlyingType_(underlyingType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline constexpr bool has_node_id = false;
|
||||||
|
|
||||||
|
DECLARE_ACCEPT
|
||||||
|
|
||||||
|
const std::string& name() const override {
|
||||||
|
return kName;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view inputName() const override {
|
||||||
|
return underlyingType_.inputName();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const override {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t align() const override {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeId id() const override {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type& underlyingType() const {
|
||||||
|
return underlyingType_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type& underlyingType_;
|
||||||
|
static const std::string kName;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class
|
* Class
|
||||||
*
|
*
|
||||||
|
@ -71,6 +71,8 @@ class RecursiveVisitor : public Visitor {
|
|||||||
if (type)
|
if (type)
|
||||||
accept(*type);
|
accept(*type);
|
||||||
}
|
}
|
||||||
|
virtual void visit(Incomplete&) {
|
||||||
|
}
|
||||||
virtual void visit(Class& c) {
|
virtual void visit(Class& c) {
|
||||||
for (const auto& param : c.templateParams) {
|
for (const auto& param : c.templateParams) {
|
||||||
accept(param.type());
|
accept(param.type());
|
||||||
|
@ -211,6 +211,9 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
|
|||||||
std::to_string(refId)};
|
std::to_string(refId)};
|
||||||
|
|
||||||
type = &it->second.get();
|
type = &it->second.get();
|
||||||
|
} else if (nodeTypeName == "Incomplete") {
|
||||||
|
auto& underlyingType = parseType(input, indent + 2);
|
||||||
|
type = &typeGraph_.makeType<Incomplete>(underlyingType);
|
||||||
} else if (nodeTypeName == "Class" || nodeTypeName == "Struct" ||
|
} else if (nodeTypeName == "Class" || nodeTypeName == "Struct" ||
|
||||||
nodeTypeName == "Union") {
|
nodeTypeName == "Union") {
|
||||||
// Format: "Class: MyClass (size: 12)"
|
// Format: "Class: MyClass (size: 12)"
|
||||||
|
@ -367,7 +367,8 @@ TEST_F(DrgnParserTest, PointerNoFollow) {
|
|||||||
TEST_F(DrgnParserTest, PointerIncomplete) {
|
TEST_F(DrgnParserTest, PointerIncomplete) {
|
||||||
test("oid_test_case_pointers_incomplete_raw", R"(
|
test("oid_test_case_pointers_incomplete_raw", R"(
|
||||||
[0] Pointer
|
[0] Pointer
|
||||||
Primitive: void (incomplete)
|
Incomplete:
|
||||||
|
Primitive: void (incomplete)
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user