diff --git a/oi/CodeGen.cpp b/oi/CodeGen.cpp index bef102f..ea8e4e3 100644 --- a/oi/CodeGen.cpp +++ b/oi/CodeGen.cpp @@ -1157,9 +1157,9 @@ void CodeGen::transform(TypeGraph& typeGraph) { // Simplify the type graph first so there is less work for later passes pm.addPass(RemoveTopLevelPointer::createPass()); + pm.addPass(IdentifyContainers::createPass(containerInfos_)); pm.addPass(Flattener::createPass()); pm.addPass(AlignmentCalc::createPass()); - pm.addPass(IdentifyContainers::createPass(containerInfos_)); pm.addPass(TypeIdentifier::createPass(config_.passThroughTypes)); if (config_.features[Feature::PruneTypeGraph]) pm.addPass(Prune::createPass()); @@ -1173,9 +1173,9 @@ void CodeGen::transform(TypeGraph& typeGraph) { pm.addPass(AddChildren::createPass(drgnParser, symbols_)); // Re-run passes over newly added children + pm.addPass(IdentifyContainers::createPass(containerInfos_)); pm.addPass(Flattener::createPass()); pm.addPass(AlignmentCalc::createPass()); - pm.addPass(IdentifyContainers::createPass(containerInfos_)); pm.addPass(TypeIdentifier::createPass(config_.passThroughTypes)); if (config_.features[Feature::PruneTypeGraph]) pm.addPass(Prune::createPass()); diff --git a/oi/type_graph/AlignmentCalc.cpp b/oi/type_graph/AlignmentCalc.cpp index 31a7a30..cf23eff 100644 --- a/oi/type_graph/AlignmentCalc.cpp +++ b/oi/type_graph/AlignmentCalc.cpp @@ -48,15 +48,7 @@ void AlignmentCalc::accept(Type& type) { } void AlignmentCalc::visit(Class& c) { - for (const auto& param : c.templateParams) { - accept(param.type()); - } - for (const auto& parent : c.parents) { - accept(parent.type()); - } - for (const auto& child : c.children) { - accept(child); - } + RecursiveVisitor::visit(c); uint64_t alignment = 1; for (auto& member : c.members) { @@ -82,4 +74,12 @@ void AlignmentCalc::visit(Class& c) { } } +void AlignmentCalc::visit(Container& c) { + RecursiveVisitor::visit(c); + + if (c.underlying()) { + c.setAlign(c.underlying()->align()); + } +} + } // namespace oi::detail::type_graph diff --git a/oi/type_graph/AlignmentCalc.h b/oi/type_graph/AlignmentCalc.h index 4949341..b89f114 100644 --- a/oi/type_graph/AlignmentCalc.h +++ b/oi/type_graph/AlignmentCalc.h @@ -41,6 +41,7 @@ class AlignmentCalc final : public RecursiveVisitor { void accept(Type& type) override; void visit(Class& c) override; + void visit(Container& c) override; private: std::unordered_set visited_; diff --git a/oi/type_graph/DrgnParser.h b/oi/type_graph/DrgnParser.h index 5b8fbe3..1d69636 100644 --- a/oi/type_graph/DrgnParser.h +++ b/oi/type_graph/DrgnParser.h @@ -81,7 +81,7 @@ class DrgnParser { template T& makeType(struct drgn_type* drgnType, Args&&... args) { auto& newType = typeGraph_.makeType(std::forward(args)...); - drgn_types_.insert({drgnType, newType}); + drgn_types_.insert_or_assign(drgnType, newType); return newType; } bool chasePointer() const; diff --git a/oi/type_graph/Flattener.cpp b/oi/type_graph/Flattener.cpp index 57e3748..28a9f32 100644 --- a/oi/type_graph/Flattener.cpp +++ b/oi/type_graph/Flattener.cpp @@ -134,8 +134,6 @@ void Flattener::visit(Class& c) { // }; // TODO comment about virtual inheritance - // TODO alignment of parent classes - // Flatten types referenced by template params, parents and members for (const auto& param : c.templateParams) { accept(param.type()); @@ -207,12 +205,4 @@ void Flattener::visit(Class& c) { } } -void Flattener::visit(Container& c) { - // Containers themselves don't need to be flattened, but their template - // parameters might need to be - for (const auto& templateParam : c.templateParams) { - accept(templateParam.type()); - } -} - } // namespace oi::detail::type_graph diff --git a/oi/type_graph/Flattener.h b/oi/type_graph/Flattener.h index 1d46f02..95f78c6 100644 --- a/oi/type_graph/Flattener.h +++ b/oi/type_graph/Flattener.h @@ -42,7 +42,6 @@ class Flattener : public RecursiveVisitor { void accept(Type& type) override; void visit(Class& c) override; - void visit(Container& c) override; static const inline std::string ParentPrefix = "__oi_parent"; diff --git a/oi/type_graph/IdentifyContainers.cpp b/oi/type_graph/IdentifyContainers.cpp index 470f2af..1a4f648 100644 --- a/oi/type_graph/IdentifyContainers.cpp +++ b/oi/type_graph/IdentifyContainers.cpp @@ -57,11 +57,12 @@ Type& IdentifyContainers::visit(Class& c) { continue; } - auto& container = typeGraph_.makeType(*containerInfo, c.size()); + auto& container = + typeGraph_.makeType(*containerInfo, c.size(), &c); container.templateParams = c.templateParams; tracker_.set(c, &container); - RecursiveMutator::visit(container); + visit(container); return container; } @@ -70,4 +71,15 @@ Type& IdentifyContainers::visit(Class& c) { return c; } +Type& IdentifyContainers::visit(Container& c) { + for (auto& param : c.templateParams) { + param.setType(mutate(param.type())); + } + + // Do not mutate the underlying class further here as that would result in it + // getting replaced with this Container node + + return c; +} + } // namespace oi::detail::type_graph diff --git a/oi/type_graph/IdentifyContainers.h b/oi/type_graph/IdentifyContainers.h index 2e7c793..cffb170 100644 --- a/oi/type_graph/IdentifyContainers.h +++ b/oi/type_graph/IdentifyContainers.h @@ -48,6 +48,7 @@ class IdentifyContainers : public RecursiveMutator { Type& mutate(Type& type) override; Type& visit(Class& c) override; + Type& visit(Container& c) override; private: ResultTracker tracker_; diff --git a/oi/type_graph/Printer.cpp b/oi/type_graph/Printer.cpp index e7d70eb..0dae0ab 100644 --- a/oi/type_graph/Printer.cpp +++ b/oi/type_graph/Printer.cpp @@ -85,7 +85,7 @@ void Printer::visit(const Class& c) { print_function(function); } for (auto& child : c.children) { - print_child(child); + print_type("Child", child); } } @@ -93,11 +93,14 @@ void Printer::visit(const Container& c) { if (prefix(c)) return; - out_ << "Container: " << c.name() << " (size: " << c.size() << ")" - << std::endl; + out_ << "Container: " << c.name() << " (size: " << c.size() + << align_str(c.align()) << ")" << std::endl; for (const auto& param : c.templateParams) { print_param(param); } + if (c.underlying()) { + print_type("Underlying", *c.underlying()); + } } void Printer::visit(const Primitive& p) { @@ -240,11 +243,11 @@ void Printer::print_function(const Function& function) { depth_--; } -void Printer::print_child(const Type& child) { +void Printer::print_type(std::string_view header, const Type& type) { depth_++; prefix(); - out_ << "Child" << std::endl; - print(child); + out_ << header << std::endl; + print(type); depth_--; } diff --git a/oi/type_graph/Printer.h b/oi/type_graph/Printer.h index a66581e..8d7138a 100644 --- a/oi/type_graph/Printer.h +++ b/oi/type_graph/Printer.h @@ -51,7 +51,7 @@ class Printer : public ConstVisitor { void print_parent(const Parent& parent); void print_member(const Member& member); void print_function(const Function& function); - void print_child(const Type& child); + void print_type(std::string_view header, const Type& type); void print_value(const std::string& value); void print_qualifiers(const QualifierSet& qualifiers); void print_enumerator(int64_t val, const std::string& name); diff --git a/oi/type_graph/Prune.cpp b/oi/type_graph/Prune.cpp index 903a8c2..8effd3b 100644 --- a/oi/type_graph/Prune.cpp +++ b/oi/type_graph/Prune.cpp @@ -39,18 +39,7 @@ void Prune::accept(Type& type) { } void Prune::visit(Class& c) { - for (const auto& param : c.templateParams) { - accept(param.type()); - } - for (const auto& parent : c.parents) { - accept(parent.type()); - } - for (const auto& member : c.members) { - accept(member.type()); - } - for (const auto& child : c.children) { - accept(child); - } + RecursiveVisitor::visit(c); c.templateParams.clear(); c.parents.clear(); @@ -62,4 +51,10 @@ void Prune::visit(Class& c) { c.functions.shrink_to_fit(); } +void Prune::visit(Container& c) { + RecursiveVisitor::visit(c); + + c.setUnderlying(nullptr); +} + } // namespace oi::detail::type_graph diff --git a/oi/type_graph/Prune.h b/oi/type_graph/Prune.h index d444ea3..c0701db 100644 --- a/oi/type_graph/Prune.h +++ b/oi/type_graph/Prune.h @@ -43,6 +43,7 @@ class Prune : public RecursiveVisitor { void accept(Type& type) override; void visit(Class& c) override; + void visit(Container& c) override; private: NodeTracker& tracker_; diff --git a/oi/type_graph/TypeIdentifier.cpp b/oi/type_graph/TypeIdentifier.cpp index 17fa43a..bba08f8 100644 --- a/oi/type_graph/TypeIdentifier.cpp +++ b/oi/type_graph/TypeIdentifier.cpp @@ -79,7 +79,8 @@ void TypeIdentifier::visit(Container& c) { it != passThroughTypeDummys_.end()) { dummy = &it->second.get(); } else { - dummy = &typeGraph_.makeType(info, param.type().size()); + dummy = &typeGraph_.makeType( + info, param.type().size(), paramClass); dummy->templateParams = paramClass->templateParams; passThroughTypeDummys_.insert(it, {paramClass->id(), std::ref(*dummy)}); diff --git a/oi/type_graph/Types.h b/oi/type_graph/Types.h index dfb0806..e05d224 100644 --- a/oi/type_graph/Types.h +++ b/oi/type_graph/Types.h @@ -150,7 +150,6 @@ struct Function { int virtuality; }; -class Class; struct Parent { Parent(Type& type, uint64_t bitOffset) : type_(type), bitOffset(bitOffset) { } @@ -298,10 +297,6 @@ class Class : public Type { DECLARE_ACCEPT - Kind kind() const { - return kind_; - } - virtual const std::string& name() const override { return name_; } @@ -326,12 +321,16 @@ class Class : public Type { return align_; } + void setAlign(uint64_t alignment) { + align_ = alignment; + } + virtual NodeId id() const override { return id_; } - void setAlign(uint64_t alignment) { - align_ = alignment; + Kind kind() const { + return kind_; } int virtuality() const { @@ -371,10 +370,19 @@ class Class : public Type { bool packed_ = false; }; +/* + * Container + * + * A type of class for which we can do special processing. + */ class Container : public Type { public: - Container(NodeId id, const ContainerInfo& containerInfo, size_t size) + Container(NodeId id, + const ContainerInfo& containerInfo, + size_t size, + Type* underlying) : containerInfo_(containerInfo), + underlying_(underlying), name_(containerInfo.typeName), inputName_(containerInfo.typeName), size_(size), @@ -386,6 +394,7 @@ class Container : public Type { const ContainerInfo& containerInfo) : templateParams(other.templateParams), containerInfo_(containerInfo), + underlying_(other.underlying_), name_(other.name_), inputName_(other.inputName_), size_(other.size_), @@ -396,22 +405,18 @@ class Container : public Type { DECLARE_ACCEPT - const std::string& containerName() const { - return containerInfo_.typeName; - } - virtual const std::string& name() const override { return name_; } - void setName(std::string name) { - name_ = std::move(name); - } - virtual std::string_view inputName() const override { return inputName_; } + void setName(std::string name) { + name_ = std::move(name); + } + void setInputName(std::string name) { inputName_ = std::move(name); } @@ -424,18 +429,31 @@ class Container : public Type { return align_; } + void setAlign(uint64_t alignment) { + align_ = alignment; + } + virtual NodeId id() const override { return id_; } - void setAlign(uint64_t alignment) { - align_ = alignment; + const std::string& containerName() const { + return containerInfo_.typeName; + } + + Type* underlying() const { + return underlying_; + } + + void setUnderlying(Type* underlying) { + underlying_ = underlying; } std::vector templateParams; const ContainerInfo& containerInfo_; private: + Type* underlying_; std::string name_; std::string inputName_; size_t size_; diff --git a/oi/type_graph/Visitor.h b/oi/type_graph/Visitor.h index 68c2c26..a7f7eec 100644 --- a/oi/type_graph/Visitor.h +++ b/oi/type_graph/Visitor.h @@ -93,6 +93,7 @@ class RecursiveVisitor : public Visitor { for (const auto& param : c.templateParams) { accept(param.type()); } + accept(c.underlying()); } virtual void visit(Primitive&) { } @@ -126,6 +127,11 @@ class RecursiveMutator : public Visitor { public: virtual ~RecursiveMutator() = default; virtual Type& mutate(Type&) = 0; + virtual Type* mutate(Type* type) { + if (type) + return &mutate(*type); + return nullptr; + } virtual Type& visit(Incomplete& i) { return i; } @@ -148,6 +154,7 @@ class RecursiveMutator : public Visitor { for (auto& param : c.templateParams) { param.setType(mutate(param.type())); } + c.setUnderlying(mutate(c.underlying())); return c; } virtual Type& visit(Primitive& p) { diff --git a/test/TypeGraphParser.cpp b/test/TypeGraphParser.cpp index 7b6f425..f54fe08 100644 --- a/test/TypeGraphParser.cpp +++ b/test/TypeGraphParser.cpp @@ -265,10 +265,11 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) { auto size = parseNumericAttribute(line, nodeTypeName, "size: "); - Container& c = typeGraph_.makeType(id, info, size); + Container& c = typeGraph_.makeType(id, info, size, nullptr); nodesById_.insert({id, c}); parseParams(c, input, indent + 2); + parseUnderlying(c, input, indent + 2); type = &c; } else if (nodeTypeName == "Primitive") { @@ -452,3 +453,26 @@ void TypeGraphParser::parseChildren(Class& c, // No more children for us - put back the line we just read input = origInput; } + +void TypeGraphParser::parseUnderlying(Container& c, + std::string_view& input, + size_t rootIndent) { + std::string_view origInput = input; + std::string_view line; + getline(input, line); + + size_t indent = stripIndent(line); + if (indent != rootIndent) { + input = origInput; + return; + } + + // Format: "Underlying" + if (!tryRemovePrefix(line, "Underlying")) { + input = origInput; + return; + } + + Type& type = parseType(input, rootIndent + 2); + c.setUnderlying(&type); +} diff --git a/test/TypeGraphParser.h b/test/TypeGraphParser.h index 626c4a4..640b706 100644 --- a/test/TypeGraphParser.h +++ b/test/TypeGraphParser.h @@ -34,6 +34,9 @@ class TypeGraphParser { void parseMembers(Class& c, std::string_view& input, size_t rootIndent); void parseFunctions(Class& c, std::string_view& input, size_t rootIndent); void parseChildren(Class& c, std::string_view& input, size_t rootIndent); + void parseUnderlying(Container& c, + std::string_view& input, + size_t rootIndent); }; class TypeGraphParserError : public std::runtime_error { diff --git a/test/test_add_children.cpp b/test/test_add_children.cpp index aca046e..0d9fb75 100644 --- a/test/test_add_children.cpp +++ b/test/test_add_children.cpp @@ -106,7 +106,7 @@ TEST_F(AddChildrenTest, InheritancePolymorphic) { Function: ~allocator Function: allocate Function: deallocate - * +* Function: ~B (virtual) Function: myfunc (virtual) Function: B @@ -159,7 +159,7 @@ TEST_F(AddChildrenTest, InheritancePolymorphic) { Function: ~allocator Function: allocate Function: deallocate - * +* Function: operator= Function: B Function: B diff --git a/test/test_alignment_calc.cpp b/test/test_alignment_calc.cpp index 5bc4573..2526cbe 100644 --- a/test/test_alignment_calc.cpp +++ b/test/test_alignment_calc.cpp @@ -58,16 +58,16 @@ TEST(AlignmentCalcTest, StructInContainer) { Member: n (offset: 0) Primitive: int8_t Member: n (offset: 8) - Primitive: int64_t + Primitive: int32_t )", R"( [0] Container: std::vector (size: 8) Param -[1] Class: MyClass (size: 16, align: 8) +[1] Class: MyClass (size: 16, align: 4) Member: n (offset: 0, align: 1) Primitive: int8_t - Member: n (offset: 8, align: 8) - Primitive: int64_t + Member: n (offset: 8, align: 4) + Primitive: int32_t )"); } @@ -264,3 +264,33 @@ TEST(AlignmentCalcTest, Typedef) { Primitive: int8_t )"); } + +TEST(AlignmentCalcTest, Container) { + test(AlignmentCalc::createPass(), + R"( +[0] Container: std::vector (size: 24) + Underlying +[1] Class: vector (size: 24) + Member: n (offset: 0) + Primitive: int8_t + Member: s (offset: 4) +[2] Struct: MyStruct (size: 8) + Member: n1 (offset: 0) + Primitive: int32_t + Member: n2 (offset: 4) + Primitive: int32_t +)", + R"( +[0] Container: std::vector (size: 24, align: 4) + Underlying +[1] Class: vector (size: 24, align: 4) + Member: n (offset: 0, align: 1) + Primitive: int8_t + Member: s (offset: 4, align: 4) +[2] Struct: MyStruct (size: 8, align: 4) + Member: n1 (offset: 0, align: 4) + Primitive: int32_t + Member: n2 (offset: 4, align: 4) + Primitive: int32_t +)"); +} diff --git a/test/test_codegen.cpp b/test/test_codegen.cpp index 660c411..a74b740 100644 --- a/test/test_codegen.cpp +++ b/test/test_codegen.cpp @@ -45,6 +45,8 @@ void testTransform(OICodeGen::Config& config, void testTransform(std::string_view input, std::string_view expectedAfter) { OICodeGen::Config config; + config.features[Feature::PruneTypeGraph] = true; + config.features[Feature::TreeBuilderV2] = true; testTransform(config, input, expectedAfter); } } // namespace @@ -62,7 +64,7 @@ TEST(CodeGenTest, TransformContainerAllocator) { Function: deallocate )", R"( -[2] Container: std::vector> (size: 24) +[2] Container: std::vector> (size: 24, align: 1) Param Primitive: int32_t Param @@ -95,14 +97,14 @@ TEST(CodeGenTest, TransformContainerAllocatorParamInParent) { Function: deallocate )", R"( -[4] Container: std::map, 0, 1, 6>> (size: 24) +[4] Container: std::map, 0, 1, 6>> (size: 24, align: 1) Param Primitive: int32_t Param Primitive: int32_t Param [6] DummyAllocator [MyAlloc>] (size: 0, align: 1) -[5] Container: std::pair (size: 8) +[5] Container: std::pair (size: 8, align: 1) Param Primitive: int32_t Qualifiers: const @@ -168,7 +170,7 @@ TEST(CodeGenTest, ReplaceContainersAndDummies) { Function: deallocate )", R"( -[2] Container: std::vector> (size: 24) +[2] Container: std::vector> (size: 24, align: 1) Param Primitive: uint32_t Param @@ -176,3 +178,73 @@ TEST(CodeGenTest, ReplaceContainersAndDummies) { Primitive: uint32_t )"); } + +TEST(CodeGenTest, ContainerAlignment) { + testTransform(R"( +[0] Class: MyClass (size: 24) + Member: container (offset: 0) +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t + Member: __impl__ (offset: 0) + Primitive: StubbedPointer + Member: __impl__ (offset: 8) + Primitive: StubbedPointer + Member: __impl__ (offset: 16) + Primitive: StubbedPointer +)", + R"( +[0] Class: MyClass_0 [MyClass] (size: 24, align: 8) + Member: container_0 [container] (offset: 0, align: 8) +[2] Container: std::vector (size: 24, align: 8) + Param + Primitive: int32_t +)"); +} + +TEST(CodeGenTest, InheritFromContainer) { + testTransform(R"( +[0] Class: MyClass (size: 24) + Parent (offset: 0) +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t + Member: __impl__ (offset: 0) + Primitive: StubbedPointer + Member: __impl__ (offset: 8) + Primitive: StubbedPointer + Member: __impl__ (offset: 16) + Primitive: StubbedPointer +)", + R"( +[0] Class: MyClass_0 [MyClass] (size: 24, align: 8) + Member: __oi_parent_0 [__oi_parent] (offset: 0, align: 8) +[2] Container: std::vector (size: 24, align: 8) + Param + Primitive: int32_t +)"); +} + +TEST(CodeGenTest, InheritFromContainerCompat) { + OICodeGen::Config config; + testTransform(config, + R"( +[0] Class: MyClass (size: 24) + Parent (offset: 0) +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t + Member: __impl__ (offset: 0) + Primitive: StubbedPointer + Member: __impl__ (offset: 8) + Primitive: StubbedPointer + Member: __impl__ (offset: 16) + Primitive: StubbedPointer +)", + R"( +[0] Class: MyClass_0 [MyClass] (size: 24, align: 8) + Member: __oi_padding_0 (offset: 0) +[3] Array: [int8_t[24]] (length: 24) + Primitive: int8_t +)"); +} diff --git a/test/test_flattener.cpp b/test/test_flattener.cpp index eab3cf8..808f4ee 100644 --- a/test/test_flattener.cpp +++ b/test/test_flattener.cpp @@ -799,6 +799,27 @@ TEST(FlattenerTest, ParentClassAndContainer) { )"); } +TEST(FlattenerTest, ContainerWithParent) { + // This is necessary to correctly calculate container alignment + test(Flattener::createPass(), + R"( +[0] Container: std::vector (size: 24) + Underlying +[1] Class: vector (size: 24) + Parent (offset: 0) +[2] Class: Parent (size: 4) + Member: x (offset: 0) + Primitive: int32_t +)", + R"( +[0] Container: std::vector (size: 24) + Underlying +[1] Class: vector (size: 24) + Member: x (offset: 0) + Primitive: int32_t +)"); +} + TEST(FlattenerTest, AllocatorParamInParent) { test(Flattener::createPass(), R"( @@ -857,7 +878,7 @@ TEST(FlattenerTest, AllocatorUnfixableNoParent) { )"); } -TEST(FlattenerTest, AllocatorUnfixableParentNotClass) { +TEST(FlattenerTest, AllocatorParamInParentContainer) { // This could be supported if need-be, we just don't do it yet test(Flattener::createPass(), R"( diff --git a/test/test_identify_containers.cpp b/test/test_identify_containers.cpp index 4c359eb..3c42231 100644 --- a/test/test_identify_containers.cpp +++ b/test/test_identify_containers.cpp @@ -27,6 +27,12 @@ TEST(IdentifyContainers, Container) { [1] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[0] Class: std::vector (size: 24) + Param + Primitive: int32_t + Member: a (offset: 0) + Primitive: int32_t )"); } @@ -52,14 +58,26 @@ TEST(IdentifyContainers, ContainerInClass) { [4] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t Parent (offset: 0) [5] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[2] Class: std::vector (size: 24) + Param + Primitive: int32_t Member: a (offset: 0) [6] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[3] Class: std::vector (size: 24) + Param + Primitive: int32_t )"); } @@ -77,6 +95,14 @@ TEST(IdentifyContainers, ContainerInContainer) { [3] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t + Underlying +[0] Class: std::vector (size: 24) + Param + [1] )"); } @@ -94,6 +120,10 @@ TEST(IdentifyContainers, ContainerInContainer2) { [2] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t )"); } @@ -109,6 +139,10 @@ TEST(IdentifyContainers, ContainerInArray) { [2] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t )"); } @@ -124,6 +158,10 @@ TEST(IdentifyContainers, ContainerInTypedef) { [2] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t )"); } @@ -139,6 +177,10 @@ TEST(IdentifyContainers, ContainerInPointer) { [2] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[1] Class: std::vector (size: 24) + Param + Primitive: int32_t )"); } @@ -155,6 +197,12 @@ TEST(IdentifyContainers, ContainerDuplicate) { [1] Container: std::vector (size: 24) Param Primitive: int32_t + Underlying +[0] Class: std::vector (size: 24) + Param + Primitive: int32_t + Member: a (offset: 0) + Primitive: int32_t [1] )"); } @@ -190,5 +238,9 @@ TEST(IdentifyContainers, CycleContainer) { [2] Container: std::vector (size: 0) Param [0] + Underlying +[1] Class: std::vector (size: 0) + Param + [0] )"); } diff --git a/test/test_prune.cpp b/test/test_prune.cpp index 3ae5d61..ad8ceee 100644 --- a/test/test_prune.cpp +++ b/test/test_prune.cpp @@ -63,3 +63,33 @@ TEST(PruneTest, RecurseClassChild) { [1] Class: ClassA (size: 12) )"); } + +TEST(PruneTest, PruneContainer) { + test(Prune::createPass(), + R"( +[0] Container: std::vector (size: 24) + Param + Primitive: int32_t + Param + Value: "123" + Primitive: int32_t + Underlying +[1] Class: vector (size: 24) + Parent (offset: 0) +[2] Class: MyParent (size: 4) + Member: a (offset: 0) + Primitive: int32_t + Member: a (offset: 0) + Primitive: int32_t + Member: b (offset: 4) + Primitive: int32_t +)", + R"( +[0] Container: std::vector (size: 24) + Param + Primitive: int32_t + Param + Value: "123" + Primitive: int32_t +)"); +} diff --git a/test/test_type_identifier.cpp b/test/test_type_identifier.cpp index b2b8c8c..ec9efd5 100644 --- a/test/test_type_identifier.cpp +++ b/test/test_type_identifier.cpp @@ -108,6 +108,12 @@ TEST(TypeIdentifierTest, PassThroughTypes) { [2] Container: std::allocator (size: 1) Param Primitive: int32_t + Underlying +[1] Class: std::allocator (size: 1) + Param + Primitive: int32_t + Function: allocate + Function: deallocate )"); } @@ -137,6 +143,12 @@ TEST(TypeIdentifierTest, PassThroughSameType) { [2] Container: std::allocator (size: 1) Param Primitive: int32_t + Underlying +[1] Class: std::allocator (size: 1) + Param + Primitive: int32_t + Function: allocate + Function: deallocate Param [2] )"); diff --git a/test/type_graph_utils.cpp b/test/type_graph_utils.cpp index 815a46a..2d5709f 100644 --- a/test/type_graph_utils.cpp +++ b/test/type_graph_utils.cpp @@ -86,22 +86,23 @@ std::vector> getContainerInfos() { Container getVector(NodeId id) { static ContainerInfo info{"std::vector", SEQ_TYPE, "vector"}; info.stubTemplateParams = {1}; - return Container{id, info, 24}; + return Container{id, info, 24, nullptr}; } Container getMap(NodeId id) { static ContainerInfo info{"std::map", STD_MAP_TYPE, "map"}; info.stubTemplateParams = {2, 3}; - return Container{id, info, 48}; + return Container{id, info, 48, nullptr}; } Container getList(NodeId id) { static ContainerInfo info{"std::list", LIST_TYPE, "list"}; info.stubTemplateParams = {1}; - return Container{id, info, 24}; + return Container{id, info, 24, nullptr}; } Container getPair(NodeId id) { static ContainerInfo info{"std::pair", PAIR_TYPE, "utility"}; - return Container{id, info, 8}; // Nonsense size, shouldn't matter for tests + return Container{ + id, info, 8, nullptr}; // Nonsense size, shouldn't matter for tests }