object-introspection/test/integration/pointers_incomplete.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

167 lines
6.1 KiB
TOML

includes = ["memory", "optional"]
definitions = '''
struct IncompleteType;
struct IncompleteTypeContainer {
IncompleteType *ptrundef;
// std::unique_ptr<IncompleteType> unundef; // std::unique_ptr requires its template param to have a size
char __makePad1;
std::shared_ptr<IncompleteType> shundef;
char __makePad2;
std::optional<std::shared_ptr<IncompleteType>> shoptundef;
char __makePad3;
std::optional<IncompleteType *> optundef;
};
void incomplete_type_deleter(IncompleteType *ptr) {
::operator delete(ptr);
}
'''
[cases]
[cases.raw]
oid_skip = "oid codegen fails on this" # https://github.com/facebookexperimental/object-introspection/issues/17
oil_skip = "oil codegen fails on top level incomplete objects" # https://github.com/facebookexperimental/object-introspection/issues/459
param_types = ["IncompleteType*"]
setup = "return static_cast<IncompleteType*>(::operator new(5));"
features = ["chase-raw-pointers"]
expect_json = '''[{
"typeName": "IncompleteType",
"staticSize": 0,
"dynamicSize": 0,
"NOT": "members"
}]'''
[cases.raw_no_follow]
oid_skip = "oid codegen fails on this" # https://github.com/facebookexperimental/object-introspection/issues/17
oil_skip = "oil codegen fails on top level incomplete objects" # https://github.com/facebookexperimental/object-introspection/issues/459
param_types = ["IncompleteType*"]
setup = "return static_cast<IncompleteType*>(::operator new(5));"
expect_json = '''[{
"typeName": "IncompleteType",
"staticSize": 0,
"dynamicSize": 0,
"NOT": "members"
}]'''
[cases.raw_null]
oid_skip = "oid codegen fails on this" # https://github.com/facebookexperimental/object-introspection/issues/17
oil_skip = "oil codegen fails on top level incomplete objects" # https://github.com/facebookexperimental/object-introspection/issues/459
param_types = ["IncompleteType*"]
setup = "return nullptr;"
expect_json = '''[{
"typeName": "IncompleteType",
"staticSize": 0,
"dynamicSize": 0,
"NOT": "members"
}]'''
[cases.unique_ptr]
param_types = ["const std::unique_ptr<IncompleteType, decltype(&incomplete_type_deleter)>&"]
setup = '''
auto raw_ptr = static_cast<IncompleteType*>(::operator new(5));
return std::unique_ptr<IncompleteType, decltype(&incomplete_type_deleter)>(
raw_ptr, &incomplete_type_deleter);
'''
expect_json = '[{"staticSize":16, "dynamicSize":0, "NOT":"members"}]'
expect_json_v2 = '[{"staticSize":16, "exclusiveSize":16}]'
[cases.unique_ptr_null]
param_types = ["const std::unique_ptr<IncompleteType, decltype(&incomplete_type_deleter)>&"]
setup = '''
return std::unique_ptr<IncompleteType, decltype(&incomplete_type_deleter)>(
nullptr, &incomplete_type_deleter);
'''
expect_json = '[{"staticSize":16, "dynamicSize":0, "NOT":"members"}]'
expect_json_v2 = '[{"staticSize":16, "exclusiveSize":16}]'
[cases.shared_ptr]
param_types = ["const std::shared_ptr<IncompleteType>&"]
setup = '''
auto raw_ptr = static_cast<IncompleteType*>(::operator new(5));
return std::shared_ptr<IncompleteType>(raw_ptr , &incomplete_type_deleter);
'''
expect_json = '[{"staticSize":16, "dynamicSize":0, "NOT":"members"}]'
expect_json_v2 = '[{"staticSize":16, "exclusiveSize":16}]'
[cases.shared_ptr_null]
param_types = ["const std::shared_ptr<IncompleteType>"]
setup = "return nullptr;"
expect_json = '[{"staticSize":16, "dynamicSize":0, "NOT":"members"}]'
expect_json_v2 = '[{"staticSize":16, "exclusiveSize":16}]'
[cases.containing_struct]
param_types = ["const IncompleteTypeContainer&"]
setup = "return IncompleteTypeContainer{};"
features = ["chase-raw-pointers"]
expect_json = '''[{
"staticSize": 88,
"dynamicSize": 0,
"members": [
{ "name": "ptrundef", "staticSize": 8, "dynamicSize": 0 },
{ "name": "__makePad1", "staticSize": 1, "dynamicSize": 0 },
{ "name": "shundef", "staticSize": 16, "dynamicSize": 0 },
{ "name": "__makePad2", "staticSize": 1, "dynamicSize": 0 },
{ "name": "shoptundef",
"staticSize": 24,
"dynamicSize": 0,
"length": 0,
"capacity": 1,
"elementStaticSize": 16
},
{ "name": "__makePad3", "staticSize": 1, "dynamicSize": 0 },
{ "name": "optundef",
"staticSize": 16,
"dynamicSize": 0,
"length": 0,
"capacity": 1,
"elementStaticSize": 8
}
]
}]'''
expect_json_v2 = '''[{
"staticSize": 88,
"exclusiveSize": 21,
"size": 88,
"members": [
{ "name": "ptrundef", "staticSize": 8, "exclusiveSize": 8, "size": 8 },
{ "name": "__makePad1", "staticSize": 1, "exclusiveSize": 1, "size": 1 },
{ "name": "shundef", "staticSize": 16, "exclusiveSize": 16, "size": 16 },
{ "name": "__makePad2", "staticSize": 1, "exclusiveSize": 1, "size": 1 },
{ "name": "shoptundef",
"staticSize": 24,
"exclusiveSize": 24,
"size": 24,
"length": 0,
"capacity": 1
},
{ "name": "__makePad3", "staticSize": 1, "exclusiveSize": 1, "size": 1 },
{ "name": "optundef",
"staticSize": 16,
"exclusiveSize": 16,
"size": 16,
"length": 0,
"capacity": 1
}
]
}]'''
[cases.containing_struct_no_follow]
param_types = ["const IncompleteTypeContainer&"]
setup = "return IncompleteTypeContainer{};"
expect_json = '''[{
"staticSize": 88,
"members": [
{ "name": "ptrundef", "staticSize": 8 },
{ "name": "__makePad1", "staticSize": 1 },
{ "name": "shundef", "staticSize": 16 },
{ "name": "__makePad2", "staticSize": 1 },
{ "name": "shoptundef",
"staticSize": 24,
"length": 0,
"capacity": 1
},
{ "name": "__makePad3", "staticSize": 1 },
{ "name": "optundef",
"staticSize": 16,
"length": 0,
"capacity": 1
}
]
}]'''