aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSid Nayyar <sidnayyar@google.com>2024-04-16 12:28:44 +0100
committerGiuliano Procida <gprocida@google.com>2024-04-25 22:05:56 +0100
commit5ef4e13addf4037dc4f83ebcd76e926fb59884d7 (patch)
tree4fe65a2e9ff661747e008d57d4b72a4084c70251
parent577d950c95ddc21398c7b98373821232f5f931f7 (diff)
downloadstg-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.cc14
-rw-r--r--comparison.h4
-rw-r--r--equality.h8
-rw-r--r--fidelity.cc7
-rw-r--r--fingerprint.cc11
-rw-r--r--graph.h22
-rw-r--r--naming.cc8
-rw-r--r--naming.h3
-rw-r--r--proto_reader.cc12
-rw-r--r--proto_writer.cc12
-rw-r--r--stable_hash.cc10
-rw-r--r--stable_hash.h3
-rw-r--r--stg.proto22
-rw-r--r--substitution.h6
-rw-r--r--type_normalisation.cc6
-rw-r--r--type_resolution.cc6
-rw-r--r--unification.cc9
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&);
diff --git a/equality.h b/equality.h
index 77cd1a4..6fb4e72 100644
--- a/equality.h
+++ b/equality.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
@@ -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()) {
diff --git a/graph.h b/graph.h
index d57128c..bb51625 100644
--- a/graph.h
+++ b/graph.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
@@ -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)...);
diff --git a/naming.cc b/naming.cc
index f386dce..c30de56 100644
--- a/naming.cc
+++ b/naming.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
@@ -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 << ' ';
diff --git a/naming.h b/naming.h
index 163627f..0e5c3a1 100644
--- a/naming.h
+++ b/naming.h
@@ -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&);
diff --git a/stg.proto b/stg.proto
index 6f5ce91..9c21d81 100644
--- a/stg.proto
+++ b/stg.proto
@@ -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;