Coverage Report

Created: 2023-12-11 06:17

/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_