Remove Primitive::Kind::Incomplete

This commit is contained in:
Thierry Treyer 2023-09-29 15:09:15 -07:00 committed by Jake Hillion
parent 3065dd14e9
commit f4a1bd3d99
11 changed files with 51 additions and 38 deletions

View File

@ -123,10 +123,17 @@ Type& DrgnParser::enumerateType(struct drgn_type* type) {
std::to_string(kind)};
}
} catch (const DrgnParserError& e) {
depth_--;
if (isTypeIncomplete) {
t = &makeType<Primitive>(type, Primitive::Kind::Incomplete);
const char* typeName = "<incomplete>";
if (drgn_type_has_name(type)) {
typeName = drgn_type_name(type);
} else if (drgn_type_has_tag(type)) {
typeName = drgn_type_tag(type);
}
return makeType<Incomplete>(nullptr, typeName);
} else {
depth_--;
throw e;
}
}

View File

@ -83,14 +83,6 @@ void EnforceCompatibility::visit(Class& c) {
// 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
// the pointer's address in this case.
return true;
}
}
}
return false;

View File

@ -56,9 +56,7 @@ void flattenParent(const Parent& parent,
// Create a new member to represent this parent container
flattenedMembers.emplace_back(*parentContainer, Flattener::ParentPrefix,
parent.bitOffset);
} else if (auto* parentPrimitive = dynamic_cast<Primitive*>(&parentType);
parentPrimitive &&
parentPrimitive->kind() == Primitive::Kind::Incomplete) {
} else if (auto* parentPrimitive = dynamic_cast<Incomplete*>(&parentType)) {
// Bad DWARF can lead to us seeing incomplete parent types. Just ignore
// these as there is nothing we can do to recover the missing info.
} else {

View File

@ -38,8 +38,13 @@ void Printer::print(const Type& type) {
void Printer::visit(const Incomplete& i) {
prefix();
out_ << "Incomplete:" << std::endl;
print(i.underlyingType());
out_ << "Incomplete";
if (auto underlyingType = i.underlyingType()) {
out_ << std::endl;
print(underlyingType.value().get());
} else {
out_ << ": [" << i.inputName() << "]" << std::endl;
}
}
void Printer::visit(const Class& c) {
@ -97,10 +102,7 @@ void Printer::visit(const Container& c) {
void Printer::visit(const Primitive& p) {
prefix();
out_ << "Primitive: " << p.name();
if (p.kind() == Primitive::Kind::Incomplete)
out_ << " (incomplete)";
out_ << std::endl;
out_ << "Primitive: " << p.name() << std::endl;
}
void Printer::visit(const Enum& e) {

View File

@ -65,9 +65,6 @@ Primitive& TypeGraph::makeType<Primitive>(Primitive::Kind kind) {
case Primitive::Kind::Void:
static Primitive pVoid{kind};
return pVoid;
case Primitive::Kind::Incomplete:
static Primitive pIncomplete{kind};
return pIncomplete;
}
}

View File

@ -62,7 +62,6 @@ std::string Primitive::getName(Kind kind) {
case Kind::StubbedPointer:
return "StubbedPointer";
case Kind::Void:
case Kind::Incomplete:
return "void";
}
}
@ -105,7 +104,6 @@ std::size_t Primitive::size() const {
case Kind::StubbedPointer:
return sizeof(uintptr_t);
case Kind::Void:
case Kind::Incomplete:
return 0;
}
}

View File

@ -34,6 +34,7 @@
#include <optional>
#include <string>
#include <string_view>
#include <variant>
#include <vector>
#include "oi/ContainerInfo.h"
@ -195,6 +196,10 @@ class Incomplete : public Type {
Incomplete(Type& underlyingType) : underlyingType_(underlyingType) {
}
Incomplete(std::string underlyingTypeName)
: underlyingType_(std::move(underlyingTypeName)) {
}
static inline constexpr bool has_node_id = false;
DECLARE_ACCEPT
@ -204,7 +209,13 @@ class Incomplete : public Type {
}
std::string_view inputName() const override {
return underlyingType_.inputName();
if (std::holds_alternative<std::string>(underlyingType_)) {
return std::get<std::string>(underlyingType_);
}
return std::get<std::reference_wrapper<Type>>(underlyingType_)
.get()
.inputName();
}
size_t size() const override {
@ -219,12 +230,16 @@ class Incomplete : public Type {
return -1;
}
Type& underlyingType() const {
return underlyingType_;
std::optional<std::reference_wrapper<Type>> underlyingType() const {
if (std::holds_alternative<std::string>(underlyingType_)) {
return std::nullopt;
}
return std::get<std::reference_wrapper<Type>>(underlyingType_);
}
private:
Type& underlyingType_;
std::variant<std::string, std::reference_wrapper<Type>> underlyingType_;
static const std::string kName;
};
@ -551,8 +566,6 @@ class Primitive : public Type {
StubbedPointer,
Void,
Incomplete, // Behaves the same as Void, but alerts us that the type was
// stubbed out due to incomplete DWARF
};
explicit Primitive(Kind kind) : kind_(kind), name_(getName(kind)) {

View File

@ -49,8 +49,6 @@ Primitive::Kind getKind(std::string_view kindStr) {
return Primitive::Kind::StubbedPointer;
if (kindStr == "void")
return Primitive::Kind::Void;
if (kindStr == "void (incomplete)")
return Primitive::Kind::Incomplete;
throw TypeGraphParserError{"Invalid Primitive::Kind: " +
std::string{kindStr}};
}
@ -212,8 +210,16 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
type = &it->second.get();
} else if (nodeTypeName == "Incomplete") {
auto& underlyingType = parseType(input, indent + 2);
type = &typeGraph_.makeType<Incomplete>(underlyingType);
if (line[nodeEndPos] == ':') {
auto nameStartPos = line.find('[', nodeEndPos) + 1;
auto nameEndPos = line.find(']', nameStartPos);
auto underlyingTypeName =
line.substr(nameStartPos, nameEndPos - nameStartPos);
type = &typeGraph_.makeType<Incomplete>(std::string(underlyingTypeName));
} else {
auto& underlyingType = parseType(input, indent + 2);
type = &typeGraph_.makeType<Incomplete>(underlyingType);
}
} else if (nodeTypeName == "Class" || nodeTypeName == "Struct" ||
nodeTypeName == "Union") {
// Format: "Class: MyClass (size: 12)"

View File

@ -367,8 +367,7 @@ TEST_F(DrgnParserTest, PointerNoFollow) {
TEST_F(DrgnParserTest, PointerIncomplete) {
test("oid_test_case_pointers_incomplete_raw", R"(
[0] Pointer
Incomplete:
Primitive: void (incomplete)
Incomplete: [IncompleteType]
)");
}

View File

@ -36,7 +36,8 @@ TEST(EnforceCompatibilityTest, VoidPointer) {
[0] Class: MyClass (size: 8)
Member: p (offset: 0)
[1] Pointer
Primitive: void (incomplete)
Incomplete
Primitive: void
)",
R"(
[0] Class: MyClass (size: 8)

View File

@ -958,7 +958,7 @@ TEST(FlattenerTest, IncompleteParent) {
test(Flattener::createPass(), R"(
[0] Class: MyClass (size: 4)
Parent (offset: 0)
Primitive: void (incomplete)
Incomplete: [IncompleteParent]
)",
R"(
[0] Class: MyClass (size: 4)