1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "annotation.h"
17
18 namespace panda::pandasm {
19
InitScalarValue(const ScalarValue &sc_val)20 std::unique_ptr<ScalarValue> InitScalarValue(const ScalarValue &sc_val)
21 {
22 std::unique_ptr<ScalarValue> copy_val;
23 switch (sc_val.GetType()) {
24 case Value::Type::U1: {
25 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::U1>(sc_val.GetValue<uint8_t>()));
26 break;
27 }
28 case Value::Type::U8: {
29 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::U8>(sc_val.GetValue<uint8_t>()));
30 break;
31 }
32 case Value::Type::U16: {
33 copy_val =
34 std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::U16>(sc_val.GetValue<uint16_t>()));
35 break;
36 }
37 case Value::Type::U32: {
38 copy_val =
39 std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::U32>(sc_val.GetValue<uint32_t>()));
40 break;
41 }
42 case Value::Type::U64: {
43 copy_val =
44 std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::U64>(sc_val.GetValue<uint64_t>()));
45 break;
46 }
47 case Value::Type::I8: {
48 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::I8>(sc_val.GetValue<int8_t>()));
49 break;
50 }
51 case Value::Type::I16: {
52 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::I16>(sc_val.GetValue<int16_t>()));
53 break;
54 }
55 case Value::Type::I32: {
56 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::I32>(sc_val.GetValue<int32_t>()));
57 break;
58 }
59 case Value::Type::I64: {
60 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::I64>(sc_val.GetValue<int64_t>()));
61 break;
62 }
63 case Value::Type::F32: {
64 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::F32>(sc_val.GetValue<float>()));
65 break;
66 }
67 case Value::Type::F64: {
68 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::F64>(sc_val.GetValue<double>()));
69 break;
70 }
71 case Value::Type::STRING: {
72 copy_val =
73 std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::STRING>(sc_val.GetValue<std::string>()));
74 break;
75 }
76 case Value::Type::STRING_NULLPTR: {
77 copy_val = std::make_unique<ScalarValue>(
78 ScalarValue::Create<Value::Type::STRING_NULLPTR>(sc_val.GetValue<int32_t>()));
79 break;
80 }
81 case Value::Type::RECORD: {
82 copy_val = std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::RECORD>(sc_val.GetValue<Type>()));
83 break;
84 }
85 case Value::Type::METHOD: {
86 copy_val =
87 std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::METHOD>(sc_val.GetValue<std::string>()));
88 break;
89 }
90 case Value::Type::ENUM: {
91 copy_val =
92 std::make_unique<ScalarValue>(ScalarValue::Create<Value::Type::ENUM>(sc_val.GetValue<std::string>()));
93 break;
94 }
95 case Value::Type::ANNOTATION: {
96 copy_val = std::make_unique<ScalarValue>(
97 ScalarValue::Create<Value::Type::ANNOTATION>(sc_val.GetValue<AnnotationData>()));
98 break;
99 }
100 case Value::Type::LITERALARRAY: {
101 copy_val = std::make_unique<ScalarValue>(
102 ScalarValue::Create<Value::Type::LITERALARRAY>(sc_val.GetValue<std::string>()));
103 break;
104 }
105 default: {
106 UNREACHABLE();
107 copy_val = nullptr;
108 break;
109 }
110 }
111 return copy_val;
112 }
113
making_value(const AnnotationElement &ann_elem)114 std::unique_ptr<Value> making_value(const AnnotationElement &ann_elem)
115 {
116 std::unique_ptr<Value> copy_val;
117 switch (ann_elem.GetValue()->GetType()) {
118 case Value::Type::U1:
119 case Value::Type::U8:
120 case Value::Type::U16:
121 case Value::Type::U32:
122 case Value::Type::U64:
123 case Value::Type::I8:
124 case Value::Type::I16:
125 case Value::Type::I32:
126 case Value::Type::I64:
127 case Value::Type::F32:
128 case Value::Type::F64:
129 case Value::Type::STRING:
130 case Value::Type::STRING_NULLPTR:
131 case Value::Type::RECORD:
132 case Value::Type::METHOD:
133 case Value::Type::ENUM:
134 case Value::Type::ANNOTATION:
135 case Value::Type::LITERALARRAY: {
136 copy_val = InitScalarValue(*static_cast<ScalarValue *>(ann_elem.GetValue()));
137 break;
138 }
139 case Value::Type::ARRAY: {
140 Value::Type c_type;
141 auto *elem_arr = static_cast<ArrayValue *>(ann_elem.GetValue());
142 if (elem_arr->GetValues().size() == 0) {
143 c_type = Value::Type::VOID;
144 } else {
145 c_type = elem_arr->GetValues().front().GetType();
146 }
147 std::vector<ScalarValue> sc_vals;
148 for (const auto &sc_val : elem_arr->GetValues()) {
149 sc_vals.push_back(*InitScalarValue(sc_val));
150 }
151 copy_val = std::make_unique<ArrayValue>(c_type, std::move(sc_vals));
152 break;
153 }
154 default: {
155 UNREACHABLE();
156 copy_val = nullptr;
157 break;
158 }
159 }
160 return copy_val;
161 }
162
AnnotationElement(const AnnotationElement &ann_elem)163 AnnotationElement::AnnotationElement(const AnnotationElement &ann_elem)
164 {
165 this->value_ = making_value(ann_elem);
166 this->name_ = ann_elem.GetName();
167 }
168
operator =(const AnnotationElement &ann_elem)169 AnnotationElement &AnnotationElement::operator=(const AnnotationElement &ann_elem)
170 {
171 if (this == &ann_elem) {
172 return *this;
173 }
174
175 this->value_ = making_value(ann_elem);
176 this->name_ = ann_elem.GetName();
177 return *this;
178 }
179
GetAsScalar()180 ScalarValue *Value::GetAsScalar()
181 {
182 ASSERT(!IsArray());
183 return static_cast<ScalarValue *>(this);
184 }
185
GetAsScalar() const186 const ScalarValue *Value::GetAsScalar() const
187 {
188 ASSERT(!IsArray());
189 return static_cast<const ScalarValue *>(this);
190 }
191
GetAsArray()192 ArrayValue *Value::GetAsArray()
193 {
194 ASSERT(IsArray());
195 return static_cast<ArrayValue *>(this);
196 }
197
GetAsArray() const198 const ArrayValue *Value::GetAsArray() const
199 {
200 ASSERT(IsArray());
201 return static_cast<const ArrayValue *>(this);
202 }
203
204 /* static */
TypeToString(Value::Type type)205 std::string AnnotationElement::TypeToString(Value::Type type)
206 {
207 switch (type) {
208 case Value::Type::U1:
209 return "u1";
210 case Value::Type::I8:
211 return "i8";
212 case Value::Type::U8:
213 return "u8";
214 case Value::Type::I16:
215 return "i16";
216 case Value::Type::U16:
217 return "u16";
218 case Value::Type::I32:
219 return "i32";
220 case Value::Type::U32:
221 return "u32";
222 case Value::Type::I64:
223 return "i64";
224 case Value::Type::U64:
225 return "u64";
226 case Value::Type::F32:
227 return "f32";
228 case Value::Type::F64:
229 return "f64";
230 case Value::Type::STRING:
231 return "string";
232 case Value::Type::RECORD:
233 return "class";
234 case Value::Type::METHOD:
235 return "method";
236 case Value::Type::ENUM:
237 return "enum";
238 case Value::Type::ANNOTATION:
239 return "annotation";
240 case Value::Type::ARRAY:
241 return "array";
242 case Value::Type::VOID:
243 return "void";
244 default: {
245 UNREACHABLE();
246 return "unknown";
247 }
248 }
249 }
250
SetOrAddElementByIndex(size_t ele_idx, AnnotationElement &&element)251 void AnnotationData::SetOrAddElementByIndex(size_t ele_idx, AnnotationElement &&element)
252 {
253 auto len = elements_.size();
254 ASSERT(ele_idx <= len);
255 if (ele_idx == len) {
256 AddElement(std::move(element));
257 return;
258 }
259 elements_[ele_idx] = std::forward<AnnotationElement>(element);
260 }
261
DeleteAnnotationElementByName(const std::string_view &annotation_elem_name)262 void AnnotationData::DeleteAnnotationElementByName(const std::string_view &annotation_elem_name)
263 {
264 auto annotation_elem_iter = std::find_if(elements_.begin(), elements_.end(),
265 [&](pandasm::AnnotationElement &annotation_element) -> bool {
266 return annotation_element.GetName() == annotation_elem_name;
267 });
268 if (annotation_elem_iter != elements_.end()) {
269 (void)elements_.erase(annotation_elem_iter);
270 }
271 }
272 } // namespace panda::pandasm
273