mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 13:14:55 +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())
|
||||
return it->second;
|
||||
|
||||
if (!drgn_utils::isSizeComplete(type) &&
|
||||
drgn_type_kind(type) != DRGN_TYPE_VOID) {
|
||||
return makeType<Primitive>(nullptr, Primitive::Kind::Incomplete);
|
||||
}
|
||||
bool isTypeIncomplete = !drgn_utils::isSizeComplete(type) &&
|
||||
drgn_type_kind(type) != DRGN_TYPE_VOID;
|
||||
|
||||
enum drgn_type_kind kind = drgn_type_kind(type);
|
||||
Type* t = nullptr;
|
||||
depth_++;
|
||||
switch (kind) {
|
||||
case DRGN_TYPE_CLASS:
|
||||
case DRGN_TYPE_STRUCT:
|
||||
case DRGN_TYPE_UNION:
|
||||
t = &enumerateClass(type);
|
||||
break;
|
||||
case DRGN_TYPE_ENUM:
|
||||
t = &enumerateEnum(type);
|
||||
break;
|
||||
case DRGN_TYPE_TYPEDEF:
|
||||
t = &enumerateTypedef(type);
|
||||
break;
|
||||
case DRGN_TYPE_POINTER:
|
||||
t = &enumeratePointer(type);
|
||||
break;
|
||||
case DRGN_TYPE_ARRAY:
|
||||
t = &enumerateArray(type);
|
||||
break;
|
||||
case DRGN_TYPE_INT:
|
||||
case DRGN_TYPE_BOOL:
|
||||
case DRGN_TYPE_FLOAT:
|
||||
case DRGN_TYPE_VOID:
|
||||
t = &enumeratePrimitive(type);
|
||||
break;
|
||||
default:
|
||||
throw DrgnParserError{"Unknown drgn type kind: " + std::to_string(kind)};
|
||||
try {
|
||||
switch (kind) {
|
||||
case DRGN_TYPE_CLASS:
|
||||
case DRGN_TYPE_STRUCT:
|
||||
case DRGN_TYPE_UNION:
|
||||
t = &enumerateClass(type);
|
||||
break;
|
||||
case DRGN_TYPE_ENUM:
|
||||
t = &enumerateEnum(type);
|
||||
break;
|
||||
case DRGN_TYPE_TYPEDEF:
|
||||
t = &enumerateTypedef(type);
|
||||
break;
|
||||
case DRGN_TYPE_POINTER:
|
||||
t = &enumeratePointer(type);
|
||||
break;
|
||||
case DRGN_TYPE_ARRAY:
|
||||
t = &enumerateArray(type);
|
||||
break;
|
||||
case DRGN_TYPE_INT:
|
||||
case DRGN_TYPE_BOOL:
|
||||
case DRGN_TYPE_FLOAT:
|
||||
case DRGN_TYPE_VOID:
|
||||
t = &enumeratePrimitive(type);
|
||||
break;
|
||||
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_--;
|
||||
|
||||
if (isTypeIncomplete) {
|
||||
return makeType<Incomplete>(nullptr, *t);
|
||||
}
|
||||
|
||||
return *t;
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,12 @@ void EnforceCompatibility::visit(Class& c) {
|
||||
return true;
|
||||
|
||||
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 (primitive->kind() == Primitive::Kind::Incomplete) {
|
||||
// This is a pointer to an incomplete type. CodeGen v1 does not record
|
||||
|
@ -36,6 +36,12 @@ void Printer::print(const Type& type) {
|
||||
depth_--;
|
||||
}
|
||||
|
||||
void Printer::visit(const Incomplete& i) {
|
||||
prefix();
|
||||
out_ << "Incomplete:" << std::endl;
|
||||
print(i.underlyingType());
|
||||
}
|
||||
|
||||
void Printer::visit(const Class& c) {
|
||||
if (prefix(c))
|
||||
return;
|
||||
|
@ -32,6 +32,7 @@ class Printer : public ConstVisitor {
|
||||
|
||||
void print(const Type& type);
|
||||
|
||||
void visit(const Incomplete& i) override;
|
||||
void visit(const Class& c) override;
|
||||
void visit(const Container& c) override;
|
||||
void visit(const Primitive& p) override;
|
||||
|
@ -29,6 +29,8 @@ namespace oi::detail::type_graph {
|
||||
OI_TYPE_LIST
|
||||
#undef X
|
||||
|
||||
const std::string Incomplete::kName = "void";
|
||||
|
||||
std::string Primitive::getName(Kind kind) {
|
||||
switch (kind) {
|
||||
case Kind::Int8:
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "oi/EnumBitset.h"
|
||||
|
||||
#define OI_TYPE_LIST \
|
||||
X(Incomplete) \
|
||||
X(Class) \
|
||||
X(Container) \
|
||||
X(Primitive) \
|
||||
@ -184,6 +185,49 @@ struct TemplateParam {
|
||||
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
|
||||
*
|
||||
|
@ -71,6 +71,8 @@ class RecursiveVisitor : public Visitor {
|
||||
if (type)
|
||||
accept(*type);
|
||||
}
|
||||
virtual void visit(Incomplete&) {
|
||||
}
|
||||
virtual void visit(Class& c) {
|
||||
for (const auto& param : c.templateParams) {
|
||||
accept(param.type());
|
||||
|
@ -211,6 +211,9 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
|
||||
std::to_string(refId)};
|
||||
|
||||
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" ||
|
||||
nodeTypeName == "Union") {
|
||||
// Format: "Class: MyClass (size: 12)"
|
||||
|
@ -367,7 +367,8 @@ TEST_F(DrgnParserTest, PointerNoFollow) {
|
||||
TEST_F(DrgnParserTest, PointerIncomplete) {
|
||||
test("oid_test_case_pointers_incomplete_raw", R"(
|
||||
[0] Pointer
|
||||
Primitive: void (incomplete)
|
||||
Incomplete:
|
||||
Primitive: void (incomplete)
|
||||
)");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user