blob: 3268264575b440e85a49bd5076d753e7499ca8ed [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
Timur Iskhakovcec46c42017-08-09 00:22:02 -070019#include <hidl-util/Formatter.h>
20#include <inttypes.h>
Timur Iskhakove8ee6a02017-09-06 11:42:10 -070021#include <iostream>
Timur Iskhakovcec46c42017-08-09 00:22:02 -070022#include <unordered_map>
23
Andreas Huber019d21d2016-10-03 12:59:47 -070024#include "Annotation.h"
Timur Iskhakov505316c2017-08-05 03:38:59 +000025#include "Location.h"
Andreas Huber881227d2016-08-02 14:20:21 -070026#include "ScalarType.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070027
28namespace android {
29
Timur Iskhakov565b0132017-09-06 18:07:11 -070030EnumType::EnumType(const char* localName, const FQName& fullName, const Location& location,
Timur Iskhakov505316c2017-08-05 03:38:59 +000031 const Reference<Type>& storageType, Scope* parent)
Yifan Hongc14dd6e2017-09-15 13:39:58 -070032 : Scope(localName, fullName, location, parent), mValues(), mStorageType(storageType) {}
Andreas Huberc9410c72016-07-28 12:18:40 -070033
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070034const Type *EnumType::storageType() const {
Timur Iskhakovb3f8bcb2017-08-30 15:33:29 -070035 return mStorageType.get();
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070036}
37
38const std::vector<EnumValue *> &EnumType::values() const {
Yifan Hongf24fa852016-09-23 11:03:15 -070039 return mValues;
40}
41
Yifan Hong0a9cc862017-10-06 16:21:55 -070042void EnumType::forEachValueFromRoot(const std::function<void(EnumValue*)> f) const {
43 std::vector<const EnumType*> chain = typeChain();
44 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
45 const auto& type = *it;
46 for (EnumValue* v : type->values()) {
47 f(v);
48 }
49 }
50}
51
Steven Moreland12f0ab12018-11-02 17:27:37 -070052size_t EnumType::numValueNames() const {
53 size_t count = 0;
54 for (const auto it : typeChain()) {
55 count += it->values().size();
56 }
57 return count;
58}
59
Timur Iskhakovcec46c42017-08-09 00:22:02 -070060void EnumType::addValue(EnumValue* value) {
Yifan Hongf24fa852016-09-23 11:03:15 -070061 CHECK(value != nullptr);
Timur Iskhakovcec46c42017-08-09 00:22:02 -070062 mValues.push_back(value);
63}
Yifan Hongf24fa852016-09-23 11:03:15 -070064
Timur Iskhakovcec46c42017-08-09 00:22:02 -070065status_t EnumType::resolveInheritance() {
66 const EnumType* prevType = nullptr;
67 EnumValue* prevValue = nullptr;
68
69 for (const auto* type : superTypeChain()) {
70 if (!type->values().empty()) {
71 prevType = type;
72 prevValue = type->values().back();
Yifan Hongf24fa852016-09-23 11:03:15 -070073 break;
74 }
75 }
76
Timur Iskhakovcec46c42017-08-09 00:22:02 -070077 for (auto* value : mValues) {
78 value->autofill(prevType, prevValue, mStorageType->resolveToScalarType());
79 prevType = this;
80 prevValue = value;
81 }
82
83 return Scope::resolveInheritance();
84}
85
Timur Iskhakovb58f4182017-08-29 15:19:24 -070086std::vector<const Reference<Type>*> EnumType::getReferences() const {
87 return {&mStorageType};
Timur Iskhakov33431e62017-08-21 17:31:23 -070088}
Timur Iskhakovcec46c42017-08-09 00:22:02 -070089
Timur Iskhakovb58f4182017-08-29 15:19:24 -070090std::vector<const ConstantExpression*> EnumType::getConstantExpressions() const {
91 std::vector<const ConstantExpression*> ret;
Timur Iskhakov891a8662017-08-25 21:53:48 -070092 for (const auto* value : mValues) {
93 ret.push_back(value->constExpr());
Timur Iskhakovcec46c42017-08-09 00:22:02 -070094 }
Timur Iskhakov891a8662017-08-25 21:53:48 -070095 return ret;
Timur Iskhakovcec46c42017-08-09 00:22:02 -070096}
97
98status_t EnumType::validate() const {
Timur Iskhakova15f8092017-08-18 16:31:21 -070099 CHECK(getSubTypes().empty());
100
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700101 if (!isElidableType() || !mStorageType->isValidEnumStorageType()) {
102 std::cerr << "ERROR: Invalid enum storage type (" << (mStorageType)->typeName()
103 << ") specified at " << mStorageType.location() << "\n";
104 return UNKNOWN_ERROR;
105 }
106
Timur Iskhakov33431e62017-08-21 17:31:23 -0700107 status_t err = validateUniqueNames();
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700108 if (err != OK) return err;
109
110 return Scope::validate();
111}
112
113status_t EnumType::validateUniqueNames() const {
114 std::unordered_map<std::string, const EnumType*> registeredValueNames;
115 for (const auto* type : superTypeChain()) {
116 for (const auto* enumValue : type->mValues) {
117 // No need to check super value uniqueness
118 registeredValueNames[enumValue->name()] = type;
119 }
120 }
121
122 for (const auto* value : mValues) {
123 auto registered = registeredValueNames.find(value->name());
124
125 if (registered != registeredValueNames.end()) {
126 const EnumType* definedInType = registered->second;
127
128 if (definedInType == this) {
129 // Defined in this enum
130 std::cerr << "ERROR: Redefinition of value '" << value->name() << "'";
131 } else {
132 // Defined in super enum
Timur Iskhakovec123f32017-08-21 18:00:10 -0700133 std::cerr << "ERROR: Redefinition of value '" << value->name()
134 << "' defined in enum '" << definedInType->fullName() << "'";
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700135 }
136 std::cerr << " at " << value->location() << "\n";
137 return UNKNOWN_ERROR;
138 }
139
140 registeredValueNames[value->name()] = this;
141 }
142
143 return OK;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700144}
145
Steven Moreland9df52442016-12-12 08:51:14 -0800146bool EnumType::isElidableType() const {
147 return mStorageType->isElidableType();
148}
149
Andreas Huber737080b2016-08-02 15:38:04 -0700150const ScalarType *EnumType::resolveToScalarType() const {
151 return mStorageType->resolveToScalarType();
152}
153
Steven Moreland30bb6a82016-11-30 09:18:34 -0800154std::string EnumType::typeName() const {
155 return "enum " + localName();
156}
157
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700158bool EnumType::isEnum() const {
159 return true;
160}
161
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700162bool EnumType::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const {
Yifan Hongc6752dc2016-12-20 14:00:14 -0800163 return true;
164}
165
Steven Moreland979e0992016-09-07 09:18:08 -0700166std::string EnumType::getCppType(StorageMode,
Steven Morelande30ee9b2017-05-09 13:31:01 -0700167 bool /* specifyNamespaces */) const {
168 return fullName();
Andreas Huber881227d2016-08-02 14:20:21 -0700169}
170
Yifan Hong4ed13472016-11-02 10:44:11 -0700171std::string EnumType::getJavaType(bool forInitializer) const {
172 return mStorageType->resolveToScalarType()->getJavaType(forInitializer);
Andreas Huber2831d512016-08-15 09:33:47 -0700173}
174
175std::string EnumType::getJavaSuffix() const {
176 return mStorageType->resolveToScalarType()->getJavaSuffix();
177}
178
Nirav Atre66842a92018-06-28 18:14:13 -0700179std::string EnumType::getJavaTypeClass() const {
180 return mStorageType->resolveToScalarType()->getJavaTypeClass();
Andreas Hubera3558b32016-09-14 09:12:42 -0700181}
182
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700183std::string EnumType::getVtsType() const {
184 return "TYPE_ENUM";
185}
186
Steven Moreland38a4fa12017-12-28 13:36:15 -0800187std::string EnumType::getBitfieldCppType(StorageMode /* mode */, bool specifyNamespaces) const {
188 const std::string space = specifyNamespaces ? "::android::hardware::" : "";
189 return space + "hidl_bitfield<" + (specifyNamespaces ? fullName() : localName()) + ">";
Yifan Hongc14dd6e2017-09-15 13:39:58 -0700190}
Timur Iskhakov63f39902017-08-29 15:47:29 -0700191
Yifan Hongc14dd6e2017-09-15 13:39:58 -0700192std::string EnumType::getBitfieldJavaType(bool forInitializer) const {
193 return resolveToScalarType()->getJavaType(forInitializer);
194}
195
Nirav Atre66842a92018-06-28 18:14:13 -0700196std::string EnumType::getBitfieldJavaTypeClass() const {
197 return resolveToScalarType()->getJavaTypeClass();
Yifan Honge45b5302017-02-22 10:49:07 -0800198}
199
Yifan Hongf24fa852016-09-23 11:03:15 -0700200LocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
Timur Iskhakovf1b902d2017-08-13 20:14:31 -0700201 std::vector<const EnumType*> chain = typeChain();
Yifan Hongf24fa852016-09-23 11:03:15 -0700202 for (auto it = chain.begin(); it != chain.end(); ++it) {
203 const auto &type = *it;
204 for(EnumValue *v : type->values()) {
205 if(v->name() == name) {
206 return v;
207 }
208 }
209 }
210 return nullptr;
211}
212
Andreas Huber881227d2016-08-02 14:20:21 -0700213void EnumType::emitReaderWriter(
214 Formatter &out,
215 const std::string &name,
216 const std::string &parcelObj,
217 bool parcelObjIsPointer,
218 bool isReader,
219 ErrorMode mode) const {
Andreas Huber737080b2016-08-02 15:38:04 -0700220 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Yi Kong56758da2018-07-24 16:21:37 -0700221 CHECK(scalarType != nullptr);
Andreas Huber737080b2016-08-02 15:38:04 -0700222
223 scalarType->emitReaderWriterWithCast(
224 out,
225 name,
226 parcelObj,
227 parcelObjIsPointer,
228 isReader,
229 mode,
230 true /* needsCast */);
Andreas Huber881227d2016-08-02 14:20:21 -0700231}
232
Andreas Huber85eabdb2016-08-25 11:24:49 -0700233void EnumType::emitJavaFieldReaderWriter(
234 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700235 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700236 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700237 const std::string &blobName,
238 const std::string &fieldName,
239 const std::string &offset,
240 bool isReader) const {
241 return mStorageType->emitJavaFieldReaderWriter(
Andreas Huber709b62d2016-09-19 11:21:18 -0700242 out, depth, parcelName, blobName, fieldName, offset, isReader);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700243}
244
Steven Moreland368e4602018-02-16 14:21:49 -0800245void EnumType::emitTypeDeclarations(Formatter& out) const {
Andreas Huber737080b2016-08-02 15:38:04 -0700246 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Andreas Hubere3f769a2016-10-10 10:54:44 -0700247 CHECK(scalarType != nullptr);
Andreas Huber737080b2016-08-02 15:38:04 -0700248
Yifan Hong3b320f82016-11-01 15:15:54 -0700249 const std::string storageType = scalarType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700250
251 out << "enum class "
Andreas Huber0e00de42016-08-03 09:56:02 -0700252 << localName()
Andreas Huber881227d2016-08-02 14:20:21 -0700253 << " : "
Andreas Hubere3f769a2016-10-10 10:54:44 -0700254 << storageType
Andreas Huber881227d2016-08-02 14:20:21 -0700255 << " {\n";
256
257 out.indent();
258
Timur Iskhakovf1b902d2017-08-13 20:14:31 -0700259 std::vector<const EnumType*> chain = typeChain();
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700260
261 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
262 const auto &type = *it;
263
264 for (const auto &entry : type->values()) {
Steven Moreland49bad8d2018-05-17 15:45:26 -0700265 entry->emitDocComment(out);
266
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700267 out << entry->name();
268
Yifan Hongfc610cd2016-09-22 13:34:45 -0700269 std::string value = entry->cppValue(scalarType->getKind());
Yifan Hongf24fa852016-09-23 11:03:15 -0700270 CHECK(!value.empty()); // use autofilled values for c++.
Steven Morelandf21962d2018-08-09 12:44:40 -0700271 out << " = " << value << ",\n";
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700272 }
Andreas Huber881227d2016-08-02 14:20:21 -0700273 }
274
275 out.unindent();
276 out << "};\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700277}
278
Timur Iskhakovfd3f2502017-09-05 16:25:02 -0700279void EnumType::emitTypeForwardDeclaration(Formatter& out) const {
280 const ScalarType* scalarType = mStorageType->resolveToScalarType();
281 const std::string storageType = scalarType->getCppStackType();
282
283 out << "enum class " << localName() << " : " << storageType << ";\n";
284}
285
Steven Moreland6961d3f2017-11-17 14:23:39 -0800286void EnumType::emitIteratorDeclaration(Formatter& out) const {
287 size_t elementCount = 0;
288 for (const auto* type : typeChain()) {
289 elementCount += type->mValues.size();
290 }
291
Steven Morelanddab3ff12018-10-26 14:09:00 -0700292 out << "template<> constexpr std::array<" << getCppStackType() << ", " << elementCount
293 << "> hidl_enum_values<" << getCppStackType() << "> = ";
Steven Moreland6961d3f2017-11-17 14:23:39 -0800294 out.block([&] {
Steven Morelanddab3ff12018-10-26 14:09:00 -0700295 auto enumerators = typeChain();
296 std::reverse(enumerators.begin(), enumerators.end());
297 for (const auto* type : enumerators) {
298 for (const auto* enumValue : type->mValues) {
299 out << fullName() << "::" << enumValue->name() << ",\n";
300 }
301 }
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700302 }) << ";\n";
Steven Moreland6961d3f2017-11-17 14:23:39 -0800303}
304
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800305void EnumType::emitEnumBitwiseOperator(
306 Formatter &out,
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800307 bool lhsIsEnum,
308 bool rhsIsEnum,
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800309 const std::string &op) const {
Andreas Hubere3f769a2016-10-10 10:54:44 -0700310 const ScalarType *scalarType = mStorageType->resolveToScalarType();
311 CHECK(scalarType != nullptr);
312
Yifan Hong3b320f82016-11-01 15:15:54 -0700313 const std::string storageType = scalarType->getCppStackType();
Andreas Hubere3f769a2016-10-10 10:54:44 -0700314
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800315 out << "constexpr "
316 << storageType
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800317 << " operator"
318 << op
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800319 << "(const "
320 << (lhsIsEnum ? fullName() : storageType)
321 << " lhs, const "
322 << (rhsIsEnum ? fullName() : storageType)
Andreas Hubere3f769a2016-10-10 10:54:44 -0700323 << " rhs) {\n";
Andreas Hubere3f769a2016-10-10 10:54:44 -0700324
Yifan Hong33223ca2016-12-13 15:07:35 -0800325 out.indent([&] {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800326 out << "return static_cast<"
327 << storageType
328 << ">(";
Andreas Hubere3f769a2016-10-10 10:54:44 -0700329
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800330 if (lhsIsEnum) {
331 out << "static_cast<"
332 << storageType
333 << ">(lhs)";
334 } else {
335 out << "lhs";
336 }
337 out << " " << op << " ";
338 if (rhsIsEnum) {
339 out << "static_cast<"
340 << storageType
341 << ">(rhs)";
342 } else {
343 out << "rhs";
344 }
345 out << ");\n";
346 });
Andreas Hubere3f769a2016-10-10 10:54:44 -0700347
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700348 out << "}\n";
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800349}
350
351void EnumType::emitBitFieldBitwiseAssignmentOperator(
352 Formatter &out,
353 const std::string &op) const {
354 const ScalarType *scalarType = mStorageType->resolveToScalarType();
355 CHECK(scalarType != nullptr);
356
357 const std::string storageType = scalarType->getCppStackType();
358
359 out << "constexpr " << storageType << " &operator" << op << "=("
360 << storageType << "& v, const " << fullName() << " e) {\n";
361
Yifan Hong33223ca2016-12-13 15:07:35 -0800362 out.indent([&] {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800363 out << "v " << op << "= static_cast<" << storageType << ">(e);\n";
364 out << "return v;\n";
365 });
Andreas Hubere3f769a2016-10-10 10:54:44 -0700366
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700367 out << "}\n";
Andreas Hubere3f769a2016-10-10 10:54:44 -0700368}
369
Steven Moreland6961d3f2017-11-17 14:23:39 -0800370void EnumType::emitGlobalTypeDeclarations(Formatter& out) const {
371 out << "namespace android {\n";
372 out << "namespace hardware {\n";
Steven Morelanddab3ff12018-10-26 14:09:00 -0700373 out << "namespace details {\n";
Steven Moreland6961d3f2017-11-17 14:23:39 -0800374
375 emitIteratorDeclaration(out);
376
Steven Morelanddab3ff12018-10-26 14:09:00 -0700377 out << "} // namespace details\n";
Steven Moreland6961d3f2017-11-17 14:23:39 -0800378 out << "} // namespace hardware\n";
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700379 out << "} // namespace android\n\n";
Steven Moreland6961d3f2017-11-17 14:23:39 -0800380}
381
Steven Moreland368e4602018-02-16 14:21:49 -0800382void EnumType::emitPackageTypeDeclarations(Formatter& out) const {
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700383 out << "template<typename>\n"
384 << "static inline std::string toString(" << resolveToScalarType()->getCppArgumentType()
385 << " o);\n";
386 out << "static inline std::string toString(" << getCppArgumentType() << " o);\n\n";
387
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800388 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, true /* rhsIsEnum */, "|");
389 emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true /* rhsIsEnum */, "|");
390 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, false /* rhsIsEnum */, "|");
391 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, true /* rhsIsEnum */, "&");
392 emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true /* rhsIsEnum */, "&");
393 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, false /* rhsIsEnum */, "&");
394
395 emitBitFieldBitwiseAssignmentOperator(out, "|");
396 emitBitFieldBitwiseAssignmentOperator(out, "&");
Andreas Hubere3f769a2016-10-10 10:54:44 -0700397
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700398 out.endl();
399}
400
401void EnumType::emitPackageTypeHeaderDefinitions(Formatter& out) const {
Steven Morelandbf714212017-10-27 18:29:01 -0700402 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Yi Kong56758da2018-07-24 16:21:37 -0700403 CHECK(scalarType != nullptr);
Steven Morelandbf714212017-10-27 18:29:01 -0700404
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800405 out << "template<>\n"
Steven Morelandbf714212017-10-27 18:29:01 -0700406 << "inline std::string toString<" << getCppStackType() << ">("
407 << scalarType->getCppArgumentType() << " o) ";
408 out.block([&] {
409 // include toHexString for scalar types
410 out << "using ::android::hardware::details::toHexString;\n"
411 << "std::string os;\n"
412 << getBitfieldCppType(StorageMode_Stack) << " flipped = 0;\n"
413 << "bool first = true;\n";
Steven Moreland5f930042018-03-21 17:09:12 -0700414 forEachValueFromRoot([&](EnumValue* value) {
Steven Morelandbf714212017-10-27 18:29:01 -0700415 std::string valueName = fullName() + "::" + value->name();
416 out.sIf("(o & " + valueName + ")" +
417 " == static_cast<" + scalarType->getCppStackType() +
418 ">(" + valueName + ")", [&] {
419 out << "os += (first ? \"\" : \" | \");\n"
420 << "os += \"" << value->name() << "\";\n"
421 << "first = false;\n"
422 << "flipped |= " << valueName << ";\n";
423 }).endl();
Steven Moreland5f930042018-03-21 17:09:12 -0700424 });
Steven Morelandbf714212017-10-27 18:29:01 -0700425 // put remaining bits
426 out.sIf("o != flipped", [&] {
427 out << "os += (first ? \"\" : \" | \");\n";
428 scalarType->emitHexDump(out, "os", "o & (~flipped)");
429 });
430 out << "os += \" (\";\n";
431 scalarType->emitHexDump(out, "os", "o");
432 out << "os += \")\";\n";
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800433
Steven Morelandbf714212017-10-27 18:29:01 -0700434 out << "return os;\n";
435 }).endl().endl();
436
437 out << "static inline std::string toString(" << getCppArgumentType() << " o) ";
438
439 out.block([&] {
440 out << "using ::android::hardware::details::toHexString;\n";
Steven Moreland5f930042018-03-21 17:09:12 -0700441 forEachValueFromRoot([&](EnumValue* value) {
Steven Morelandbf714212017-10-27 18:29:01 -0700442 out.sIf("o == " + fullName() + "::" + value->name(), [&] {
443 out << "return \"" << value->name() << "\";\n";
444 }).endl();
Steven Moreland5f930042018-03-21 17:09:12 -0700445 });
Steven Morelandbf714212017-10-27 18:29:01 -0700446 out << "std::string os;\n";
447 scalarType->emitHexDump(out, "os",
448 "static_cast<" + scalarType->getCppStackType() + ">(o)");
449 out << "return os;\n";
450 }).endl().endl();
Andreas Hubere3f769a2016-10-10 10:54:44 -0700451}
452
Steven Moreland368e4602018-02-16 14:21:49 -0800453void EnumType::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const {
Andreas Huber2831d512016-08-15 09:33:47 -0700454 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Yi Kong56758da2018-07-24 16:21:37 -0700455 CHECK(scalarType != nullptr);
Andreas Huber2831d512016-08-15 09:33:47 -0700456
Yifan Honge45b5302017-02-22 10:49:07 -0800457 out << "public "
458 << (atTopLevel ? "" : "static ")
459 << "final class "
Andreas Huber2831d512016-08-15 09:33:47 -0700460 << localName()
461 << " {\n";
462
463 out.indent();
464
Andreas Huber4c865b72016-09-14 15:26:27 -0700465 const std::string typeName =
Yifan Hong4ed13472016-11-02 10:44:11 -0700466 scalarType->getJavaType(false /* forInitializer */);
Andreas Huber2831d512016-08-15 09:33:47 -0700467
Timur Iskhakovf1b902d2017-08-13 20:14:31 -0700468 std::vector<const EnumType*> chain = typeChain();
Andreas Huber2831d512016-08-15 09:33:47 -0700469
470 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
471 const auto &type = *it;
472
473 for (const auto &entry : type->values()) {
Steven Moreland49bad8d2018-05-17 15:45:26 -0700474 entry->emitDocComment(out);
475
Andreas Huber2831d512016-08-15 09:33:47 -0700476 out << "public static final "
477 << typeName
478 << " "
Andreas Huberab647c02016-09-14 09:44:00 -0700479 << entry->name()
480 << " = ";
Andreas Huber2831d512016-08-15 09:33:47 -0700481
Yifan Hongf24fa852016-09-23 11:03:15 -0700482 // javaValue will make the number signed.
Yifan Hongfc610cd2016-09-22 13:34:45 -0700483 std::string value = entry->javaValue(scalarType->getKind());
Yifan Hongf24fa852016-09-23 11:03:15 -0700484 CHECK(!value.empty()); // use autofilled values for java.
Steven Morelandf21962d2018-08-09 12:44:40 -0700485 out << value << ";\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700486 }
487 }
488
Yifan Honge45b5302017-02-22 10:49:07 -0800489 out << "public static final String toString("
490 << typeName << " o) ";
491 out.block([&] {
Yifan Hong0a9cc862017-10-06 16:21:55 -0700492 forEachValueFromRoot([&](EnumValue* value) {
Yifan Honge45b5302017-02-22 10:49:07 -0800493 out.sIf("o == " + value->name(), [&] {
494 out << "return \"" << value->name() << "\";\n";
495 }).endl();
Yifan Hong0a9cc862017-10-06 16:21:55 -0700496 });
Yifan Honge45b5302017-02-22 10:49:07 -0800497 out << "return \"0x\" + ";
498 scalarType->emitConvertToJavaHexString(out, "o");
499 out << ";\n";
500 }).endl();
501
Yifan Hongc14dd6e2017-09-15 13:39:58 -0700502 auto bitfieldType = getBitfieldJavaType(false /* forInitializer */);
Yifan Honge45b5302017-02-22 10:49:07 -0800503 out << "\n"
504 << "public static final String dumpBitfield("
505 << bitfieldType << " o) ";
506 out.block([&] {
507 out << "java.util.ArrayList<String> list = new java.util.ArrayList<>();\n";
508 out << bitfieldType << " flipped = 0;\n";
Yifan Hong0a9cc862017-10-06 16:21:55 -0700509 forEachValueFromRoot([&](EnumValue* value) {
Yifan Hongdd7c5742017-07-06 13:16:30 -0700510 if (value->constExpr()->castSizeT() == 0) {
511 out << "list.add(\"" << value->name() << "\"); // " << value->name() << " == 0\n";
Yifan Hong0a9cc862017-10-06 16:21:55 -0700512 return; // continue to next value
Yifan Hongdd7c5742017-07-06 13:16:30 -0700513 }
Yifan Honge45b5302017-02-22 10:49:07 -0800514 out.sIf("(o & " + value->name() + ") == " + value->name(), [&] {
515 out << "list.add(\"" << value->name() << "\");\n";
516 out << "flipped |= " << value->name() << ";\n";
517 }).endl();
Yifan Hong0a9cc862017-10-06 16:21:55 -0700518 });
Yifan Honge45b5302017-02-22 10:49:07 -0800519 // put remaining bits
520 out.sIf("o != flipped", [&] {
521 out << "list.add(\"0x\" + ";
522 scalarType->emitConvertToJavaHexString(out, "o & (~flipped)");
523 out << ");\n";
524 }).endl();
525 out << "return String.join(\" | \", list);\n";
526 }).endl().endl();
527
Andreas Huber2831d512016-08-15 09:33:47 -0700528 out.unindent();
529 out << "};\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700530}
531
Steven Moreland368e4602018-02-16 14:21:49 -0800532void EnumType::emitVtsTypeDeclarations(Formatter& out) const {
Yifan Hongc07b2022016-11-08 12:44:24 -0800533 const ScalarType *scalarType = mStorageType->resolveToScalarType();
534
Zhuoyao Zhangbf828c82016-10-26 14:15:10 -0700535 out << "name: \"" << fullName() << "\"\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700536 out << "type: " << getVtsType() << "\n";
537 out << "enum_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700538 out.indent();
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700539
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700540 out << "scalar_type: \""
Yifan Hongc07b2022016-11-08 12:44:24 -0800541 << scalarType->getVtsScalarType()
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700542 << "\"\n\n";
Timur Iskhakovf1b902d2017-08-13 20:14:31 -0700543 std::vector<const EnumType*> chain = typeChain();
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700544
545 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
546 const auto &type = *it;
547
548 for (const auto &entry : type->values()) {
549 out << "enumerator: \"" << entry->name() << "\"\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700550 out << "scalar_value: {\n";
551 out.indent();
Yifan Hongc07b2022016-11-08 12:44:24 -0800552 // use autofilled values for vts.
Steven Morelandf21962d2018-08-09 12:44:40 -0700553 std::string value = entry->rawValue(scalarType->getKind());
Yifan Hongc07b2022016-11-08 12:44:24 -0800554 CHECK(!value.empty());
555 out << mStorageType->resolveToScalarType()->getVtsScalarType()
556 << ": "
557 << value
558 << "\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700559 out.unindent();
560 out << "}\n";
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700561 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700562 }
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700563
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700564 out.unindent();
565 out << "}\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700566}
567
Steven Moreland368e4602018-02-16 14:21:49 -0800568void EnumType::emitVtsAttributeType(Formatter& out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700569 out << "type: " << getVtsType() << "\n";
Zhuoyao Zhangbf828c82016-10-26 14:15:10 -0700570 out << "predefined_type: \"" << fullName() << "\"\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700571}
572
Yifan Honge45b5302017-02-22 10:49:07 -0800573void EnumType::emitJavaDump(
574 Formatter &out,
575 const std::string &streamName,
576 const std::string &name) const {
577 out << streamName << ".append(" << fqName().javaName() << ".toString("
578 << name << "));\n";
579}
580
Timur Iskhakovf1b902d2017-08-13 20:14:31 -0700581std::vector<const EnumType*> EnumType::typeChain() const {
582 std::vector<const EnumType*> types;
583 for (const EnumType* type = this; type != nullptr;) {
584 types.push_back(type);
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700585
Timur Iskhakovf1b902d2017-08-13 20:14:31 -0700586 const Type* superType = type->storageType();
587 if (superType != nullptr && superType->isEnum()) {
588 type = static_cast<const EnumType*>(superType);
589 } else {
590 type = nullptr;
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700591 }
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700592 }
Timur Iskhakovf1b902d2017-08-13 20:14:31 -0700593
594 return types;
595}
596
597std::vector<const EnumType*> EnumType::superTypeChain() const {
598 const Type* superType = storageType();
599 if (superType == nullptr || !superType->isEnum()) {
600 return {};
601 }
602 return static_cast<const EnumType*>(superType)->typeChain();
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700603}
604
Andreas Huber85eabdb2016-08-25 11:24:49 -0700605void EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
606 mStorageType->getAlignmentAndSize(align, size);
607}
608
Andreas Huber019d21d2016-10-03 12:59:47 -0700609const Annotation *EnumType::findExportAnnotation() const {
610 for (const auto &annotation : annotations()) {
611 if (annotation->name() == "export") {
612 return annotation;
613 }
614 }
615
616 return nullptr;
617}
618
619void EnumType::appendToExportedTypesVector(
620 std::vector<const Type *> *exportedTypes) const {
621 if (findExportAnnotation() != nullptr) {
622 exportedTypes->push_back(this);
623 }
624}
625
Steven Moreland368e4602018-02-16 14:21:49 -0800626void EnumType::emitExportedHeader(Formatter& out, bool forJava) const {
Andreas Huber019d21d2016-10-03 12:59:47 -0700627 const Annotation *annotation = findExportAnnotation();
628 CHECK(annotation != nullptr);
629
630 std::string name = localName();
631
632 const AnnotationParam *nameParam = annotation->getParam("name");
633 if (nameParam != nullptr) {
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800634 name = nameParam->getSingleString();
635 }
Andreas Huber019d21d2016-10-03 12:59:47 -0700636
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800637 bool exportParent = true;
638 const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
639 if (exportParentParam != nullptr) {
640 exportParent = exportParentParam->getSingleBool();
Andreas Huber019d21d2016-10-03 12:59:47 -0700641 }
642
Andreas Huberb0627fb2016-10-10 09:39:28 -0700643 std::string valuePrefix;
Andreas Huberb0627fb2016-10-10 09:39:28 -0700644 const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
645 if (prefixParam != nullptr) {
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800646 valuePrefix = prefixParam->getSingleString();
Andreas Huberb0627fb2016-10-10 09:39:28 -0700647 }
648
Steven Moreland73cdc882016-11-21 16:43:50 -0800649 std::string valueSuffix;
650 const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
651 if (suffixParam != nullptr) {
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800652 valueSuffix = suffixParam->getSingleString();
Steven Moreland73cdc882016-11-21 16:43:50 -0800653 }
654
Andreas Huber019d21d2016-10-03 12:59:47 -0700655 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Andreas Huber1c507272016-10-05 14:33:21 -0700656 CHECK(scalarType != nullptr);
Andreas Huber019d21d2016-10-03 12:59:47 -0700657
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800658 std::vector<const EnumType *> chain;
659 if (exportParent) {
Timur Iskhakovf1b902d2017-08-13 20:14:31 -0700660 chain = typeChain();
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800661 } else {
662 chain = { this };
663 }
664
Andreas Huber1c507272016-10-05 14:33:21 -0700665 if (forJava) {
666 if (!name.empty()) {
667 out << "public final class "
668 << name
669 << " {\n";
670
671 out.indent();
672 } else {
673 out << "// Values declared in " << localName() << " follow.\n";
674 }
675
Andreas Huber1c507272016-10-05 14:33:21 -0700676 const std::string typeName =
Yifan Hong4ed13472016-11-02 10:44:11 -0700677 scalarType->getJavaType(false /* forInitializer */);
Andreas Huber1c507272016-10-05 14:33:21 -0700678
Andreas Huber1c507272016-10-05 14:33:21 -0700679 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
680 const auto &type = *it;
681
682 for (const auto &entry : type->values()) {
683 out << "public static final "
684 << typeName
685 << " "
686 << valuePrefix
687 << entry->name()
Steven Moreland73cdc882016-11-21 16:43:50 -0800688 << valueSuffix
Andreas Huber1c507272016-10-05 14:33:21 -0700689 << " = ";
690
691 // javaValue will make the number signed.
692 std::string value = entry->javaValue(scalarType->getKind());
693 CHECK(!value.empty()); // use autofilled values for java.
Steven Morelandf21962d2018-08-09 12:44:40 -0700694 out << value << ";\n";
Andreas Huber1c507272016-10-05 14:33:21 -0700695 }
696 }
697
698 if (!name.empty()) {
699 out.unindent();
700 out << "};\n";
701 }
702 out << "\n";
703
Steven Moreland368e4602018-02-16 14:21:49 -0800704 return;
Andreas Huber1c507272016-10-05 14:33:21 -0700705 }
Andreas Huber019d21d2016-10-03 12:59:47 -0700706
707 if (!name.empty()) {
708 out << "typedef ";
709 }
710
711 out << "enum {\n";
712
713 out.indent();
714
Andreas Huber019d21d2016-10-03 12:59:47 -0700715 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
716 const auto &type = *it;
717
718 for (const auto &entry : type->values()) {
Steven Moreland73cdc882016-11-21 16:43:50 -0800719 out << valuePrefix << entry->name() << valueSuffix;
Andreas Huber019d21d2016-10-03 12:59:47 -0700720
721 std::string value = entry->cppValue(scalarType->getKind());
722 CHECK(!value.empty()); // use autofilled values for c++.
Steven Morelandf21962d2018-08-09 12:44:40 -0700723 out << " = " << value << ",\n";
Andreas Huber019d21d2016-10-03 12:59:47 -0700724 }
725 }
726
727 out.unindent();
728 out << "}";
729
730 if (!name.empty()) {
731 out << " " << name;
732 }
733
734 out << ";\n\n";
Andreas Huber019d21d2016-10-03 12:59:47 -0700735}
736
Andreas Huber31629bc2016-08-03 09:06:40 -0700737////////////////////////////////////////////////////////////////////////////////
738
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700739EnumValue::EnumValue(const char* name, ConstantExpression* value, const Location& location)
740 : mName(name), mValue(value), mLocation(location), mIsAutoFill(false) {}
Andreas Huber31629bc2016-08-03 09:06:40 -0700741
742std::string EnumValue::name() const {
743 return mName;
744}
745
Steven Morelandf21962d2018-08-09 12:44:40 -0700746std::string EnumValue::rawValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700747 CHECK(mValue != nullptr);
Steven Morelandf21962d2018-08-09 12:44:40 -0700748 return mValue->rawValue(castKind);
Yifan Hong57886972016-08-17 10:42:15 -0700749}
750
Yifan Hongfc610cd2016-09-22 13:34:45 -0700751std::string EnumValue::cppValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700752 CHECK(mValue != nullptr);
753 return mValue->cppValue(castKind);
Yifan Hong57886972016-08-17 10:42:15 -0700754}
Yifan Hongfc610cd2016-09-22 13:34:45 -0700755std::string EnumValue::javaValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700756 CHECK(mValue != nullptr);
757 return mValue->javaValue(castKind);
Yifan Hong19ca75a2016-08-31 10:20:03 -0700758}
Yifan Hong57886972016-08-17 10:42:15 -0700759
Yifan Hongf24fa852016-09-23 11:03:15 -0700760ConstantExpression *EnumValue::constExpr() const {
761 CHECK(mValue != nullptr);
762 return mValue;
763}
764
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700765void EnumValue::autofill(const EnumType* prevType, EnumValue* prevValue, const ScalarType* type) {
766 // Value is defined explicitly
Timur Iskhakov7296af12017-08-09 21:52:48 +0000767 if (mValue != nullptr) return;
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700768
769 CHECK((prevType == nullptr) == (prevValue == nullptr));
770
Yifan Hongf24fa852016-09-23 11:03:15 -0700771 mIsAutoFill = true;
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700772 if (prevValue == nullptr) {
Timur Iskhakov7296af12017-08-09 21:52:48 +0000773 mValue = ConstantExpression::Zero(type->getKind()).release();
Yifan Hongf24fa852016-09-23 11:03:15 -0700774 } else {
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700775 std::string description = prevType->fullName() + "." + prevValue->name() + " implicitly";
776 auto* prevReference = new ReferenceConstantExpression(
777 Reference<LocalIdentifier>(prevValue, mLocation), description);
778 mValue = prevReference->addOne(type->getKind()).release();
Yifan Hongf24fa852016-09-23 11:03:15 -0700779 }
Yifan Hongf24fa852016-09-23 11:03:15 -0700780}
781
782bool EnumValue::isAutoFill() const {
783 return mIsAutoFill;
784}
785
786bool EnumValue::isEnumValue() const {
787 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700788}
789
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700790const Location& EnumValue::location() const {
791 return mLocation;
792}
793
Yifan Hongabf73ee2016-12-05 18:47:00 -0800794////////////////////////////////////////////////////////////////////////////////
795
Yifan Hongc14dd6e2017-09-15 13:39:58 -0700796BitFieldType::BitFieldType(Scope* parent) : TemplatedType(parent) {}
797
Yifan Hongabf73ee2016-12-05 18:47:00 -0800798bool BitFieldType::isBitField() const {
799 return true;
800}
801
Yifan Hongc14dd6e2017-09-15 13:39:58 -0700802const EnumType* BitFieldType::getElementEnumType() const {
803 CHECK(mElementType.get() != nullptr && mElementType->isEnum());
804 return static_cast<const EnumType*>(mElementType.get());
805}
806
Timur Iskhakov3f1d26e2017-08-30 15:35:53 -0700807std::string BitFieldType::templatedTypeName() const {
808 return "mask";
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800809}
810
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700811bool BitFieldType::isCompatibleElementType(const Type* elementType) const {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800812 return elementType->isEnum();
813}
814
815const ScalarType *BitFieldType::resolveToScalarType() const {
816 return mElementType->resolveToScalarType();
817}
818
819std::string BitFieldType::getCppType(StorageMode mode,
820 bool specifyNamespaces) const {
Yifan Hongc14dd6e2017-09-15 13:39:58 -0700821 return getElementEnumType()->getBitfieldCppType(mode, specifyNamespaces);
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800822}
823
824std::string BitFieldType::getJavaType(bool forInitializer) const {
Yifan Hongc14dd6e2017-09-15 13:39:58 -0700825 return getElementEnumType()->getBitfieldJavaType(forInitializer);
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800826}
827
828std::string BitFieldType::getJavaSuffix() const {
829 return resolveToScalarType()->getJavaSuffix();
830}
831
Nirav Atre66842a92018-06-28 18:14:13 -0700832std::string BitFieldType::getJavaTypeClass() const {
833 return getElementEnumType()->getBitfieldJavaTypeClass();
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800834}
835
836std::string BitFieldType::getVtsType() const {
837 return "TYPE_MASK";
838}
839
Yifan Hong8c56cbe2016-12-12 15:30:12 -0800840bool BitFieldType::isElidableType() const {
841 return resolveToScalarType()->isElidableType();
842}
843
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700844bool BitFieldType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
845 return resolveToScalarType()->canCheckEquality(visited);
Yifan Hong7d1839f2017-02-22 13:24:29 -0800846}
847
Steven Moreland368e4602018-02-16 14:21:49 -0800848void BitFieldType::emitVtsAttributeType(Formatter& out) const {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800849 out << "type: " << getVtsType() << "\n";
Zhuoyao Zhang13236232017-01-24 14:27:55 -0800850 out << "scalar_type: \""
851 << mElementType->resolveToScalarType()->getVtsScalarType()
852 << "\"\n";
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700853 out << "predefined_type: \"" << static_cast<const NamedType*>(mElementType.get())->fullName()
Timur Iskhakov505316c2017-08-05 03:38:59 +0000854 << "\"\n";
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800855}
856
857void BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
858 resolveToScalarType()->getAlignmentAndSize(align, size);
859}
860
861void BitFieldType::emitReaderWriter(
862 Formatter &out,
863 const std::string &name,
864 const std::string &parcelObj,
865 bool parcelObjIsPointer,
866 bool isReader,
867 ErrorMode mode) const {
868 resolveToScalarType()->emitReaderWriterWithCast(
869 out,
870 name,
871 parcelObj,
872 parcelObjIsPointer,
873 isReader,
874 mode,
875 true /* needsCast */);
876}
877
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700878const EnumType* BitFieldType::getEnumType() const {
Yifan Honge45b5302017-02-22 10:49:07 -0800879 CHECK(mElementType->isEnum());
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700880 return static_cast<const EnumType*>(mElementType.get());
Yifan Honge45b5302017-02-22 10:49:07 -0800881}
882
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800883// a bitfield maps to the underlying scalar type in C++, so operator<< is
884// already defined. We can still emit useful information if the bitfield is
885// in a struct / union by overriding emitDump as below.
886void BitFieldType::emitDump(
887 Formatter &out,
888 const std::string &streamName,
889 const std::string &name) const {
Yifan Honge45b5302017-02-22 10:49:07 -0800890 out << streamName << " += "<< getEnumType()->fqName().cppNamespace()
891 << "::toString<" << getEnumType()->getCppStackType()
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800892 << ">(" << name << ");\n";
893}
894
Yifan Honge45b5302017-02-22 10:49:07 -0800895void BitFieldType::emitJavaDump(
896 Formatter &out,
897 const std::string &streamName,
898 const std::string &name) const {
899 out << streamName << ".append(" << getEnumType()->fqName().javaName() << ".dumpBitfield("
900 << name << "));\n";
901}
902
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800903void BitFieldType::emitJavaFieldReaderWriter(
904 Formatter &out,
905 size_t depth,
906 const std::string &parcelName,
907 const std::string &blobName,
908 const std::string &fieldName,
909 const std::string &offset,
910 bool isReader) const {
911 return resolveToScalarType()->emitJavaFieldReaderWriter(
912 out, depth, parcelName, blobName, fieldName, offset, isReader);
913}
914
Andreas Huberc9410c72016-07-28 12:18:40 -0700915} // namespace android
916