blob: f7a5e49af830424746327e948b8d40f45029f7ba [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
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 * http://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
Andreas Huberc9410c72016-07-28 12:18:40 -070017#include "EnumType.h"
18
Andreas Huber019d21d2016-10-03 12:59:47 -070019#include "Annotation.h"
Andreas Huber881227d2016-08-02 14:20:21 -070020#include "ScalarType.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070021
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070022#include <inttypes.h>
23#include <hidl-util/Formatter.h>
Andreas Huber737080b2016-08-02 15:38:04 -070024#include <android-base/logging.h>
25
Andreas Huberc9410c72016-07-28 12:18:40 -070026namespace android {
27
Andreas Huberc9410c72016-07-28 12:18:40 -070028EnumType::EnumType(
Andreas Huber9ed827c2016-08-22 12:31:13 -070029 const char *localName,
Yifan Honga4b53d02016-10-31 17:29:10 -070030 const Location &location,
Andreas Huber9ed827c2016-08-22 12:31:13 -070031 Type *storageType)
Yifan Honga4b53d02016-10-31 17:29:10 -070032 : Scope(localName, location),
Yifan Hongf24fa852016-09-23 11:03:15 -070033 mValues(),
Steven Moreland1c71fd52016-11-29 14:03:33 -080034 mStorageType(storageType) {
Andreas Huberc9410c72016-07-28 12:18:40 -070035}
36
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070037const Type *EnumType::storageType() const {
38 return mStorageType;
39}
40
41const std::vector<EnumValue *> &EnumType::values() const {
Yifan Hongf24fa852016-09-23 11:03:15 -070042 return mValues;
43}
44
45void EnumType::addValue(EnumValue *value) {
46 CHECK(value != nullptr);
47
48 EnumValue *prev = nullptr;
49 std::vector<const EnumType *> chain;
50 getTypeChain(&chain);
51 for (auto it = chain.begin(); it != chain.end(); ++it) {
52 const auto &type = *it;
53 if(!type->values().empty()) {
54 prev = type->values().back();
55 break;
56 }
57 }
58
59 value->autofill(prev, resolveToScalarType());
60 mValues.push_back(value);
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070061}
62
Steven Moreland9df52442016-12-12 08:51:14 -080063bool EnumType::isElidableType() const {
64 return mStorageType->isElidableType();
65}
66
Andreas Huber737080b2016-08-02 15:38:04 -070067const ScalarType *EnumType::resolveToScalarType() const {
68 return mStorageType->resolveToScalarType();
69}
70
Steven Moreland30bb6a82016-11-30 09:18:34 -080071std::string EnumType::typeName() const {
72 return "enum " + localName();
73}
74
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070075bool EnumType::isEnum() const {
76 return true;
77}
78
Steven Moreland979e0992016-09-07 09:18:08 -070079std::string EnumType::getCppType(StorageMode,
Steven Moreland979e0992016-09-07 09:18:08 -070080 bool specifyNamespaces) const {
Steven Moreland979e0992016-09-07 09:18:08 -070081 return specifyNamespaces ? fullName() : partialCppName();
Andreas Huber881227d2016-08-02 14:20:21 -070082}
83
Yifan Hong4ed13472016-11-02 10:44:11 -070084std::string EnumType::getJavaType(bool forInitializer) const {
85 return mStorageType->resolveToScalarType()->getJavaType(forInitializer);
Andreas Huber2831d512016-08-15 09:33:47 -070086}
87
88std::string EnumType::getJavaSuffix() const {
89 return mStorageType->resolveToScalarType()->getJavaSuffix();
90}
91
Andreas Hubera3558b32016-09-14 09:12:42 -070092std::string EnumType::getJavaWrapperType() const {
93 return mStorageType->resolveToScalarType()->getJavaWrapperType();
94}
95
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -070096std::string EnumType::getVtsType() const {
97 return "TYPE_ENUM";
98}
99
Yifan Hongf24fa852016-09-23 11:03:15 -0700100LocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
101 std::vector<const EnumType *> chain;
102 getTypeChain(&chain);
103 for (auto it = chain.begin(); it != chain.end(); ++it) {
104 const auto &type = *it;
105 for(EnumValue *v : type->values()) {
106 if(v->name() == name) {
107 return v;
108 }
109 }
110 }
111 return nullptr;
112}
113
Andreas Huber881227d2016-08-02 14:20:21 -0700114void EnumType::emitReaderWriter(
115 Formatter &out,
116 const std::string &name,
117 const std::string &parcelObj,
118 bool parcelObjIsPointer,
119 bool isReader,
120 ErrorMode mode) const {
Andreas Huber737080b2016-08-02 15:38:04 -0700121 const ScalarType *scalarType = mStorageType->resolveToScalarType();
122 CHECK(scalarType != NULL);
123
124 scalarType->emitReaderWriterWithCast(
125 out,
126 name,
127 parcelObj,
128 parcelObjIsPointer,
129 isReader,
130 mode,
131 true /* needsCast */);
Andreas Huber881227d2016-08-02 14:20:21 -0700132}
133
Andreas Huber85eabdb2016-08-25 11:24:49 -0700134void EnumType::emitJavaFieldReaderWriter(
135 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700136 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700137 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700138 const std::string &blobName,
139 const std::string &fieldName,
140 const std::string &offset,
141 bool isReader) const {
142 return mStorageType->emitJavaFieldReaderWriter(
Andreas Huber709b62d2016-09-19 11:21:18 -0700143 out, depth, parcelName, blobName, fieldName, offset, isReader);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700144}
145
Andreas Huber881227d2016-08-02 14:20:21 -0700146status_t EnumType::emitTypeDeclarations(Formatter &out) const {
Andreas Huber737080b2016-08-02 15:38:04 -0700147 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Andreas Hubere3f769a2016-10-10 10:54:44 -0700148 CHECK(scalarType != nullptr);
Andreas Huber737080b2016-08-02 15:38:04 -0700149
Yifan Hong3b320f82016-11-01 15:15:54 -0700150 const std::string storageType = scalarType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700151
152 out << "enum class "
Andreas Huber0e00de42016-08-03 09:56:02 -0700153 << localName()
Andreas Huber881227d2016-08-02 14:20:21 -0700154 << " : "
Andreas Hubere3f769a2016-10-10 10:54:44 -0700155 << storageType
Andreas Huber881227d2016-08-02 14:20:21 -0700156 << " {\n";
157
158 out.indent();
159
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700160 std::vector<const EnumType *> chain;
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700161 getTypeChain(&chain);
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700162
163 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
164 const auto &type = *it;
165
166 for (const auto &entry : type->values()) {
167 out << entry->name();
168
Yifan Hongfc610cd2016-09-22 13:34:45 -0700169 std::string value = entry->cppValue(scalarType->getKind());
Yifan Hongf24fa852016-09-23 11:03:15 -0700170 CHECK(!value.empty()); // use autofilled values for c++.
171 out << " = " << value;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700172
Yifan Hong57886972016-08-17 10:42:15 -0700173 out << ",";
174
Yifan Hongfc610cd2016-09-22 13:34:45 -0700175 std::string comment = entry->comment();
176 if (!comment.empty() && comment != value) {
Yifan Hong57886972016-08-17 10:42:15 -0700177 out << " // " << comment;
178 }
179
180 out << "\n";
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700181 }
Andreas Huber881227d2016-08-02 14:20:21 -0700182 }
183
184 out.unindent();
185 out << "};\n\n";
186
187 return OK;
188}
189
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800190void EnumType::emitEnumBitwiseOperator(
191 Formatter &out,
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800192 bool lhsIsEnum,
193 bool rhsIsEnum,
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800194 const std::string &op) const {
Andreas Hubere3f769a2016-10-10 10:54:44 -0700195 const ScalarType *scalarType = mStorageType->resolveToScalarType();
196 CHECK(scalarType != nullptr);
197
Yifan Hong3b320f82016-11-01 15:15:54 -0700198 const std::string storageType = scalarType->getCppStackType();
Andreas Hubere3f769a2016-10-10 10:54:44 -0700199
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800200 out << "constexpr "
201 << storageType
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800202 << " operator"
203 << op
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800204 << "(const "
205 << (lhsIsEnum ? fullName() : storageType)
206 << " lhs, const "
207 << (rhsIsEnum ? fullName() : storageType)
Andreas Hubere3f769a2016-10-10 10:54:44 -0700208 << " rhs) {\n";
Andreas Hubere3f769a2016-10-10 10:54:44 -0700209
Yifan Hong33223ca2016-12-13 15:07:35 -0800210 out.indent([&] {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800211 out << "return static_cast<"
212 << storageType
213 << ">(";
Andreas Hubere3f769a2016-10-10 10:54:44 -0700214
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800215 if (lhsIsEnum) {
216 out << "static_cast<"
217 << storageType
218 << ">(lhs)";
219 } else {
220 out << "lhs";
221 }
222 out << " " << op << " ";
223 if (rhsIsEnum) {
224 out << "static_cast<"
225 << storageType
226 << ">(rhs)";
227 } else {
228 out << "rhs";
229 }
230 out << ");\n";
231 });
Andreas Hubere3f769a2016-10-10 10:54:44 -0700232
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800233 out << "}\n\n";
234}
235
236void EnumType::emitBitFieldBitwiseAssignmentOperator(
237 Formatter &out,
238 const std::string &op) const {
239 const ScalarType *scalarType = mStorageType->resolveToScalarType();
240 CHECK(scalarType != nullptr);
241
242 const std::string storageType = scalarType->getCppStackType();
243
244 out << "constexpr " << storageType << " &operator" << op << "=("
245 << storageType << "& v, const " << fullName() << " e) {\n";
246
Yifan Hong33223ca2016-12-13 15:07:35 -0800247 out.indent([&] {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800248 out << "v " << op << "= static_cast<" << storageType << ">(e);\n";
249 out << "return v;\n";
250 });
Andreas Hubere3f769a2016-10-10 10:54:44 -0700251
252 out << "}\n\n";
253}
254
255status_t EnumType::emitGlobalTypeDeclarations(Formatter &out) const {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800256 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, true /* rhsIsEnum */, "|");
257 emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true /* rhsIsEnum */, "|");
258 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, false /* rhsIsEnum */, "|");
259 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, true /* rhsIsEnum */, "&");
260 emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true /* rhsIsEnum */, "&");
261 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, false /* rhsIsEnum */, "&");
262
263 emitBitFieldBitwiseAssignmentOperator(out, "|");
264 emitBitFieldBitwiseAssignmentOperator(out, "&");
Andreas Hubere3f769a2016-10-10 10:54:44 -0700265
266 return OK;
267}
268
Andreas Huber85eabdb2016-08-25 11:24:49 -0700269status_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool) const {
Andreas Huber2831d512016-08-15 09:33:47 -0700270 const ScalarType *scalarType = mStorageType->resolveToScalarType();
271 CHECK(scalarType != NULL);
272
273 out << "public final class "
274 << localName()
275 << " {\n";
276
277 out.indent();
278
Andreas Huber4c865b72016-09-14 15:26:27 -0700279 const std::string typeName =
Yifan Hong4ed13472016-11-02 10:44:11 -0700280 scalarType->getJavaType(false /* forInitializer */);
Andreas Huber2831d512016-08-15 09:33:47 -0700281
282 std::vector<const EnumType *> chain;
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700283 getTypeChain(&chain);
Andreas Huber2831d512016-08-15 09:33:47 -0700284
285 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
286 const auto &type = *it;
287
288 for (const auto &entry : type->values()) {
289 out << "public static final "
290 << typeName
291 << " "
Andreas Huberab647c02016-09-14 09:44:00 -0700292 << entry->name()
293 << " = ";
Andreas Huber2831d512016-08-15 09:33:47 -0700294
Yifan Hongf24fa852016-09-23 11:03:15 -0700295 // javaValue will make the number signed.
Yifan Hongfc610cd2016-09-22 13:34:45 -0700296 std::string value = entry->javaValue(scalarType->getKind());
Yifan Hongf24fa852016-09-23 11:03:15 -0700297 CHECK(!value.empty()); // use autofilled values for java.
298 out << value;
Andreas Huber2831d512016-08-15 09:33:47 -0700299
Yifan Hong19ca75a2016-08-31 10:20:03 -0700300 out << ";";
301
Yifan Hongfc610cd2016-09-22 13:34:45 -0700302 std::string comment = entry->comment();
303 if (!comment.empty() && comment != value) {
Yifan Hong19ca75a2016-08-31 10:20:03 -0700304 out << " // " << comment;
305 }
306
307 out << "\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700308 }
309 }
310
311 out.unindent();
312 out << "};\n\n";
313
314 return OK;
315}
316
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700317status_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
Yifan Hongc07b2022016-11-08 12:44:24 -0800318 const ScalarType *scalarType = mStorageType->resolveToScalarType();
319
Zhuoyao Zhangbf828c82016-10-26 14:15:10 -0700320 out << "name: \"" << fullName() << "\"\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700321 out << "type: " << getVtsType() << "\n";
322 out << "enum_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700323 out.indent();
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700324
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700325 out << "scalar_type: \""
Yifan Hongc07b2022016-11-08 12:44:24 -0800326 << scalarType->getVtsScalarType()
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700327 << "\"\n\n";
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700328 std::vector<const EnumType *> chain;
329 getTypeChain(&chain);
330
331 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
332 const auto &type = *it;
333
334 for (const auto &entry : type->values()) {
335 out << "enumerator: \"" << entry->name() << "\"\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700336 out << "scalar_value: {\n";
337 out.indent();
Yifan Hongc07b2022016-11-08 12:44:24 -0800338 // use autofilled values for vts.
339 std::string value = entry->value(scalarType->getKind());
340 CHECK(!value.empty());
341 out << mStorageType->resolveToScalarType()->getVtsScalarType()
342 << ": "
343 << value
344 << "\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700345 out.unindent();
346 out << "}\n";
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700347 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700348 }
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700349
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700350 out.unindent();
351 out << "}\n";
352 return OK;
353}
354
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700355status_t EnumType::emitVtsAttributeType(Formatter &out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700356 out << "type: " << getVtsType() << "\n";
Zhuoyao Zhangbf828c82016-10-26 14:15:10 -0700357 out << "predefined_type: \"" << fullName() << "\"\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700358 return OK;
359}
360
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700361void EnumType::getTypeChain(std::vector<const EnumType *> *out) const {
362 out->clear();
363 const EnumType *type = this;
364 for (;;) {
365 out->push_back(type);
366
367 const Type *superType = type->storageType();
368 if (superType == NULL || !superType->isEnum()) {
369 break;
370 }
371
372 type = static_cast<const EnumType *>(superType);
373 }
374}
375
Andreas Huber85eabdb2016-08-25 11:24:49 -0700376void EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
377 mStorageType->getAlignmentAndSize(align, size);
378}
379
Andreas Huber019d21d2016-10-03 12:59:47 -0700380const Annotation *EnumType::findExportAnnotation() const {
381 for (const auto &annotation : annotations()) {
382 if (annotation->name() == "export") {
383 return annotation;
384 }
385 }
386
387 return nullptr;
388}
389
390void EnumType::appendToExportedTypesVector(
391 std::vector<const Type *> *exportedTypes) const {
392 if (findExportAnnotation() != nullptr) {
393 exportedTypes->push_back(this);
394 }
395}
396
Andreas Huber1c507272016-10-05 14:33:21 -0700397status_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
Andreas Huber019d21d2016-10-03 12:59:47 -0700398 const Annotation *annotation = findExportAnnotation();
399 CHECK(annotation != nullptr);
400
401 std::string name = localName();
402
403 const AnnotationParam *nameParam = annotation->getParam("name");
404 if (nameParam != nullptr) {
405 CHECK_EQ(nameParam->getValues()->size(), 1u);
406
407 std::string quotedString = nameParam->getValues()->at(0);
408 name = quotedString.substr(1, quotedString.size() - 2);
409 }
410
Andreas Huberb0627fb2016-10-10 09:39:28 -0700411 std::string valuePrefix;
Andreas Huberb0627fb2016-10-10 09:39:28 -0700412 const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
413 if (prefixParam != nullptr) {
414 CHECK_EQ(prefixParam->getValues()->size(), 1u);
415
416 std::string quotedString = prefixParam->getValues()->at(0);
417 valuePrefix = quotedString.substr(1, quotedString.size() - 2);
418 }
419
Steven Moreland73cdc882016-11-21 16:43:50 -0800420 std::string valueSuffix;
421 const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
422 if (suffixParam != nullptr) {
423 CHECK_EQ(suffixParam->getValues()->size(), 1u);
424
425 std::string quotedString = suffixParam->getValues()->at(0);
426 valueSuffix = quotedString.substr(1, quotedString.size() - 2);
427 }
428
Andreas Huber019d21d2016-10-03 12:59:47 -0700429 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Andreas Huber1c507272016-10-05 14:33:21 -0700430 CHECK(scalarType != nullptr);
Andreas Huber019d21d2016-10-03 12:59:47 -0700431
Andreas Huber1c507272016-10-05 14:33:21 -0700432 if (forJava) {
433 if (!name.empty()) {
434 out << "public final class "
435 << name
436 << " {\n";
437
438 out.indent();
439 } else {
440 out << "// Values declared in " << localName() << " follow.\n";
441 }
442
Andreas Huber1c507272016-10-05 14:33:21 -0700443 const std::string typeName =
Yifan Hong4ed13472016-11-02 10:44:11 -0700444 scalarType->getJavaType(false /* forInitializer */);
Andreas Huber1c507272016-10-05 14:33:21 -0700445
446 std::vector<const EnumType *> chain;
447 getTypeChain(&chain);
448
449 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
450 const auto &type = *it;
451
452 for (const auto &entry : type->values()) {
453 out << "public static final "
454 << typeName
455 << " "
456 << valuePrefix
457 << entry->name()
Steven Moreland73cdc882016-11-21 16:43:50 -0800458 << valueSuffix
Andreas Huber1c507272016-10-05 14:33:21 -0700459 << " = ";
460
461 // javaValue will make the number signed.
462 std::string value = entry->javaValue(scalarType->getKind());
463 CHECK(!value.empty()); // use autofilled values for java.
464 out << value;
465
466 out << ";";
467
468 std::string comment = entry->comment();
469 if (!comment.empty() && comment != value) {
470 out << " // " << comment;
471 }
472
473 out << "\n";
474 }
475 }
476
477 if (!name.empty()) {
478 out.unindent();
479 out << "};\n";
480 }
481 out << "\n";
482
483 return OK;
484 }
Andreas Huber019d21d2016-10-03 12:59:47 -0700485
486 if (!name.empty()) {
487 out << "typedef ";
488 }
489
490 out << "enum {\n";
491
492 out.indent();
493
494 std::vector<const EnumType *> chain;
495 getTypeChain(&chain);
496
497 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
498 const auto &type = *it;
499
500 for (const auto &entry : type->values()) {
Steven Moreland73cdc882016-11-21 16:43:50 -0800501 out << valuePrefix << entry->name() << valueSuffix;
Andreas Huber019d21d2016-10-03 12:59:47 -0700502
503 std::string value = entry->cppValue(scalarType->getKind());
504 CHECK(!value.empty()); // use autofilled values for c++.
505 out << " = " << value;
506
507 out << ",";
508
509 std::string comment = entry->comment();
510 if (!comment.empty() && comment != value) {
511 out << " // " << comment;
512 }
513
514 out << "\n";
515 }
516 }
517
518 out.unindent();
519 out << "}";
520
521 if (!name.empty()) {
522 out << " " << name;
523 }
524
525 out << ";\n\n";
526
527 return OK;
528}
529
Andreas Huber31629bc2016-08-03 09:06:40 -0700530////////////////////////////////////////////////////////////////////////////////
531
Yifan Hongf24fa852016-09-23 11:03:15 -0700532EnumValue::EnumValue(const char *name, ConstantExpression *value)
Andreas Huber31629bc2016-08-03 09:06:40 -0700533 : mName(name),
Yifan Hongf24fa852016-09-23 11:03:15 -0700534 mValue(value),
535 mIsAutoFill(false) {
Andreas Huber31629bc2016-08-03 09:06:40 -0700536}
537
538std::string EnumValue::name() const {
539 return mName;
540}
541
Yifan Hongc07b2022016-11-08 12:44:24 -0800542std::string EnumValue::value(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700543 CHECK(mValue != nullptr);
Yifan Hongc07b2022016-11-08 12:44:24 -0800544 return mValue->value(castKind);
Yifan Hong57886972016-08-17 10:42:15 -0700545}
546
Yifan Hongfc610cd2016-09-22 13:34:45 -0700547std::string EnumValue::cppValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700548 CHECK(mValue != nullptr);
549 return mValue->cppValue(castKind);
Yifan Hong57886972016-08-17 10:42:15 -0700550}
Yifan Hongfc610cd2016-09-22 13:34:45 -0700551std::string EnumValue::javaValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700552 CHECK(mValue != nullptr);
553 return mValue->javaValue(castKind);
Yifan Hong19ca75a2016-08-31 10:20:03 -0700554}
Yifan Hong57886972016-08-17 10:42:15 -0700555
Yifan Hongfc610cd2016-09-22 13:34:45 -0700556std::string EnumValue::comment() const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700557 CHECK(mValue != nullptr);
558 return mValue->description();
559}
560
561ConstantExpression *EnumValue::constExpr() const {
562 CHECK(mValue != nullptr);
563 return mValue;
564}
565
566void EnumValue::autofill(const EnumValue *prev, const ScalarType *type) {
567 if(mValue != nullptr)
568 return;
569 mIsAutoFill = true;
570 ConstantExpression *value = new ConstantExpression();
571 if(prev == nullptr) {
572 *value = ConstantExpression::Zero(type->getKind());
573 } else {
574 CHECK(prev->mValue != nullptr);
575 *value = prev->mValue->addOne();
576 }
577 mValue = value;
578}
579
580bool EnumValue::isAutoFill() const {
581 return mIsAutoFill;
582}
583
584bool EnumValue::isEnumValue() const {
585 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700586}
587
Yifan Hongabf73ee2016-12-05 18:47:00 -0800588////////////////////////////////////////////////////////////////////////////////
589
590bool BitFieldType::isBitField() const {
591 return true;
592}
593
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800594std::string BitFieldType::typeName() const {
595 return "mask" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
596}
597
598void BitFieldType::addNamedTypesToSet(std::set<const FQName> &) const {
599}
600
601bool BitFieldType::isCompatibleElementType(Type *elementType) const {
602 return elementType->isEnum();
603}
604
605const ScalarType *BitFieldType::resolveToScalarType() const {
606 return mElementType->resolveToScalarType();
607}
608
609std::string BitFieldType::getCppType(StorageMode mode,
610 bool specifyNamespaces) const {
611 return resolveToScalarType()->getCppType(mode, specifyNamespaces);
612}
613
614std::string BitFieldType::getJavaType(bool forInitializer) const {
615 return resolveToScalarType()->getJavaType(forInitializer);
616}
617
618std::string BitFieldType::getJavaSuffix() const {
619 return resolveToScalarType()->getJavaSuffix();
620}
621
622std::string BitFieldType::getJavaWrapperType() const {
623 return resolveToScalarType()->getJavaWrapperType();
624}
625
626std::string BitFieldType::getVtsType() const {
627 return "TYPE_MASK";
628}
629
Yifan Hong8c56cbe2016-12-12 15:30:12 -0800630bool BitFieldType::isElidableType() const {
631 return resolveToScalarType()->isElidableType();
632}
633
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800634status_t BitFieldType::emitVtsTypeDeclarations(Formatter &out) const {
635 out << "type: " << getVtsType() << "\n";
636 out << "enum_value: {\n";
637 out.indent();
638 status_t err = mElementType->emitVtsTypeDeclarations(out);
639 if (err != OK) {
640 return err;
641 }
642 out.unindent();
643 out << "}\n";
644 return OK;
645}
646
647status_t BitFieldType::emitVtsAttributeType(Formatter &out) const {
648 out << "type: " << getVtsType() << "\n";
649 out << "enum_value: {\n";
650 out.indent();
651 status_t err = mElementType->emitVtsAttributeType(out);
652 if (err != OK) {
653 return err;
654 }
655 out.unindent();
656 out << "}\n";
657 return OK;
658}
659
660void BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
661 resolveToScalarType()->getAlignmentAndSize(align, size);
662}
663
664void BitFieldType::emitReaderWriter(
665 Formatter &out,
666 const std::string &name,
667 const std::string &parcelObj,
668 bool parcelObjIsPointer,
669 bool isReader,
670 ErrorMode mode) const {
671 resolveToScalarType()->emitReaderWriterWithCast(
672 out,
673 name,
674 parcelObj,
675 parcelObjIsPointer,
676 isReader,
677 mode,
678 true /* needsCast */);
679}
680
681void BitFieldType::emitJavaFieldReaderWriter(
682 Formatter &out,
683 size_t depth,
684 const std::string &parcelName,
685 const std::string &blobName,
686 const std::string &fieldName,
687 const std::string &offset,
688 bool isReader) const {
689 return resolveToScalarType()->emitJavaFieldReaderWriter(
690 out, depth, parcelName, blobName, fieldName, offset, isReader);
691}
692
Andreas Huberc9410c72016-07-28 12:18:40 -0700693} // namespace android
694