object-introspection/test/integration/anonymous.toml
Jake Hillion 31ba8659f0 tbv2: fix pointer codegen
A previous change enabled running OIL tests with specific features enabled.
This highlighted that pointer code generation under TreeBuilder-v2 was very
broken. This change updates pointer code generation to work and enables the
skipped tests. All enabled tests need `expected_json_v2` added to them due to
formatting differences.

Reformatted and rewrote the basic type handler that handles primitives and
pointers. Removed the reliance on `features` to decide whether to generate for
TreeBuilder-v2 as the intermediate features have been removed. Pointers are
treated as containers with a capacity of 1 and a length of 0 if null/a cycle
and 1 if followed. This holds for void pointers where, although they aren't
followed, the length is still set.

There were a couple of other changes needed to enable these tests on TBv2 that
aren't worth their own issues and PRs, I sneaked them in here.

Extra changes:
- Added `Pointer` and `Reference` to TopoSorter so they generate
  `NameProvider` instances. It might be worth visiting the graph differently
  for `NameProvider` as it requires so many instances that others generators do
  not. Will consider that in the future.
- Follow typedefs when calculating exclusive size for a type.

Closes #458.

Test plan:
- CI
- Enabled previously disabled tests.
2024-01-18 16:22:18 +00:00

444 lines
13 KiB
TOML

definitions = '''
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnested-anon-types"
struct Node {
int a, b, c;
};
struct DynNode {
std::vector<Node> nodes;
};
typedef struct {
struct Node *node;
} AnonStruct;
struct AnonStructContainer {
struct { struct Node *node; } anon;
};
struct AnonStructPtrContainer {
struct { struct Node *node; } *anon;
};
struct AnonTypedefContainer {
AnonStruct anon;
};
struct AnonUnionContainer {
union {char c; short int d;};
union {int a; double b;};
int e;
};
struct NestedAnonContainer {
struct {
union {
char c;
struct {
int x;
double y;
} d;
};
struct {
int a, b, c;
union {
union { char x; int y; };
long z;
};
AnonStruct as;
} v;
} m;
union {
union { int x1; char y1; };
union { double z1; long w1; };
struct {
long a, b, c;
} s1;
};
union {
union { int x2; char y2; };
union { double z2; long w2; };
struct {
char a, b, c;
} s2;
};
};
/* This test is disable due to GCC not supporting it
struct AnonArrayContainer {
struct {
float *x;
DynNode ns[4];
};
};
*/
#pragma clang diagnostic pop
'''
[cases]
[cases.regular_struct]
param_types = ["const Node&"]
setup = "return Node{1, 2, 3};"
features = ["chase-raw-pointers"]
expect_json = '''[{
"staticSize":12,
"dynamicSize":0,
"exclusiveSize":0,
"size": 12,
"members":[
{"name":"a", "staticSize":4, "dynamicSize":0, "exclusiveSize":4, "size":4},
{"name":"b", "staticSize":4, "dynamicSize":0, "exclusiveSize":4, "size":4},
{"name":"c", "staticSize":4, "dynamicSize":0, "exclusiveSize":4, "size":4}
]}]'''
[cases.anon_struct]
param_types = ["const AnonStructContainer&"]
setup = '''
return AnonStructContainer{
.anon = {
.node = new Node{1, 2, 3}
}
};
'''
features = ["chase-raw-pointers"]
expect_json = '''[{
"staticSize": 8,
"dynamicSize": 12,
"members": [{
"name": "anon",
"typeName": "__oi_anon_1",
"staticSize": 8,
"dynamicSize": 12,
"members": [{
"name": "node",
"typeName": "ns_anonymous::Node*",
"staticSize": 8,
"dynamicSize": 12,
"members": [{
"typeName": "ns_anonymous::Node",
"staticSize": 12,
"dynamicSize": 0,
"members": [
{ "name": "a", "staticSize": 4, "dynamicSize": 0 },
{ "name": "b", "staticSize": 4, "dynamicSize": 0 },
{ "name": "c", "staticSize": 4, "dynamicSize": 0 }
]
}]
}]
}]
}]'''
expect_json_v2 = '''[{
"name":"a0",
"typeNames":["ns_anonymous::AnonStructContainer"],
"staticSize":8,
"exclusiveSize":0,
"size":20,
"members":[{
"name":"anon",
"typeNames":["__oi_anon_1"],
"staticSize":8,
"exclusiveSize":0,
"size":20,
"members":[{
"name":"node",
"typeNames":["ns_anonymous::Node*"],
"staticSize":8,
"exclusiveSize":8,
"size":20,
"length":1,
"capacity":1,
"members":[{
"name":"*",
"typeNames":["ns_anonymous::Node"],
"staticSize":12,
"exclusiveSize":0,
"size":12,
"members":[
{ "name": "a", "staticSize": 4, "exclusiveSize": 4, "size": 4 },
{ "name": "b", "staticSize": 4, "exclusiveSize": 4, "size": 4 },
{ "name": "c", "staticSize": 4, "exclusiveSize": 4, "size": 4 }
]
}]
}]}
]}]'''
[cases.anon_struct_ptr]
skip = "We don't support pointer to anon-structs yet" # https://github.com/facebookexperimental/object-introspection/issues/20
param_types = ["const AnonStructPtrContainer&"]
setup = '''
return AnonStructPtrContainer{
.anon = (decltype(AnonStructPtrContainer::anon))new (Node*){
new Node{1, 2, 3}
}
};'''
features = ["chase-raw-pointers"]
[cases.anon_typedef]
param_types = ["const AnonTypedefContainer&"]
setup = '''
return AnonTypedefContainer{
.anon = {
.node = new Node{1, 2, 3}
}
};'''
features = ["chase-raw-pointers"]
expect_json = '''[{
"staticSize": 8,
"dynamicSize": 12,
"members": [{
"name": "anon",
"typeName": "AnonStruct",
"isTypedef": true,
"staticSize": 8,
"dynamicSize": 12,
"exclusiveSize": 0,
"members": [{
"name": "",
"typeName": "__oi_anon_2",
"isTypedef": false,
"staticSize": 8,
"dynamicSize": 12,
"exclusiveSize": 0,
"members": [{
"name": "node",
"typeName": "ns_anonymous::Node*",
"staticSize": 8,
"dynamicSize": 12,
"exclusiveSize": 8,
"members": [{
"typeName": "ns_anonymous::Node",
"staticSize": 12,
"exclusiveSize": 0,
"members": [
{ "name": "a", "staticSize": 4, "exclusiveSize": 4, "dynamicSize": 0 },
{ "name": "b", "staticSize": 4, "exclusiveSize": 4, "dynamicSize": 0 },
{ "name": "c", "staticSize": 4, "exclusiveSize": 4, "dynamicSize": 0 }
]
}]
}]
}]
}]
}]'''
expect_json_v2 = '''[{
"staticSize": 8,
"exclusiveSize": 0,
"size": 20,
"members": [{
"typeNames":["AnonStruct", "__oi_anon_2"],
"staticSize": 8,
"exclusiveSize": 0,
"size": 20,
"members": [{
"typeNames": ["ns_anonymous::Node*"],
"staticSize": 8,
"exclusiveSize": 8,
"size": 20,
"members": [{
"typeNames": ["ns_anonymous::Node"],
"staticSize": 12,
"exclusiveSize": 0,
"size": 12,
"members": [
{ "name": "a", "staticSize": 4, "exclusiveSize": 4, "size": 4 },
{ "name": "b", "staticSize": 4, "exclusiveSize": 4, "size": 4 },
{ "name": "c", "staticSize": 4, "exclusiveSize": 4, "size": 4 }
]
}]
}]
}]
}]'''
[cases.anon_union]
param_types = ["const AnonUnionContainer&"]
setup = 'return AnonUnionContainer{ .a = 3 };'
expect_json = '''[{
"staticSize": 24,
"dynamicSize": 0,
"members": [
{"name":"__oi_anon_0", "staticSize":2, "dynamicSize":0},
{"name":"__oi_anon_2", "staticSize":8, "dynamicSize":0},
{"name":"e", "staticSize":4, "dynamicSize":0}
]
}]'''
expect_json_v2 = '''[{
"staticSize": 24,
"exclusiveSize": 10,
"size": 24,
"members": [
{"name":"__oi_anon_0", "staticSize":2, "exclusiveSize":2, "size":2},
{"name":"__oi_anon_2", "staticSize":8, "exclusiveSize":8, "size":8},
{"name":"e", "staticSize":4, "exclusiveSize":4, "size":4, "typeNames":["int32_t"]}
]
}]'''
[cases.nested_anon_struct]
param_types = ["const NestedAnonContainer&"]
features = ["chase-raw-pointers"]
setup = 'return NestedAnonContainer{.m = { .v = {.as = {new Node{1, 2, 3}}}}};'
expect_json = '''[{
"staticSize": 80,
"dynamicSize": 12,
"members": [{
"name": "m",
"staticSize": 48,
"dynamicSize": 12,
"members": [
{ "staticSize": 16, "dynamicSize": 0 },
{ "name": "v",
"staticSize": 32,
"dynamicSize": 12,
"members": [
{ "name": "a", "staticSize": 4, "dynamicSize": 0 },
{ "name": "b", "staticSize": 4, "dynamicSize": 0 },
{ "name": "c", "staticSize": 4, "dynamicSize": 0 },
{ "staticSize": 8, "dynamicSize": 0 },
{ "name": "as",
"typeName": "AnonStruct",
"isTypedef": true,
"staticSize": 8,
"dynamicSize": 12,
"members": [{
"isTypedef": false,
"staticSize": 8,
"dynamicSize": 12,
"members": [{
"name": "node",
"staticSize": 8,
"dynamicSize": 12,
"members": [{
"staticSize": 12,
"dynamicSize": 0,
"members": [
{ "name": "a", "staticSize": 4, "dynamicSize": 0 },
{ "name": "b", "staticSize": 4, "dynamicSize": 0 },
{ "name": "c", "staticSize": 4, "dynamicSize": 0 }
]
}]
}]
}]
}]
}]
}, {
"staticSize": 24,
"dynamicSize": 0
}, {
"staticSize": 8,
"dynamicSize": 0
}]
}]'''
expect_json_v2 = '''[{
"staticSize":80,
"exclusiveSize":0,
"size":92,
"members":[
{
"name":"m",
"typeNames": ["__oi_anon_1"],
"staticSize": 48,
"exclusiveSize":0,
"size": 60,
"members":[
{"name":"__oi_anon_0", "typeNames":["__oi_anon_2"], "staticSize":16, "exclusiveSize":16, "size":16},
{
"name":"v",
"typeNames":["__oi_anon_3"],
"staticSize":32,
"exclusiveSize":4,
"size":44,
"members":[
{"name":"a", "typeNames":["int32_t"], "staticSize":4, "exclusiveSize":4, "size":4},
{"name":"b", "typeNames":["int32_t"], "staticSize":4, "exclusiveSize":4, "size":4},
{"name":"c", "typeNames":["int32_t"], "staticSize":4, "exclusiveSize":4, "size":4},
{"name":"__oi_anon_4", "typeNames":["__oi_anon_4"], "staticSize":8, "exclusiveSize":8, "size":8},
{
"name":"as",
"typeNames":["AnonStruct", "__oi_anon_6"],
"staticSize":8,
"exclusiveSize":0,
"size":20,
"members":[{
"name":"node",
"typeNames":["ns_anonymous::Node*"],
"staticSize":8,
"exclusiveSize":8,
"size":20,
"members":[{
"name":"*",
"typeNames":["ns_anonymous::Node"],
"staticSize":12,
"exclusiveSize":0,
"size":12,
"members":[
{ "name": "a", "staticSize": 4, "exclusiveSize": 4, "size": 4 },
{ "name": "b", "staticSize": 4, "exclusiveSize": 4, "size": 4 },
{ "name": "c", "staticSize": 4, "exclusiveSize": 4, "size": 4 }
]
}]
}]
}
]
}
]
},
{"name":"__oi_anon_1", "typeNames": ["__oi_anon_8"], "staticSize":24, "exclusiveSize":24, "size":24},
{"name":"__oi_anon_2", "typeNames": ["__oi_anon_9"], "staticSize":8, "exclusiveSize":8, "size":8}
]
}]'''
# This test is disabled due to GCC not supporting it
# [cases.anon_array]
# param_types = ["const AnonArrayContainer&"]
# setup = '''
# auto result = AnonArrayContainer{
# .x = new float{123.456},
# .ns = {
# DynNode{ .nodes = { Node{1, 2, 3}, Node{4, 5, 6}, Node{7, 8, 9} } },
# DynNode{},
# DynNode{ .nodes = std::vector<Node>(1, Node{0, 0, 0}) },
# DynNode{ .nodes = std::vector<Node>(42, Node{1, 1, 1}) },
# },
# };
# result.ns[3].nodes.resize(22);
# return result;
# '''
# features = ["chase-raw-pointers"]
# expect_json = '''[{
# "staticSize": 104,
# "dynamicSize": 556,
# "members": [{
# "staticSize": 104,
# "dynamicSize": 556,
# "members": [{
# "name": "x",
# "staticSize": 8,
# "dynamicSize": 4,
# "members": [{ "staticSize": 4, "dynamicSize": 0 }]
# }, {
# "name": "ns",
# "staticSize": 96,
# "dynamicSize": 552,
# "length": 4,
# "capacity": 4,
# "elementStaticSize": 24,
# "members": [{
# "dynamicSize": 36,
# "members": [{ "length": 3, "capacity": 3, "elementStaticSize": 12 }]
# }, {
# "dynamicSize": 0,
# "members": [{ "length": 0, "capacity": 0, "elementStaticSize": 12 }]
# }, {
# "dynamicSize": 12,
# "members": [{ "length": 1, "capacity": 1, "elementStaticSize": 12 }]
# }, {
# "dynamicSize": 504,
# "members": [{ "length": 22, "capacity": 42, "elementStaticSize": 12 }]
# }]
# }]
# }]
# }]'''