/proc/self/cwd/src/ir/attributes/attribute.h
Line | Count | Source (jump to first uncovered line) |
1 | | //----------------------------------------------------------------------------- |
2 | | // Copyright 2022 Google LLC |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | // you may not use this file except in compliance with the License. |
6 | | // You may obtain a copy of the License at |
7 | | // |
8 | | // https://www.apache.org/licenses/LICENSE-2.0 |
9 | | // |
10 | | // Unless required by applicable law or agreed to in writing, software |
11 | | // distributed under the License is distributed on an "AS IS" BASIS, |
12 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | // See the License for the specific language governing permissions and |
14 | | // limitations under the License. |
15 | | //---------------------------------------------------------------------------- |
16 | | #ifndef SRC_IR_ATTRIBUTES_ATTRIBUTE_H_ |
17 | | #define SRC_IR_ATTRIBUTES_ATTRIBUTE_H_ |
18 | | |
19 | | #include "absl/container/flat_hash_map.h" |
20 | | #include "absl/strings/str_format.h" |
21 | | #include "absl/strings/string_view.h" |
22 | | #include "src/common/utils/intrusive_ptr.h" |
23 | | |
24 | | namespace raksha::ir { |
25 | | |
26 | | // Base class for attributes associated with IR elements. |
27 | | class AttributeBase : public RefCounted<AttributeBase> { |
28 | | public: |
29 | | enum class Kind { kInt64, kString, kFloat }; |
30 | 0 | AttributeBase(Kind kind) : kind_(kind) {} |
31 | | |
32 | | // A polymorphic class should not be copyable/movable to prevent slicing. |
33 | | AttributeBase(const AttributeBase&) = delete; |
34 | | AttributeBase& operator=(const AttributeBase&) = delete; |
35 | | AttributeBase(AttributeBase&&) = delete; |
36 | | AttributeBase& operator=(AttributeBase&&) = delete; |
37 | 0 | virtual ~AttributeBase() {} |
38 | | |
39 | 0 | Kind kind() const { return kind_; } |
40 | | |
41 | | virtual bool IsEqual(const AttributeBase& other) const = 0; |
42 | | virtual std::string ToString() const = 0; |
43 | | |
44 | | private: |
45 | | Kind kind_; |
46 | | }; |
47 | | |
48 | | class Attribute { |
49 | | public: |
50 | | // Factory method to create attributes of the appropriate kind. This |
51 | | // forwards the arguments to the corresponding T::create method to |
52 | | // create the correct attribute. |
53 | | template <typename T, typename... Args, |
54 | | std::enable_if_t<std::is_convertible<T*, AttributeBase*>::value, |
55 | | bool> = true> |
56 | | static Attribute Create(Args&&... a) { |
57 | | return T::Create(std::forward<Args>(a)...); |
58 | | } |
59 | | |
60 | | // If this is of type `T` as identified by the `kind`, this method returns a |
61 | | // non-null value to the underlying attribute. Otherwise, returns nullptr. |
62 | | template <typename T> |
63 | | intrusive_ptr<const T> GetIf() const { |
64 | | return (T::kAttributeKind != value_->kind()) |
65 | | ? nullptr |
66 | | : static_cast<const T*>(value_.get()); |
67 | | } |
68 | | |
69 | | // Returns a string representation of the attribute. |
70 | 0 | std::string ToString() const { return value_->ToString(); } |
71 | | |
72 | | friend bool operator==(const Attribute& lhs, const Attribute& rhs); |
73 | | |
74 | | private: |
75 | | // Private constructor that allows us to construct an attribute from an |
76 | | // intrusive_ptr to any derived type of `AttributeBase`. |
77 | | template <class T, |
78 | | std::enable_if_t<std::is_convertible<T*, AttributeBase*>::value, |
79 | | bool> = true> |
80 | | Attribute(intrusive_ptr<const T> value) : value_(std::move(value)) { |
81 | | CHECK(value_ != nullptr); |
82 | | } |
83 | | |
84 | | intrusive_ptr<const AttributeBase> value_; |
85 | | }; |
86 | | |
87 | | // TODO(#336): This will simply become a pointer comparison when we canonicalize |
88 | | // the attributes. |
89 | 0 | inline bool operator==(const Attribute& lhs, const Attribute& rhs) { |
90 | 0 | CHECK(lhs.value_ != nullptr && rhs.value_ != nullptr); |
91 | 0 | if (lhs.value_ == rhs.value_) return true; |
92 | 0 | return lhs.value_->IsEqual(*rhs.value_); |
93 | 0 | } |
94 | | |
95 | | using NamedAttributeMap = absl::flat_hash_map<std::string, Attribute>; |
96 | | |
97 | | } // namespace raksha::ir |
98 | | |
99 | | #endif // SRC_IR_ATTRIBUTES_ATTRIBUTE_H_ |