diff options
author | Sid Nayyar <sidnayyar@google.com> | 2024-04-16 12:28:44 +0100 |
---|---|---|
committer | Giuliano Procida <gprocida@google.com> | 2024-04-25 22:05:56 +0100 |
commit | 5ef4e13addf4037dc4f83ebcd76e926fb59884d7 (patch) | |
tree | 4fe65a2e9ff661747e008d57d4b72a4084c70251 | |
parent | 577d950c95ddc21398c7b98373821232f5f931f7 (diff) | |
download | stg-5ef4e13addf4037dc4f83ebcd76e926fb59884d7.tar.gz |
rust: add `VariantMember` node
These nodes will be used to represent members of 'fieldful' or tagged
Rust enums.
STG Rust ABI representation is unstable and is not yet subject to
format versioning.
PiperOrigin-RevId: 625281842
Change-Id: I67a9a694c01d144b7942eef15921a5ca6050fccf
-rw-r--r-- | comparison.cc | 14 | ||||
-rw-r--r-- | comparison.h | 4 | ||||
-rw-r--r-- | equality.h | 8 | ||||
-rw-r--r-- | fidelity.cc | 7 | ||||
-rw-r--r-- | fingerprint.cc | 11 | ||||
-rw-r--r-- | graph.h | 22 | ||||
-rw-r--r-- | naming.cc | 8 | ||||
-rw-r--r-- | naming.h | 3 | ||||
-rw-r--r-- | proto_reader.cc | 12 | ||||
-rw-r--r-- | proto_writer.cc | 12 | ||||
-rw-r--r-- | stable_hash.cc | 10 | ||||
-rw-r--r-- | stable_hash.h | 3 | ||||
-rw-r--r-- | stg.proto | 22 | ||||
-rw-r--r-- | substitution.h | 6 | ||||
-rw-r--r-- | type_normalisation.cc | 6 | ||||
-rw-r--r-- | type_resolution.cc | 6 | ||||
-rw-r--r-- | unification.cc | 9 |
17 files changed, 141 insertions, 22 deletions
diff --git a/comparison.cc b/comparison.cc index ca821f9..d5067b6 100644 --- a/comparison.cc +++ b/comparison.cc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2020-2022 Google LLC +// Copyright 2020-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -454,6 +454,14 @@ Result Compare::operator()(const Member& x1, const Member& x2) { return result; } +Result Compare::operator()(const VariantMember& x1, const VariantMember& x2) { + Result result; + result.MaybeAddNodeDiff("discriminant", x1.discriminant_value, + x2.discriminant_value); + result.MaybeAddEdgeDiff("", (*this)(x1.type_id, x2.type_id)); + return result; +} + Result Compare::operator()(const StructUnion& x1, const StructUnion& x2) { Result result; // Compare two anonymous types recursively, not holding diffs. @@ -751,6 +759,10 @@ std::string MatchingKey::operator()(const Member& x) { return (*this)(x.type_id); } +std::string MatchingKey::operator()(const VariantMember& x) { + return x.name; +} + std::string MatchingKey::operator()(const StructUnion& x) { if (!x.name.empty()) { return x.name; diff --git a/comparison.h b/comparison.h index 693c55a..7d49803 100644 --- a/comparison.h +++ b/comparison.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2020-2023 Google LLC +// Copyright 2020-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -214,6 +214,7 @@ struct MatchingKey { std::string operator()(const BaseClass&); std::string operator()(const Method&); std::string operator()(const Member&); + std::string operator()(const VariantMember&); std::string operator()(const StructUnion&); template <typename Node> std::string operator()(const Node&); @@ -284,6 +285,7 @@ struct Compare { Result operator()(const BaseClass&, const BaseClass&); Result operator()(const Method&, const Method&); Result operator()(const Member&, const Member&); + Result operator()(const VariantMember&, const VariantMember&); Result operator()(const StructUnion&, const StructUnion&); Result operator()(const Enumeration&, const Enumeration&); Result operator()(const Function&, const Function&); @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2022 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -160,6 +160,12 @@ struct Equals { && (*this)(x1.type_id, x2.type_id); } + bool operator()(const VariantMember& x1, const VariantMember& x2) { + return x1.name == x2.name + && x1.discriminant_value == x2.discriminant_value + && (*this)(x1.type_id, x2.type_id); + } + bool operator()(const StructUnion& x1, const StructUnion& x2) { const auto& definition1 = x1.definition; const auto& definition2 = x2.definition; diff --git a/fidelity.cc b/fidelity.cc index 89c3c8c..250c9d9 100644 --- a/fidelity.cc +++ b/fidelity.cc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2023 Google LLC +// Copyright 2023-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -53,6 +53,7 @@ struct Fidelity { void operator()(const BaseClass&, Id); void operator()(const Method&, Id); void operator()(const Member&, Id); + void operator()(const VariantMember&, Id); void operator()(const StructUnion&, Id); void operator()(const Enumeration&, Id); void operator()(const Function&, Id); @@ -121,6 +122,10 @@ void Fidelity::operator()(const Member& x, Id) { (*this)(x.type_id); } +void Fidelity::operator()(const VariantMember& x, Id) { + (*this)(x.type_id); +} + void Fidelity::operator()(const StructUnion& x, Id id) { if (!x.name.empty()) { auto [it, _] = diff --git a/fingerprint.cc b/fingerprint.cc index b97b2ff..6f1c265 100644 --- a/fingerprint.cc +++ b/fingerprint.cc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2022 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -16,6 +16,7 @@ // limitations under the License. // // Author: Giuliano Procida +// Author: Siddharth Nayyar #include "fingerprint.h" @@ -92,6 +93,14 @@ struct Hasher { return hash('D', x.name, x.offset, (*this)(x.type_id)); } + HashValue operator()(const VariantMember& x) { + auto h = hash('m', x.name, (*this)(x.type_id)); + if (x.discriminant_value) { + h = hash(h, *x.discriminant_value); + } + return h; + } + HashValue operator()(const StructUnion& x) { auto h = hash('U', static_cast<uint32_t>(x.kind), x.name); if (x.definition.has_value()) { @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2020-2023 Google LLC +// Copyright 2020-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -195,6 +195,16 @@ struct Member { uint64_t bitsize; }; +struct VariantMember { + VariantMember(const std::string& name, + std::optional<int64_t> discriminant_value, Id type_id) + : name(name), discriminant_value(discriminant_value), type_id(type_id) {} + + std::string name; + std::optional<int64_t> discriminant_value; + Id type_id; +}; + struct StructUnion { enum class Kind { STRUCT, UNION }; struct Definition { @@ -363,6 +373,9 @@ class Graph { } else if constexpr (std::is_same_v<Node, Member>) { reference = {Which::MEMBER, member_.size()}; member_.emplace_back(std::forward<Args>(args)...); + } else if constexpr (std::is_same_v<Node, VariantMember>) { + reference = {Which::VARIANT_MEMBER, variant_member_.size()}; + variant_member_.emplace_back(std::forward<Args>(args)...); } else if constexpr (std::is_same_v<Node, StructUnion>) { reference = {Which::STRUCT_UNION, struct_union_.size()}; struct_union_.emplace_back(std::forward<Args>(args)...); @@ -440,6 +453,7 @@ class Graph { BASE_CLASS, METHOD, MEMBER, + VARIANT_MEMBER, STRUCT_UNION, ENUMERATION, FUNCTION, @@ -459,6 +473,7 @@ class Graph { std::vector<BaseClass> base_class_; std::vector<Method> method_; std::vector<Member> member_; + std::vector<VariantMember> variant_member_; std::vector<StructUnion> struct_union_; std::vector<Enumeration> enumeration_; std::vector<Function> function_; @@ -492,6 +507,8 @@ Result Graph::Apply(FunctionObject& function, Id id, Args&&... args) const { return function(method_[ix], std::forward<Args>(args)...); case Which::MEMBER: return function(member_[ix], std::forward<Args>(args)...); + case Which::VARIANT_MEMBER: + return function(variant_member_[ix], std::forward<Args>(args)...); case Which::STRUCT_UNION: return function(struct_union_[ix], std::forward<Args>(args)...); case Which::ENUMERATION: @@ -546,6 +563,9 @@ Result Graph::Apply2( case Which::MEMBER: return function(member_[ix1], member_[ix2], std::forward<Args>(args)...); + case Which::VARIANT_MEMBER: + return function(variant_member_[ix1], variant_member_[ix2], + std::forward<Args>(args)...); case Which::STRUCT_UNION: return function(struct_union_[ix1], struct_union_[ix2], std::forward<Args>(args)...); @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2020-2022 Google LLC +// Copyright 2020-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -189,6 +189,12 @@ Name Describe::operator()(const Member& x) { return description; } +Name Describe::operator()(const VariantMember& x) { + auto description = (*this)(x.type_id); + description = description.Add(Side::LEFT, Precedence::ATOMIC, x.name); + return description; +} + Name Describe::operator()(const StructUnion& x) { std::ostringstream os; os << x.kind << ' '; @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2020-2022 Google LLC +// Copyright 2020-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -68,6 +68,7 @@ struct Describe { Name operator()(const BaseClass&); Name operator()(const Method&); Name operator()(const Member&); + Name operator()(const VariantMember&); Name operator()(const StructUnion&); Name operator()(const Enumeration&); Name operator()(const Function&); diff --git a/proto_reader.cc b/proto_reader.cc index c7eacb7..88ec127 100644 --- a/proto_reader.cc +++ b/proto_reader.cc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2022 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -67,6 +67,7 @@ struct Transformer { void AddNode(const Member&); void AddNode(const StructUnion&); void AddNode(const Enumeration&); + void AddNode(const VariantMember&); void AddNode(const Function&); void AddNode(const ElfSymbol&); void AddNode(const Symbols&); @@ -111,6 +112,7 @@ Id Transformer::Transform(const proto::STG& x) { AddNodes(x.base_class()); AddNodes(x.method()); AddNodes(x.member()); + AddNodes(x.variant_member()); AddNodes(x.struct_union()); AddNodes(x.enumeration()); AddNodes(x.function()); @@ -192,6 +194,14 @@ void Transformer::AddNode(const Member& x) { x.bitsize()); } +void Transformer::AddNode(const VariantMember& x) { + const auto& discr_value = x.has_discriminant_value() + ? std::make_optional(x.discriminant_value()) + : std::nullopt; + AddNode<stg::VariantMember>(GetId(x.id()), x.name(), discr_value, + GetId(x.type_id())); +} + void Transformer::AddNode(const StructUnion& x) { if (x.has_definition()) { AddNode<stg::StructUnion>( diff --git a/proto_writer.cc b/proto_writer.cc index 694d65e..a4ee972 100644 --- a/proto_writer.cc +++ b/proto_writer.cc @@ -74,6 +74,7 @@ struct Transform { void operator()(const stg::BaseClass&, uint32_t); void operator()(const stg::Method&, uint32_t); void operator()(const stg::Member&, uint32_t); + void operator()(const stg::VariantMember&, uint32_t); void operator()(const stg::StructUnion&, uint32_t); void operator()(const stg::Enumeration&, uint32_t); void operator()(const stg::Function&, uint32_t); @@ -213,6 +214,17 @@ void Transform<MapId>::operator()(const stg::Member& x, uint32_t id) { } template <typename MapId> +void Transform<MapId>::operator()(const stg::VariantMember& x, uint32_t id) { + auto& variant_member = *stg.add_variant_member(); + variant_member.set_id(id); + variant_member.set_name(x.name); + if (x.discriminant_value) { + variant_member.set_discriminant_value(*x.discriminant_value); + } + variant_member.set_type_id((*this)(x.type_id)); +} + +template <typename MapId> void Transform<MapId>::operator()(const stg::StructUnion& x, uint32_t id) { auto& struct_union = *stg.add_struct_union(); struct_union.set_id(id); diff --git a/stable_hash.cc b/stable_hash.cc index 8621aed..725cf61 100644 --- a/stable_hash.cc +++ b/stable_hash.cc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2022 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -126,6 +126,14 @@ HashValue StableHash::operator()(const Member& x) { } } +HashValue StableHash::operator()(const VariantMember& x) { + HashValue hash = hash_('v', x.name); + hash = DecayHashCombine<8>(hash, (*this)(x.type_id)); + return x.discriminant_value + ? DecayHashCombine<20>(hash, hash_(*x.discriminant_value)) + : hash; +} + HashValue StableHash::operator()(const StructUnion& x) { HashValue hash = hash_('S', static_cast<uint32_t>(x.kind), x.name, static_cast<bool>(x.definition)); diff --git a/stable_hash.h b/stable_hash.h index 1732610..75cbb92 100644 --- a/stable_hash.h +++ b/stable_hash.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2022 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -45,6 +45,7 @@ class StableHash { HashValue operator()(const BaseClass&); HashValue operator()(const Method&); HashValue operator()(const Member&); + HashValue operator()(const VariantMember&); HashValue operator()(const StructUnion&); HashValue operator()(const Enumeration&); HashValue operator()(const Function&); @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: protobuffer -*- // -// Copyright 2022 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -158,6 +158,13 @@ message Member { uint64 bitsize = 5; } +message VariantMember { + fixed32 id = 1; + string name = 2; + optional int64 discriminant_value = 3; + fixed32 type_id = 4; +} + message StructUnion { enum Kind { KIND_UNSPECIFIED = 0; @@ -268,10 +275,11 @@ message STG { repeated BaseClass base_class = 12; repeated Method method = 13; repeated Member member = 14; - repeated StructUnion struct_union = 15; - repeated Enumeration enumeration = 16; - repeated Function function = 17; - repeated ElfSymbol elf_symbol = 18; - repeated Symbols symbols = 19; - repeated Interface interface = 20; + repeated VariantMember variant_member = 15; + repeated StructUnion struct_union = 16; + repeated Enumeration enumeration = 17; + repeated Function function = 18; + repeated ElfSymbol elf_symbol = 19; + repeated Symbols symbols = 20; + repeated Interface interface = 21; } diff --git a/substitution.h b/substitution.h index 67f74b4..de0dad0 100644 --- a/substitution.h +++ b/substitution.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2022 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -99,6 +99,10 @@ struct Substitute { Update(x.type_id); } + void operator()(VariantMember& x) { + Update(x.type_id); + } + void operator()(StructUnion& x) { if (x.definition.has_value()) { auto& definition = x.definition.value(); diff --git a/type_normalisation.cc b/type_normalisation.cc index 377198f..70b0493 100644 --- a/type_normalisation.cc +++ b/type_normalisation.cc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2023 Google LLC +// Copyright 2023-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -126,6 +126,10 @@ struct FindQualifiedTypesAndFunctions { (*this)(x.type_id); } + void operator()(const VariantMember& x, Id) { + (*this)(x.type_id); + } + void operator()(const StructUnion& x, Id) { if (x.definition.has_value()) { auto& definition = x.definition.value(); diff --git a/type_resolution.cc b/type_resolution.cc index 928332c..d28db66 100644 --- a/type_resolution.cc +++ b/type_resolution.cc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2022-2023 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -121,6 +121,10 @@ struct NamedTypes { (*this)(x.type_id); } + void operator()(const VariantMember& x, Id) { + (*this)(x.type_id); + } + void operator()(const StructUnion& x, Id id) { auto tag = x.kind == StructUnion::Kind::STRUCT ? Tag::STRUCT : Tag::UNION; const auto& name = x.name; diff --git a/unification.cc b/unification.cc index b48c2ee..77891ea 100644 --- a/unification.cc +++ b/unification.cc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -*- mode: C++ -*- // -// Copyright 2022-2023 Google LLC +// Copyright 2022-2024 Google LLC // // Licensed under the Apache License v2.0 with LLVM Exceptions (the // "License"); you may not use this file except in compliance with the @@ -170,6 +170,13 @@ struct Unifier { ? Right : Neither; } + Winner operator()(const VariantMember& x1, const VariantMember& x2) { + return x1.name == x2.name + && x1.discriminant_value == x2.discriminant_value + && (*this)(x1.type_id, x2.type_id) + ? Right : Neither; + } + Winner operator()(const StructUnion& x1, const StructUnion& x2) { const auto& definition1 = x1.definition; const auto& definition2 = x2.definition; |