mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-12 21:56:54 +00:00
tbv2: fix exclusive size of elements in containers
This commit is contained in:
parent
e867178ebd
commit
f7bb1e75ad
@ -188,6 +188,22 @@ void genDecls(const TypeGraph& typeGraph, std::string& code) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
size_t calculateExclusiveSize(const Type& t) {
|
||||
if (const auto* c = dynamic_cast<const Class*>(&t)) {
|
||||
return std::accumulate(c->members.cbegin(), c->members.cend(), 0,
|
||||
[](size_t a, const auto& m) {
|
||||
if (m.name.starts_with(AddPadding::MemberPrefix))
|
||||
return a + m.type().size();
|
||||
return a;
|
||||
});
|
||||
}
|
||||
return t.size();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void genNames(const TypeGraph& typeGraph, std::string& code) {
|
||||
code += R"(
|
||||
template <typename T>
|
||||
@ -206,6 +222,26 @@ struct NameProvider {};
|
||||
}
|
||||
}
|
||||
|
||||
void genExclusiveSizes(const TypeGraph& typeGraph, std::string& code) {
|
||||
code += R"(
|
||||
template <typename T>
|
||||
struct ExclusiveSizeProvider {
|
||||
static constexpr size_t size = sizeof(T);
|
||||
};
|
||||
)";
|
||||
|
||||
for (const Type& t : typeGraph.finalTypes) {
|
||||
size_t exclusiveSize = calculateExclusiveSize(t);
|
||||
if (exclusiveSize != t.size()) {
|
||||
code += "template <> struct ExclusiveSizeProvider<";
|
||||
code += t.name();
|
||||
code += "> { static constexpr size_t size = ";
|
||||
code += std::to_string(exclusiveSize);
|
||||
code += "; };\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates a declaration for a given fully-qualified type.
|
||||
*
|
||||
@ -714,22 +750,6 @@ void CodeGen::genClassStaticType(const Class& c, std::string& code) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
size_t calculateExclusiveSize(const Type& t) {
|
||||
if (const auto* c = dynamic_cast<const Class*>(&t)) {
|
||||
return std::accumulate(c->members.cbegin(), c->members.cend(), 0,
|
||||
[](size_t a, const auto& m) {
|
||||
if (m.name.starts_with(AddPadding::MemberPrefix))
|
||||
return a + m.type().size();
|
||||
return a;
|
||||
});
|
||||
}
|
||||
return t.size();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void CodeGen::genClassTreeBuilderInstructions(const Class& c,
|
||||
std::string& code) {
|
||||
code += " private:\n";
|
||||
@ -1047,7 +1067,7 @@ template <typename DB, typename T>
|
||||
constexpr inst::Field make_field(std::string_view name) {
|
||||
return inst::Field{
|
||||
sizeof(T),
|
||||
sizeof(T), // TODO: this is incorrect for excl size
|
||||
ExclusiveSizeProvider<T>::size,
|
||||
name,
|
||||
NameProvider<T>::names,
|
||||
TypeHandler<DB, T>::fields,
|
||||
@ -1245,8 +1265,10 @@ void CodeGen::generate(
|
||||
genDecls(typeGraph, code);
|
||||
genDefs(typeGraph, code);
|
||||
genStaticAsserts(typeGraph, code);
|
||||
if (config_.features[Feature::TreeBuilderV2])
|
||||
if (config_.features[Feature::TreeBuilderV2]) {
|
||||
genNames(typeGraph, code);
|
||||
genExclusiveSizes(typeGraph, code);
|
||||
}
|
||||
|
||||
if (config_.features[Feature::TypedDataSegment]) {
|
||||
addStandardTypeHandlers(typeGraph, config_.features, code);
|
||||
|
@ -1,4 +1,13 @@
|
||||
includes = ["vector"]
|
||||
|
||||
definitions = '''
|
||||
struct SimpleStruct {
|
||||
int a;
|
||||
char b;
|
||||
long long c;
|
||||
};
|
||||
'''
|
||||
|
||||
[cases]
|
||||
[cases.int_empty]
|
||||
param_types = ["const std::vector<int>&"]
|
||||
@ -14,6 +23,15 @@ includes = ["vector"]
|
||||
{"staticSize":4, "exclusiveSize":4},
|
||||
{"staticSize":4, "exclusiveSize":4}
|
||||
]}]'''
|
||||
[cases.struct_some]
|
||||
param_types = ["const std::vector<SimpleStruct>&"]
|
||||
setup = "return {{{}, {}, {}}};"
|
||||
expect_json = '[{"staticSize":24, "dynamicSize":48, "length":3, "capacity":3, "elementStaticSize":16}]'
|
||||
expect_json_v2 = '''[{"staticSize":24, "exclusiveSize":24, "length":3, "capacity":3, "members":[
|
||||
{"staticSize":16, "exclusiveSize":3},
|
||||
{"staticSize":16, "exclusiveSize":3},
|
||||
{"staticSize":16, "exclusiveSize":3}
|
||||
]}]'''
|
||||
[cases.bool_empty]
|
||||
skip = true # https://github.com/facebookexperimental/object-introspection/issues/14
|
||||
param_types = ["const std::vector<bool>&"]
|
||||
|
@ -27,7 +27,6 @@ includes = ["vector"]
|
||||
|
||||
[cases]
|
||||
[cases.a]
|
||||
oil_skip = "oil gets the exclusive size of vector subfields wrong" # https://github.com/facebookexperimental/object-introspection/issues/301
|
||||
param_types = ["const Foo&"]
|
||||
setup = '''
|
||||
Foo foo;
|
||||
|
Loading…
Reference in New Issue
Block a user