TypeGraph: Convert unit tests relying on Printer to use TypeGraphParser

This commit is contained in:
Alastair Robertson 2023-08-01 11:06:02 -07:00 committed by Alastair Robertson
parent e5a83a3a37
commit 97ba03620a
7 changed files with 99 additions and 271 deletions

View File

@ -283,6 +283,15 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
auto& pointeeType = parseType(input, indent + 2);
type = &typeGraph_.makeType<Pointer>(id, pointeeType);
nodesById_.insert({id, *type});
} else if (nodeTypeName == "Dummy") {
// Format: "Dummy (size: 4)"
auto size = parseNumericAttribute(line, nodeTypeName, "size: ");
type = &typeGraph_.makeType<Dummy>(size, 0);
} else if (nodeTypeName == "DummyAllocator") {
// Format: "DummyAllocator (size: 8)"
auto size = parseNumericAttribute(line, nodeTypeName, "size: ");
auto& typeToAlloc = parseType(input, indent + 2);
type = &typeGraph_.makeType<DummyAllocator>(typeToAlloc, size, 0);
} else {
throw TypeGraphParserError{"Unsupported node type: " +
std::string{nodeTypeName}};

View File

@ -7,13 +7,14 @@
using namespace type_graph;
TEST(AddPaddingTest, BetweenMembers) {
auto myclass = Class{0, Class::Kind::Class, "MyClass", 16};
auto myint8 = Primitive{Primitive::Kind::Int8};
auto myint64 = Primitive{Primitive::Kind::Int64};
myclass.members.push_back(Member{myint8, "n1", 0});
myclass.members.push_back(Member{myint64, "n2", 8 * 8});
test(AddPadding::createPass(), {myclass}, R"(
test(AddPadding::createPass(), R"(
[0] Class: MyClass (size: 16)
Member: n1 (offset: 0)
Primitive: int8_t
Member: n2 (offset: 8)
Primitive: int64_t
)",
R"(
[0] Class: MyClass (size: 16)
Member: n1 (offset: 0)
Primitive: int8_t
@ -42,13 +43,14 @@ TEST(AddPaddingTest, AtBeginning) {
}
TEST(AddPaddingTest, AtEnd) {
auto myclass = Class{0, Class::Kind::Struct, "MyStruct", 16};
auto myint8 = Primitive{Primitive::Kind::Int8};
auto myint64 = Primitive{Primitive::Kind::Int64};
myclass.members.push_back(Member{myint64, "n1", 0});
myclass.members.push_back(Member{myint8, "n2", 8 * 8});
test(AddPadding::createPass(), {myclass}, R"(
test(AddPadding::createPass(), R"(
[0] Struct: MyStruct (size: 16)
Member: n1 (offset: 0)
Primitive: int64_t
Member: n2 (offset: 8)
Primitive: int8_t
)",
R"(
[0] Struct: MyStruct (size: 16)
Member: n1 (offset: 0)
Primitive: int64_t
@ -61,13 +63,14 @@ TEST(AddPaddingTest, AtEnd) {
}
TEST(AddPaddingTest, UnionBetweenMembers) {
auto myclass = Class{0, Class::Kind::Union, "MyUnion", 8};
auto myint8 = Primitive{Primitive::Kind::Int8};
auto myint64 = Primitive{Primitive::Kind::Int64};
myclass.members.push_back(Member{myint64, "n1", 0});
myclass.members.push_back(Member{myint8, "n2", 0});
test(AddPadding::createPass(), {myclass}, R"(
test(AddPadding::createPass(), R"(
[0] Union: MyUnion (size: 8)
Member: n1 (offset: 0)
Primitive: int64_t
Member: n2 (offset: 0)
Primitive: int8_t
)",
R"(
[0] Union: MyUnion (size: 8)
Member: n1 (offset: 0)
Primitive: int64_t
@ -97,32 +100,20 @@ TEST(AddPaddingTest, UnionAtEnd) {
}
TEST(AddPaddingTest, Bitfields) {
auto myclass = Class{0, Class::Kind::Class, "MyClass", 16};
auto myint64 = Primitive{Primitive::Kind::Int64};
auto myint16 = Primitive{Primitive::Kind::Int16};
auto myint8 = Primitive{Primitive::Kind::Int8};
Member b1{myint64, "b1", 0};
b1.bitsize = 3;
Member b2{myint8, "b2", 3};
b2.bitsize = 2;
// There may be a 0-sized bitfield between these two that does not appear
// in the DWARF. This would add padding and push b3 to the next byte.
Member b3{myint8, "b3", 8};
b3.bitsize = 1;
Member b4{myint64, "b4", 8 * 8};
b4.bitsize = 24;
Member n{myint16, "n", 12 * 8};
myclass.members.push_back(b1);
myclass.members.push_back(b2);
myclass.members.push_back(b3);
myclass.members.push_back(b4);
myclass.members.push_back(n);
test(AddPadding::createPass(), {myclass}, R"(
test(AddPadding::createPass(), R"(
[0] Class: MyClass (size: 16)
Member: b1 (offset: 0, bitsize: 3)
Primitive: int64_t
Member: b2 (offset: 0.375, bitsize: 2)
Primitive: int8_t
Member: b3 (offset: 1, bitsize: 1)
Primitive: int8_t
Member: b4 (offset: 8, bitsize: 24)
Primitive: int64_t
Member: n (offset: 12)
Primitive: int16_t
)",
R"(
[0] Class: MyClass (size: 16)
Member: b1 (offset: 0, bitsize: 3)
Primitive: int64_t

View File

@ -6,13 +6,14 @@
using namespace type_graph;
TEST(AlignmentCalcTest, PrimitiveMembers) {
auto myclass = Class{0, Class::Kind::Class, "MyClass", 16};
auto myint8 = Primitive{Primitive::Kind::Int8};
auto myint64 = Primitive{Primitive::Kind::Int64};
myclass.members.push_back(Member{myint8, "n", 0});
myclass.members.push_back(Member{myint64, "n", 8 * 8});
test(AlignmentCalc::createPass(), {myclass}, R"(
test(AlignmentCalc::createPass(), R"(
[0] Class: MyClass (size: 16)
Member: n (offset: 0)
Primitive: int8_t
Member: n (offset: 8)
Primitive: int64_t
)",
R"(
[0] Class: MyClass (size: 16, align: 8)
Member: n (offset: 0, align: 1)
Primitive: int8_t
@ -22,17 +23,18 @@ TEST(AlignmentCalcTest, PrimitiveMembers) {
}
TEST(AlignmentCalcTest, StructMembers) {
auto mystruct = Class{1, Class::Kind::Struct, "MyStruct", 8};
auto myint32 = Primitive{Primitive::Kind::Int32};
mystruct.members.push_back(Member{myint32, "n1", 0});
mystruct.members.push_back(Member{myint32, "n2", 4 * 8});
auto myclass = Class{0, Class::Kind::Class, "MyClass", 12};
auto myint8 = Primitive{Primitive::Kind::Int8};
myclass.members.push_back(Member{myint8, "n", 0});
myclass.members.push_back(Member{mystruct, "s", 4 * 8});
test(AlignmentCalc::createPass(), {myclass}, R"(
test(AlignmentCalc::createPass(), R"(
[0] Class: MyClass (size: 12)
Member: n (offset: 0)
Primitive: int8_t
Member: s (offset: 4)
[1] Struct: MyStruct (size: 8)
Member: n1 (offset: 0)
Primitive: int32_t
Member: n2 (offset: 4)
Primitive: int32_t
)",
R"(
[0] Class: MyClass (size: 12, align: 4)
Member: n (offset: 0, align: 1)
Primitive: int8_t
@ -46,17 +48,17 @@ TEST(AlignmentCalcTest, StructMembers) {
}
TEST(AlignmentCalcTest, StructInContainer) {
auto myclass = Class{1, Class::Kind::Class, "MyClass", 16};
auto myint8 = Primitive{Primitive::Kind::Int8};
auto myint64 = Primitive{Primitive::Kind::Int64};
myclass.members.push_back(Member{myint8, "n", 0});
myclass.members.push_back(Member{myint64, "n", 8 * 8});
auto mycontainer = Container{0, ContainerInfo{}, 8};
mycontainer.templateParams.push_back(myclass);
test(AlignmentCalc::createPass(), {mycontainer}, R"(
[0] Container: (size: 8)
test(AlignmentCalc::createPass(), R"(
[0] Container: std::vector (size: 8)
Param
[1] Class: MyClass (size: 16)
Member: n (offset: 0)
Primitive: int8_t
Member: n (offset: 8)
Primitive: int64_t
)",
R"(
[0] Container: std::vector (size: 8)
Param
[1] Class: MyClass (size: 16, align: 8)
Member: n (offset: 0, align: 1)

View File

@ -19,22 +19,6 @@ template <typename T>
using ref = std::reference_wrapper<T>;
namespace {
void testTransform(Type& type,
std::string_view expectedBefore,
std::string_view expectedAfter) {
check({type}, expectedBefore, "before transform");
type_graph::TypeGraph typeGraph;
typeGraph.addRoot(type);
OICodeGen::Config config;
MockSymbolService symbols;
CodeGen codegen{config, symbols};
codegen.transform(typeGraph);
check({type}, expectedAfter, "after transform");
}
void testTransform(OICodeGen::Config& config,
std::string_view input,
std::string_view expectedAfter) {
@ -64,18 +48,7 @@ void testTransform(std::string_view input, std::string_view expectedAfter) {
} // namespace
TEST(CodeGenTest, TransformContainerAllocator) {
auto myint = Primitive{Primitive::Kind::Int32};
auto myalloc = Class{1, Class::Kind::Struct, "MyAlloc", 8};
myalloc.templateParams.push_back(TemplateParam{myint});
myalloc.functions.push_back(Function{"allocate"});
myalloc.functions.push_back(Function{"deallocate"});
auto container = getVector();
container.templateParams.push_back(TemplateParam{myint});
container.templateParams.push_back(TemplateParam{myalloc});
testTransform(container, R"(
testTransform(R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
@ -97,35 +70,7 @@ TEST(CodeGenTest, TransformContainerAllocator) {
}
TEST(CodeGenTest, TransformContainerAllocatorParamInParent) {
ContainerInfo pairInfo{"std::pair", SEQ_TYPE, "utility"};
ContainerInfo mapInfo{"std::map", STD_MAP_TYPE, "utility"};
mapInfo.stubTemplateParams = {2, 3};
Primitive myint{Primitive::Kind::Int32};
Container pair{3, pairInfo, 8};
pair.templateParams.push_back(TemplateParam{myint, {Qualifier::Const}});
pair.templateParams.push_back(TemplateParam{myint});
Class myallocBase{2, Class::Kind::Struct,
"MyAllocBase<std::pair<const int, int>>", 1};
myallocBase.templateParams.push_back(TemplateParam{pair});
myallocBase.functions.push_back(Function{"allocate"});
myallocBase.functions.push_back(Function{"deallocate"});
Class myalloc{1, Class::Kind::Struct, "MyAlloc<std::pair<const int, int>>",
1};
myalloc.parents.push_back(Parent{myallocBase, 0});
myalloc.functions.push_back(Function{"allocate"});
myalloc.functions.push_back(Function{"deallocate"});
Container map{0, mapInfo, 24};
map.templateParams.push_back(TemplateParam{myint});
map.templateParams.push_back(TemplateParam{myint});
map.templateParams.push_back(TemplateParam{myalloc});
testTransform(map, R"(
testTransform(R"(
[0] Container: std::map (size: 24)
Param
Primitive: int32_t

View File

@ -7,18 +7,11 @@
using namespace type_graph;
TEST(RemoveMembersTest, Match) {
auto classB = Class{1, Class::Kind::Class, "ClassB", 4};
auto classA = Class{0, Class::Kind::Class, "ClassA", 12};
classA.members.push_back(Member{classB, "a", 0});
classA.members.push_back(Member{classB, "b", 4 * 8});
classA.members.push_back(Member{classB, "c", 8 * 8});
const std::vector<std::pair<std::string, std::string>>& membersToIgnore = {
{"ClassA", "b"},
};
test(RemoveMembers::createPass(membersToIgnore), {classA}, R"(
test(RemoveMembers::createPass(membersToIgnore), R"(
[0] Class: ClassA (size: 12)
Member: a (offset: 0)
[1] Class: ClassB (size: 4)
@ -37,18 +30,11 @@ TEST(RemoveMembersTest, Match) {
}
TEST(RemoveMembersTest, TypeMatchMemberMiss) {
auto classB = Class{1, Class::Kind::Class, "ClassB", 4};
auto classA = Class{0, Class::Kind::Class, "ClassA", 12};
classA.members.push_back(Member{classB, "a", 0});
classA.members.push_back(Member{classB, "b", 4 * 8});
classA.members.push_back(Member{classB, "c", 8 * 8});
const std::vector<std::pair<std::string, std::string>>& membersToIgnore = {
{"ClassA", "x"},
};
test(RemoveMembers::createPass(membersToIgnore), {classA}, R"(
testNoChange(RemoveMembers::createPass(membersToIgnore), R"(
[0] Class: ClassA (size: 12)
Member: a (offset: 0)
[1] Class: ClassB (size: 4)
@ -60,18 +46,11 @@ TEST(RemoveMembersTest, TypeMatchMemberMiss) {
}
TEST(RemoveMembersTest, MemberMatchWrongType) {
auto classB = Class{1, Class::Kind::Class, "ClassB", 4};
auto classA = Class{0, Class::Kind::Class, "ClassA", 12};
classA.members.push_back(Member{classB, "a", 0});
classA.members.push_back(Member{classB, "b", 4 * 8});
classA.members.push_back(Member{classB, "c", 8 * 8});
const std::vector<std::pair<std::string, std::string>>& membersToIgnore = {
{"ClassB", "b"},
};
test(RemoveMembers::createPass(membersToIgnore), {classA}, R"(
testNoChange(RemoveMembers::createPass(membersToIgnore), R"(
[0] Class: ClassA (size: 12)
Member: a (offset: 0)
[1] Class: ClassB (size: 4)

View File

@ -7,14 +7,13 @@
using namespace type_graph;
TEST(RemoveTopLevelPointerTest, TopLevelPointerRemoved) {
auto myint = Primitive{Primitive::Kind::Int32};
auto myclass = Class{1, Class::Kind::Class, "MyClass", 4};
myclass.members.push_back(Member{myint, "n", 0});
auto ptrA = Pointer{0, myclass};
test(RemoveTopLevelPointer::createPass(), {ptrA}, R"(
test(RemoveTopLevelPointer::createPass(), R"(
[0] Pointer
[1] Class: MyClass (size: 4)
Member: n (offset: 0)
Primitive: int32_t
)",
R"(
[0] Class: MyClass (size: 4)
Member: n (offset: 0)
Primitive: int32_t
@ -22,12 +21,7 @@ TEST(RemoveTopLevelPointerTest, TopLevelPointerRemoved) {
}
TEST(RemoveTopLevelPointerTest, TopLevelClassUntouched) {
auto myint = Primitive{Primitive::Kind::Int32};
auto myclass = Class{0, Class::Kind::Class, "MyClass", 4};
myclass.members.push_back(Member{myint, "n", 0});
test(RemoveTopLevelPointer::createPass(), {myclass}, R"(
testNoChange(RemoveTopLevelPointer::createPass(), R"(
[0] Class: MyClass (size: 4)
Member: n (offset: 0)
Primitive: int32_t
@ -35,13 +29,7 @@ TEST(RemoveTopLevelPointerTest, TopLevelClassUntouched) {
}
TEST(RemoveTopLevelPointerTest, IntermediatePointerUntouched) {
auto myint = Primitive{Primitive::Kind::Int32};
auto ptrInt = Pointer{1, myint};
auto myclass = Class{0, Class::Kind::Class, "MyClass", 4};
myclass.members.push_back(Member{ptrInt, "n", 0});
test(RemoveTopLevelPointer::createPass(), {myclass}, R"(
testNoChange(RemoveTopLevelPointer::createPass(), R"(
[0] Class: MyClass (size: 4)
Member: n (offset: 0)
[1] Pointer

View File

@ -7,17 +7,7 @@
using namespace type_graph;
TEST(TypeIdentifierTest, StubbedParam) {
auto myint = Primitive{Primitive::Kind::Int32};
auto myparam = Class{1, Class::Kind::Struct, "MyParam", 4};
myparam.members.push_back(Member{myint, "a", 0});
auto container = getVector();
container.templateParams.push_back(TemplateParam{myint});
container.templateParams.push_back(TemplateParam{myparam});
container.templateParams.push_back(TemplateParam{myint});
test(TypeIdentifier::createPass({}), {container}, R"(
test(TypeIdentifier::createPass({}), R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
@ -40,19 +30,7 @@ TEST(TypeIdentifierTest, StubbedParam) {
}
TEST(TypeIdentifierTest, Allocator) {
auto myint = Primitive{Primitive::Kind::Int32};
auto myalloc = Class{1, Class::Kind::Struct, "MyAlloc", 8};
myalloc.templateParams.push_back(TemplateParam{myint});
myalloc.functions.push_back(Function{"allocate"});
myalloc.functions.push_back(Function{"deallocate"});
auto container = getVector();
container.templateParams.push_back(TemplateParam{myint});
container.templateParams.push_back(TemplateParam{myalloc});
container.templateParams.push_back(TemplateParam{myint});
test(TypeIdentifier::createPass({}), {container}, R"(
test(TypeIdentifier::createPass({}), R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
@ -78,19 +56,7 @@ TEST(TypeIdentifierTest, Allocator) {
}
TEST(TypeIdentifierTest, AllocatorSize1) {
auto myint = Primitive{Primitive::Kind::Int32};
auto myalloc = Class{1, Class::Kind::Struct, "MyAlloc", 1};
myalloc.templateParams.push_back(TemplateParam{myint});
myalloc.functions.push_back(Function{"allocate"});
myalloc.functions.push_back(Function{"deallocate"});
auto container = getVector();
container.templateParams.push_back(TemplateParam{myint});
container.templateParams.push_back(TemplateParam{myalloc});
container.templateParams.push_back(TemplateParam{myint});
test(TypeIdentifier::createPass({}), {container}, R"(
test(TypeIdentifier::createPass({}), R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
@ -116,21 +82,10 @@ TEST(TypeIdentifierTest, AllocatorSize1) {
}
TEST(TypeIdentifierTest, PassThroughTypes) {
auto myint = Primitive{Primitive::Kind::Int32};
auto myalloc = Class{1, Class::Kind::Class, "std::allocator", 1};
myalloc.templateParams.push_back(TemplateParam{myint});
myalloc.functions.push_back(Function{"allocate"});
myalloc.functions.push_back(Function{"deallocate"});
auto container = getVector();
container.templateParams.push_back(TemplateParam{myint});
container.templateParams.push_back(TemplateParam{myalloc});
std::vector<ContainerInfo> passThroughTypes;
passThroughTypes.emplace_back("std::allocator", DUMMY_TYPE, "memory");
test(TypeIdentifier::createPass(passThroughTypes), {container}, R"(
test(TypeIdentifier::createPass(passThroughTypes), R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
@ -153,17 +108,7 @@ TEST(TypeIdentifierTest, PassThroughTypes) {
}
TEST(TypeIdentifierTest, ContainerNotReplaced) {
auto myint = Primitive{Primitive::Kind::Int32};
ContainerInfo allocatorInfo{"std::allocator", DUMMY_TYPE, "memory"};
auto myalloc = Container{1, allocatorInfo, 1};
myalloc.templateParams.push_back(TemplateParam{myint});
auto container = getVector();
container.templateParams.push_back(TemplateParam{myint});
container.templateParams.push_back(TemplateParam{myalloc});
test(TypeIdentifier::createPass({}), {container}, R"(
test(TypeIdentifier::createPass({}), R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
@ -184,22 +129,7 @@ TEST(TypeIdentifierTest, ContainerNotReplaced) {
}
TEST(TypeIdentifierTest, DummyNotReplaced) {
auto myint = Primitive{Primitive::Kind::Int32};
auto dummy = Dummy{22, 0};
auto container = getVector();
container.templateParams.push_back(TemplateParam{myint});
container.templateParams.push_back(TemplateParam{dummy});
test(TypeIdentifier::createPass({}), {container}, R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
Param
Dummy (size: 22)
)",
R"(
testNoChange(TypeIdentifier::createPass({}), R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
@ -209,23 +139,7 @@ TEST(TypeIdentifierTest, DummyNotReplaced) {
}
TEST(TypeIdentifierTest, DummyAllocatorNotReplaced) {
auto myint = Primitive{Primitive::Kind::Int32};
auto dummy = DummyAllocator{myint, 22, 0};
auto container = getVector();
container.templateParams.push_back(TemplateParam{myint});
container.templateParams.push_back(TemplateParam{dummy});
test(TypeIdentifier::createPass({}), {container}, R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t
Param
DummyAllocator (size: 22)
Primitive: int32_t
)",
R"(
testNoChange(TypeIdentifier::createPass({}), R"(
[0] Container: std::vector (size: 24)
Param
Primitive: int32_t