CycleFinder: support containers

This commit is contained in:
Jake Hillion 2023-07-14 09:59:01 -07:00
parent b8b6afda43
commit b88dabae5c
5 changed files with 48 additions and 2 deletions

View File

@ -27,7 +27,7 @@ workflows:
- build-gcc
oid_test_args: "-ftyped-data-segment"
tests_regex: "OidIntegration\\..*"
exclude_regex: ".*inheritance_polymorphic.*|.*pointers.*|.*arrays_member_int0|OidIntegration.unions.*|.*thrift_unions_dynamic_.*|.*cycles_unique_ptr|.*cycles_shared_ptr"
exclude_regex: ".*inheritance_polymorphic.*|.*pointers.*|.*arrays_member_int0|OidIntegration.unions.*|.*thrift_unions_dynamic_.*"
- test:
name: test-tree-builder-type-checking-gcc
requires:

View File

@ -38,7 +38,11 @@ void CycleFinder::accept(Type& type) {
if (auto* p = dynamic_cast<Pointer*>(&from)) {
p->setPointeeType(edge);
} else if (auto* c = dynamic_cast<Container*>(&from)) {
throw std::runtime_error("TODO: cycle is from a Container");
for (auto& param : c->templateParams) {
if (param.type() == &type) {
param.setType(&edge);
}
}
} else {
throw std::logic_error(
"all cycles are expected to come from a Pointer or Container");

View File

@ -158,6 +158,10 @@ class TemplateParam {
TemplateParam(std::string value) : value(std::move(value)) {
}
void setType(Type* type) {
type_ = type;
}
Type* type() const {
return type_;
}

View File

@ -72,6 +72,10 @@ ContainerInfo& getContainerInfo(std::string_view name) {
static ContainerInfo info{"std::allocator", DUMMY_TYPE, "memory"};
return info;
}
if (name == "std::unique_ptr") {
static ContainerInfo info{"std::unique_ptr", UNIQ_PTR_TYPE, "memory"};
return info;
}
throw TypeGraphParserError{"Unsupported container: " + std::string{name}};
}

View File

@ -59,3 +59,37 @@ TEST(CycleFinderTest, RawPointer) {
[0]
)");
}
TEST(CycleFinderTest, UniquePointer) {
// Original:
// class UniqueNode {
// int value;
// std::unique_ptr<struct UniqueNode> next;
// };
//
// After:
// class std__unique_ptr_UniqueNode_UniqueNode;
// class UniqueNode {
// int value;
// std::unique_ptr<std__unique_ptr_UniqueNode_UniqueNode> next;
// };
test(CycleFinder::createPass(), R"(
[0] Struct: UniqueNode (size: 16)
Member: value (offset: 0)
Primitive: int32_t
Member: next (offset: 8)
[1] Container: std::unique_ptr (size: 8)
Param
[0]
)",
R"(
[0] Struct: UniqueNode (size: 16)
Member: value (offset: 0)
Primitive: int32_t
Member: next (offset: 8)
[1] Container: std::unique_ptr (size: 8)
Param
[2] CycleBreaker
[0]
)");
}