diff --git a/test/integration/CMakeLists.txt b/test/integration/CMakeLists.txt index 5bf0d0b..e79cf11 100644 --- a/test/integration/CMakeLists.txt +++ b/test/integration/CMakeLists.txt @@ -3,6 +3,11 @@ set(INTEGRATION_TEST_CONFIGS anonymous.toml container_enums.toml cycles.toml + inheritance_access.toml + inheritance_multiple.toml + inheritance_polymorphic.toml + inheritance_polymorphic_diamond.toml + inheritance_polymorphic_non_dynamic_base.toml multi_arg.toml namespaces.toml packed.toml @@ -12,7 +17,6 @@ set(INTEGRATION_TEST_CONFIGS pointers_incomplete.toml primitives.toml references.toml - simple_multiple_multilevel_inheritance.toml simple_struct.toml std_array.toml std_deque_del_allocator.toml diff --git a/test/integration/inheritance_access.toml b/test/integration/inheritance_access.toml new file mode 100644 index 0000000..f19b1a2 --- /dev/null +++ b/test/integration/inheritance_access.toml @@ -0,0 +1,58 @@ +definitions = ''' + class Base { + int base_int; + }; + + class Public : public Base { + int public_int; + }; + + class Protected : protected Base { + int protected_int; + }; + + class Private : private Base { + int private_int; + }; +''' +[cases] + [cases.public] + param_types = ["const Public&"] + setup = "return {};" + expect_json = '''[{ + "staticSize":8, + "dynamicSize":0, + "members":[ + {"name":"base_int", "staticSize":4, "dynamicSize":0, "typeName": "int"}, + {"name":"public_int", "staticSize":4, "dynamicSize":0, "typeName": "int"} + ]}]''' + [cases.protected] + param_types = ["const Protected&"] + setup = "return {};" + expect_json = '''[{ + "staticSize":8, + "dynamicSize":0, + "members":[ + {"name":"base_int", "staticSize":4, "dynamicSize":0, "typeName": "int"}, + {"name":"protected_int", "staticSize":4, "dynamicSize":0, "typeName": "int"} + ]}]''' + [cases.private] + param_types = ["const Private&"] + setup = "return {};" + expect_json = '''[{ + "staticSize":8, + "dynamicSize":0, + "members":[ + {"name":"base_int", "staticSize":4, "dynamicSize":0, "typeName": "int"}, + {"name":"private_int", "staticSize":4, "dynamicSize":0, "typeName": "int"} + ]}]''' + [cases.public_as_base] + param_types = ["const Base&"] + arg_types = ["Public"] + setup = "return {};" + expect_json = '''[{ + "staticSize":4, + "dynamicSize":0, + "members":[ + {"name":"base_int", "staticSize":4, "dynamicSize":0, "typeName": "int"} + ]}]''' diff --git a/test/integration/simple_multiple_multilevel_inheritance.toml b/test/integration/inheritance_multiple.toml similarity index 93% rename from test/integration/simple_multiple_multilevel_inheritance.toml rename to test/integration/inheritance_multiple.toml index f730ac9..cf297d0 100644 --- a/test/integration/simple_multiple_multilevel_inheritance.toml +++ b/test/integration/inheritance_multiple.toml @@ -22,10 +22,7 @@ definitions = ''' [cases] [cases.a] param_types = ["const Derived_2&"] - setup = ''' - Derived_2 d; - return {d}; - ''' + setup = 'return {};' expect_json = '''[{ "staticSize":24, "dynamicSize":0, diff --git a/test/integration/inheritance_polymorphic.toml b/test/integration/inheritance_polymorphic.toml new file mode 100644 index 0000000..21665aa --- /dev/null +++ b/test/integration/inheritance_polymorphic.toml @@ -0,0 +1,119 @@ +includes = ["vector"] +definitions = ''' + class A { + public: + virtual void myfunc() {} + int int_a; + }; + + class B : public A { + public: + virtual void myfunc() override {} + std::vector vec_b; + }; + + class C : public B { + public: + virtual void myfunc() override {} + int int_c; + }; +''' +[cases] + [cases.a_as_a] + param_types = ["const A&"] + arg_types = ["A"] + setup = "return {};" + expect_json = '''[{ + "typeName":"A", + "staticSize":16, + "dynamicSize":0, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_a", "staticSize":4, "dynamicSize":0} + ]}]''' + + [cases.b_as_a] + param_types = ["const A&"] + arg_types = ["B"] + setup = ''' + B b; + b.vec_b = {1,2,3}; + return b; + ''' + expect_json = '''[{ + "typeName":"A", + "staticSize":16, + "dynamicSize":0, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_a", "staticSize":4, "dynamicSize":0} + ]}]''' + [cases.b_as_b] + param_types = ["const B&"] + arg_types = ["B"] + setup = ''' + B b; + b.vec_b = {1,2,3}; + return b; + ''' + expect_json = '''[{ + "typeName":"B", + "staticSize":40, + "dynamicSize":12, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_a", "staticSize":4, "dynamicSize":0}, + {"name":"vec_b", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4} + ]}]''' + + [cases.c_as_a] + param_types = ["const A&"] + arg_types = ["C"] + setup = ''' + C c; + c.vec_b = {1,2,3}; + return c; + ''' + expect_json = '''[{ + "typeName":"A", + "staticSize":16, + "dynamicSize":0, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_a", "staticSize":4, "dynamicSize":0} + ]}]''' + [cases.c_as_b] + param_types = ["const B&"] + arg_types = ["C"] + setup = ''' + C c; + c.vec_b = {1,2,3}; + return c; + ''' + expect_json = '''[{ + "typeName":"B", + "staticSize":40, + "dynamicSize":12, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_a", "staticSize":4, "dynamicSize":0}, + {"name":"vec_b", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4} + ]}]''' + [cases.c_as_c] + param_types = ["const C&"] + arg_types = ["C"] + setup = ''' + C c; + c.vec_b = {1,2,3}; + return c; + ''' + expect_json = '''[{ + "typeName":"C", + "staticSize":48, + "dynamicSize":12, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_a", "staticSize":4, "dynamicSize":0}, + {"name":"vec_b", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4}, + {"name":"int_c", "staticSize":4, "dynamicSize":0} + ]}]''' diff --git a/test/integration/inheritance_polymorphic_diamond.toml b/test/integration/inheritance_polymorphic_diamond.toml new file mode 100644 index 0000000..66de16a --- /dev/null +++ b/test/integration/inheritance_polymorphic_diamond.toml @@ -0,0 +1,204 @@ +includes = ["vector"] +definitions = ''' + class Root { + public: + virtual void myfunc() {} + int int_root; + }; + + class Middle1 : public Root { + public: + virtual void myfunc() override {} + std::vector vec_middle1; + }; + + class Middle2 : public Root { + public: + virtual void myfunc() override {} + std::vector vec_middle2; + }; + + class Child : public Middle1, public Middle2 { + public: + virtual void myfunc() override {} + int int_child; + }; +''' +[cases] + [cases.root_as_root] + param_types = ["const Root&"] + arg_types = ["Root"] + setup = "return {};" + expect_json = '''[{ + "typeName":"Root", + "staticSize":16, + "dynamicSize":0, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0} + ]}]''' + + [cases.middle1_as_root] + param_types = ["const Root&"] + arg_types = ["Middle1"] + setup = ''' + Middle1 m; + m.vec_middle1 = {1,2,3}; + return m; + ''' + expect_json = '''[{ + "typeName":"Root", + "staticSize":16, + "dynamicSize":0, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0} + ]}]''' + [cases.middle1_as_middle1] + param_types = ["const Middle1&"] + arg_types = ["Middle1"] + setup = ''' + Middle1 m; + m.vec_middle1 = {1,2,3}; + return m; + ''' + expect_json = '''[{ + "typeName":"Middle1", + "staticSize":40, + "dynamicSize":12, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0}, + {"name":"vec_middle1", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4} + ]}]''' + + [cases.middle2_as_root] + param_types = ["const Root&"] + arg_types = ["Middle2"] + setup = ''' + Middle2 m; + m.vec_middle2 = {4,5}; + return m; + ''' + expect_json = '''[{ + "typeName":"Root", + "staticSize":16, + "dynamicSize":0, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0} + ]}]''' + [cases.middle2_as_middle2] + param_types = ["const Middle2&"] + arg_types = ["Middle2"] + setup = ''' + Middle2 m; + m.vec_middle2 = {4,5}; + return m; + ''' + expect_json = '''[{ + "typeName":"Middle2", + "staticSize":40, + "dynamicSize":8, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0}, + {"name":"vec_middle2", "staticSize":24, "dynamicSize":8, "length":2, "capacity":2, "elementStaticSize":4} + ]}]''' + + [cases.child_as_middle1_root] + # We need to explicitly cast from Child to Middle1 before going to root to + # resolve the diamond problem + param_types = ["const Root&"] + arg_types = ["Middle1&"] + setup = ''' + auto c = new Child{}; + c->vec_middle1 = {1,2,3}; + c->vec_middle2 = {4,5}; + return static_cast(*c); + ''' + expect_json = '''[{ + "typeName":"Root", + "staticSize":16, + "dynamicSize":0, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0} + ]}]''' + [cases.child_as_middle2_root] + # We need to explicitly cast from Child to Middle2 before going to root to + # resolve the diamond problem + param_types = ["const Root&"] + arg_types = ["Middle2&"] + setup = ''' + auto c = new Child{}; + c->vec_middle1 = {1,2,3}; + c->vec_middle2 = {4,5}; + return static_cast(*c); + ''' + expect_json = '''[{ + "typeName":"Root", + "staticSize":16, + "dynamicSize":0, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0} + ]}]''' + [cases.child_as_middle1] + param_types = ["const Middle1&"] + arg_types = ["Child"] + setup = ''' + Child c; + c.vec_middle1 = {1,2,3}; + c.vec_middle2 = {4,5}; + return c; + ''' + expect_json = '''[{ + "typeName":"Middle1", + "staticSize":40, + "dynamicSize":12, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0}, + {"name":"vec_middle1", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4} + ]}]''' + [cases.child_as_middle2] + param_types = ["const Middle2&"] + arg_types = ["Child"] + setup = ''' + Child c; + c.vec_middle1 = {1,2,3}; + c.vec_middle2 = {4,5}; + return c; + ''' + expect_json = '''[{ + "typeName":"Middle2", + "staticSize":40, + "dynamicSize":8, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0}, + {"name":"vec_middle2", "staticSize":24, "dynamicSize":8, "length":2, "capacity":2, "elementStaticSize":4} + ]}]''' + [cases.child_as_child] + param_types = ["const Child&"] + arg_types = ["Child"] + setup = ''' + Child c; + c.vec_middle1 = {1,2,3}; + c.vec_middle2 = {4,5}; + return c; + ''' + expect_json = '''[{ + "typeName":"Child", + "staticSize":88, + "dynamicSize":20, + "members":[ + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0}, + {"name":"vec_middle1", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4}, + {"staticSize":8, "dynamicSize":0}, + {"name":"int_root", "staticSize":4, "dynamicSize":0}, + {"name":"vec_middle2", "staticSize":24, "dynamicSize":8, "length":2, "capacity":2, "elementStaticSize":4}, + {"name":"int_child", "staticSize":4, "dynamicSize":0} + ]}]''' diff --git a/test/integration/inheritance_polymorphic_non_dynamic_base.toml b/test/integration/inheritance_polymorphic_non_dynamic_base.toml new file mode 100644 index 0000000..8fefcb1 --- /dev/null +++ b/test/integration/inheritance_polymorphic_non_dynamic_base.toml @@ -0,0 +1,115 @@ +includes = ["vector"] +definitions = ''' + class A { + public: + int int_a; + }; + + class B : public A { + public: + virtual void myfunc() {} + std::vector vec_b; + }; + + class C : public B { + public: + virtual void myfunc() override {} + int int_c; + }; +''' +[cases] + [cases.a_as_a] + param_types = ["const A&"] + arg_types = ["A"] + setup = "return {};" + expect_json = '''[{ + "typeName":"A", + "staticSize":4, + "dynamicSize":0, + "members":[ + {"name":"int_a", "staticSize":4, "dynamicSize":0} + ]}]''' + + [cases.b_as_a] + param_types = ["const A&"] + arg_types = ["B"] + setup = ''' + B b; + b.vec_b = {1,2,3}; + return b; + ''' + expect_json = '''[{ + "typeName":"A", + "staticSize":4, + "dynamicSize":0, + "members":[ + {"name":"int_a", "staticSize":4, "dynamicSize":0} + ]}]''' + [cases.b_as_b] + param_types = ["const B&"] + arg_types = ["B"] + setup = ''' + B b; + b.vec_b = {1,2,3}; + return b; + ''' + expect_json = '''[{ + "typeName":"B", + "staticSize":40, + "dynamicSize":12, + "members":[ + {"name":"int_a", "staticSize":4, "dynamicSize":0}, + {"staticSize":8, "dynamicSize":0}, + {"name":"vec_b", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4} + ]}]''' + + [cases.c_as_a] + param_types = ["const A&"] + arg_types = ["C"] + setup = ''' + C c; + c.vec_b = {1,2,3}; + return c; + ''' + expect_json = '''[{ + "typeName":"A", + "staticSize":4, + "dynamicSize":0, + "members":[ + {"name":"int_a", "staticSize":4, "dynamicSize":0} + ]}]''' + [cases.c_as_b] + param_types = ["const B&"] + arg_types = ["C"] + setup = ''' + C c; + c.vec_b = {1,2,3}; + return c; + ''' + expect_json = '''[{ + "typeName":"B", + "staticSize":40, + "dynamicSize":12, + "members":[ + {"name":"int_a", "staticSize":4, "dynamicSize":0}, + {"staticSize":8, "dynamicSize":0}, + {"name":"vec_b", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4} + ]}]''' + [cases.c_as_c] + param_types = ["const C&"] + arg_types = ["C"] + setup = ''' + C c; + c.vec_b = {1,2,3}; + return c; + ''' + expect_json = '''[{ + "typeName":"C", + "staticSize":48, + "dynamicSize":12, + "members":[ + {"name":"int_a", "staticSize":4, "dynamicSize":0}, + {"staticSize":8, "dynamicSize":0}, + {"name":"vec_b", "staticSize":24, "dynamicSize":12, "length":3, "capacity":3, "elementStaticSize":4}, + {"name":"int_c", "staticSize":4, "dynamicSize":0} + ]}]'''