EnumType.cpp revision 870d1a7ccd70bd710128993de401278614d1975e
11aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber/*
21aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Copyright (C) 2016 The Android Open Source Project
31aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
41aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
51aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * you may not use this file except in compliance with the License.
61aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * You may obtain a copy of the License at
71aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
81aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
91aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
101aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Unless required by applicable law or agreed to in writing, software
111aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
121aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * See the License for the specific language governing permissions and
141aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * limitations under the License.
151aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber */
161aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber
17c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber#include "EnumType.h"
18c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
19019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber#include "Annotation.h"
20881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber#include "ScalarType.h"
21c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
22a72e0d2be173cebf62f728b9d215808bd862f219Iliyan Malchev#include <inttypes.h>
23a72e0d2be173cebf62f728b9d215808bd862f219Iliyan Malchev#include <hidl-util/Formatter.h>
24737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber#include <android-base/logging.h>
25737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
26c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Hubernamespace android {
27c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
28c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas HuberEnumType::EnumType(
299ed827c8cd6e8eddb1ad9987ab9413c1de8a27dfAndreas Huber        const char *localName,
30a4b53d0da8c1c6889c361fd30b913adc364163bcYifan Hong        const Location &location,
319ed827c8cd6e8eddb1ad9987ab9413c1de8a27dfAndreas Huber        Type *storageType)
32a4b53d0da8c1c6889c361fd30b913adc364163bcYifan Hong    : Scope(localName, location),
33f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mValues(),
341c71fd5ab3381d1c59671adf2b8ca5c9a3f74401Steven Moreland      mStorageType(storageType) {
35c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}
36c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
378d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst Type *EnumType::storageType() const {
388d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    return mStorageType;
398d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
408d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
418d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst std::vector<EnumValue *> &EnumType::values() const {
42f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValues;
43f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
44f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
45f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongvoid EnumType::addValue(EnumValue *value) {
46f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(value != nullptr);
47f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
48f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    EnumValue *prev = nullptr;
49f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    std::vector<const EnumType *> chain;
50f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    getTypeChain(&chain);
51f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
52f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
53f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        if(!type->values().empty()) {
54f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            prev = type->values().back();
55f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            break;
56f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
57f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
58f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
59f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    value->autofill(prev, resolveToScalarType());
60f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mValues.push_back(value);
618d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
628d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
639df5244c1dd4508cc2e25f8a04d363903912d19cSteven Morelandbool EnumType::isElidableType() const {
649df5244c1dd4508cc2e25f8a04d363903912d19cSteven Moreland    return mStorageType->isElidableType();
659df5244c1dd4508cc2e25f8a04d363903912d19cSteven Moreland}
669df5244c1dd4508cc2e25f8a04d363903912d19cSteven Moreland
67737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huberconst ScalarType *EnumType::resolveToScalarType() const {
68737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    return mStorageType->resolveToScalarType();
69737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber}
70737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
7130bb6a869be0f3f82497b7b11c71ec9d47652ed0Steven Morelandstd::string EnumType::typeName() const {
7230bb6a869be0f3f82497b7b11c71ec9d47652ed0Steven Moreland    return "enum " + localName();
7330bb6a869be0f3f82497b7b11c71ec9d47652ed0Steven Moreland}
7430bb6a869be0f3f82497b7b11c71ec9d47652ed0Steven Moreland
758d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberbool EnumType::isEnum() const {
768d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    return true;
778d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
788d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
79c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hongbool EnumType::canCheckEquality() const {
80c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong    return true;
81c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong}
82c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong
83979e099f1163ff75beed5776cd01fb409b90a0cdSteven Morelandstd::string EnumType::getCppType(StorageMode,
84979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland                                 bool specifyNamespaces) const {
85979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland    return specifyNamespaces ? fullName() : partialCppName();
86881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
87881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
884ed1347cd29e6e07acad368891bb03078c798abaYifan Hongstd::string EnumType::getJavaType(bool forInitializer) const {
894ed1347cd29e6e07acad368891bb03078c798abaYifan Hong    return mStorageType->resolveToScalarType()->getJavaType(forInitializer);
902831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
912831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
922831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huberstd::string EnumType::getJavaSuffix() const {
932831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return mStorageType->resolveToScalarType()->getJavaSuffix();
942831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
952831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
96a3558b3b273695b31fbe1025339956966cde39c4Andreas Huberstd::string EnumType::getJavaWrapperType() const {
97a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber    return mStorageType->resolveToScalarType()->getJavaWrapperType();
98a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber}
99a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber
100c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhangstd::string EnumType::getVtsType() const {
101c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    return "TYPE_ENUM";
102c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang}
103c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang
104f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongLocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
105f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    std::vector<const EnumType *> chain;
106f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    getTypeChain(&chain);
107f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
108f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
109f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        for(EnumValue *v : type->values()) {
110f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            if(v->name() == name) {
111f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                return v;
112f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            }
113f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
114f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
115f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return nullptr;
116f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
117f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
118881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid EnumType::emitReaderWriter(
119881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
120881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
121881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
122881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
123881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
124881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode) const {
125737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
126737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    CHECK(scalarType != NULL);
127737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
128737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    scalarType->emitReaderWriterWithCast(
129737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            out,
130737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            name,
131737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObj,
132737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObjIsPointer,
133737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            isReader,
134737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            mode,
135737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            true /* needsCast */);
136881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
137881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
13885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::emitJavaFieldReaderWriter(
13985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out,
1404c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        size_t depth,
141709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        const std::string &parcelName,
14285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &blobName,
14385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &fieldName,
14485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &offset,
14585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        bool isReader) const {
14685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    return mStorageType->emitJavaFieldReaderWriter(
147709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            out, depth, parcelName, blobName, fieldName, offset, isReader);
14885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
14985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
150881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberstatus_t EnumType::emitTypeDeclarations(Formatter &out) const {
151737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
152e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
153737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
1543b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
155881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
156881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "enum class "
1570e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        << localName()
158881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " : "
159e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
160881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " {\n";
161881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
162881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.indent();
163881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
1648d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    std::vector<const EnumType *> chain;
165864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
1668d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1678d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
1688d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        const auto &type = *it;
1698d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1708d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        for (const auto &entry : type->values()) {
1718d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber            out << entry->name();
1728d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
173fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->cppValue(scalarType->getKind());
174f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for c++.
175f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << " = " << value;
1768d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1775788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << ",";
1785788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
179fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
180fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
1815788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong                out << " // " << comment;
1825788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            }
1835788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
1845788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << "\n";
1858d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        }
186881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
187881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
188881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.unindent();
189881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "};\n\n";
190881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
191881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    return OK;
192881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
193881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
1942820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdharyvoid EnumType::emitEnumBitwiseOperator(
1952820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        Formatter &out,
196c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool lhsIsEnum,
197c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool rhsIsEnum,
1982820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        const std::string &op) const {
199e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
200e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
201e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
2023b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
203e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
204c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "constexpr "
205c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << storageType
2062820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << " operator"
2072820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << op
208c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << "(const "
209c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << (lhsIsEnum ? fullName() : storageType)
210c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << " lhs, const "
211c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << (rhsIsEnum ? fullName() : storageType)
212c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << " rhs) {\n";
213e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
21433223ca2a9b8126d357e0986905fa35c0970a30eYifan Hong    out.indent([&] {
215c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "return static_cast<"
216c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            << storageType
217c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            << ">(";
218e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
219c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        if (lhsIsEnum) {
220c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "static_cast<"
221c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << storageType
222c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << ">(lhs)";
223c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        } else {
224c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "lhs";
225c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        }
226c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << " " << op << " ";
227c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        if (rhsIsEnum) {
228c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "static_cast<"
229c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << storageType
230c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << ">(rhs)";
231c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        } else {
232c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "rhs";
233c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        }
234c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << ");\n";
235c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    });
236e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
237c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "}\n\n";
238c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
239e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
240c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid EnumType::emitBitFieldBitwiseAssignmentOperator(
241c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
242c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &op) const {
243c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
244c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    CHECK(scalarType != nullptr);
245e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
246c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    const std::string storageType = scalarType->getCppStackType();
247c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
248c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "constexpr " << storageType << " &operator" << op << "=("
249c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << storageType << "& v, const " << fullName() << " e) {\n";
250c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
25133223ca2a9b8126d357e0986905fa35c0970a30eYifan Hong    out.indent([&] {
252c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "v " << op << "= static_cast<" << storageType << ">(e);\n";
253c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "return v;\n";
254c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    });
255e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
256e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "}\n\n";
257e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
258e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
259e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huberstatus_t EnumType::emitGlobalTypeDeclarations(Formatter &out) const {
260c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
261c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
262c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "|");
263c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
264c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
265c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "&");
266c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
267c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitBitFieldBitwiseAssignmentOperator(out, "|");
268c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitBitFieldBitwiseAssignmentOperator(out, "&");
269e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
270870d1a7ccd70bd710128993de401278614d1975eYifan Hong    // toString for bitfields, equivalent to dumpBitfield in Java
271f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<typename>\n"
272f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString("
273f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << resolveToScalarType()->getCppArgumentType()
274f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o);\n";
275f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
276f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString<" << getCppStackType() << ">("
277f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << resolveToScalarType()->getCppArgumentType()
278f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o);\n\n";
279f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
280870d1a7ccd70bd710128993de401278614d1975eYifan Hong    // toString for enum itself
281870d1a7ccd70bd710128993de401278614d1975eYifan Hong    out << "std::string toString("
282f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << getCppArgumentType()
283870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << " o);\n\n";
284f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
285f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    return OK;
286f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
287f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
288f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hongstatus_t EnumType::emitTypeDefinitions(Formatter &out, const std::string /* prefix */) const {
289f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
290f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
291f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    CHECK(scalarType != NULL);
292f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
293f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
294f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString<" << getCppStackType() << ">("
295870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << scalarType->getCppArgumentType()
296f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o) ";
297f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out.block([&] {
298f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        // include toHexString for scalar types
299f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "using ::android::hardware::details::toHexString;\n"
300870d1a7ccd70bd710128993de401278614d1975eYifan Hong            << "std::string os;\n"
301870d1a7ccd70bd710128993de401278614d1975eYifan Hong            << getBitfieldType()->getCppStackType() << " flipped = 0;\n"
302870d1a7ccd70bd710128993de401278614d1975eYifan Hong            << "bool first = true;\n";
303f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        for (EnumValue *value : values()) {
304870d1a7ccd70bd710128993de401278614d1975eYifan Hong            std::string valueName = fullName() + "::" + value->name();
305870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out.sIf("(o & " + valueName + ")" +
306870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    " == static_cast<" + scalarType->getCppStackType() +
307870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    ">(" + valueName + ")", [&] {
308870d1a7ccd70bd710128993de401278614d1975eYifan Hong                out << "os += (first ? \"\" : \" | \");\n"
309870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    << "os += \"" << value->name() << "\";\n"
310f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong                    << "first = false;\n"
311870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    << "flipped |= " << valueName << ";\n";
312f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong            }).endl();
313f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        }
314870d1a7ccd70bd710128993de401278614d1975eYifan Hong        // put remaining bits
315870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out.sIf("o != flipped", [&] {
316870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out << "os += (first ? \"\" : \" | \");\n";
317870d1a7ccd70bd710128993de401278614d1975eYifan Hong            scalarType->emitHexDump(out, "os", "o & (~flipped)");
318870d1a7ccd70bd710128993de401278614d1975eYifan Hong        });
319f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "os += \" (\";\n";
320f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        scalarType->emitHexDump(out, "os", "o");
321f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "os += \")\";\n";
322f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
323f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "return os;\n";
324f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    }).endl().endl();
325f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
326870d1a7ccd70bd710128993de401278614d1975eYifan Hong    out << "std::string toString("
327870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << getCppArgumentType()
328870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << " o) ";
329870d1a7ccd70bd710128993de401278614d1975eYifan Hong
330870d1a7ccd70bd710128993de401278614d1975eYifan Hong    out.block([&] {
331870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "using ::android::hardware::details::toHexString;\n";
332870d1a7ccd70bd710128993de401278614d1975eYifan Hong        for (EnumValue *value : values()) {
333870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out.sIf("o == " + fullName() + "::" + value->name(), [&] {
334870d1a7ccd70bd710128993de401278614d1975eYifan Hong                out << "return \"" << value->name() << "\";\n";
335870d1a7ccd70bd710128993de401278614d1975eYifan Hong            }).endl();
336870d1a7ccd70bd710128993de401278614d1975eYifan Hong        }
337870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "std::string os;\n";
338870d1a7ccd70bd710128993de401278614d1975eYifan Hong        scalarType->emitHexDump(out, "os",
339870d1a7ccd70bd710128993de401278614d1975eYifan Hong            "static_cast<" + scalarType->getCppStackType() + ">(o)");
340870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "return os;\n";
341870d1a7ccd70bd710128993de401278614d1975eYifan Hong    }).endl().endl();
342870d1a7ccd70bd710128993de401278614d1975eYifan Hong
343e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    return OK;
344e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
345e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
34685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huberstatus_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool) const {
3472831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
3482831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    CHECK(scalarType != NULL);
3492831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3502831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "public final class "
3512831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << localName()
3522831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << " {\n";
3532831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3542831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.indent();
3552831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3564c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    const std::string typeName =
3574ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        scalarType->getJavaType(false /* forInitializer */);
3582831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3592831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    std::vector<const EnumType *> chain;
360864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
3612831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3622831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
3632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const auto &type = *it;
3642831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3652831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        for (const auto &entry : type->values()) {
3662831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            out << "public static final "
3672831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << typeName
3682831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << " "
369ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << entry->name()
370ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << " = ";
3712831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
372f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            // javaValue will make the number signed.
373fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->javaValue(scalarType->getKind());
374f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for java.
375f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << value;
3762831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
37719ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << ";";
37819ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
379fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
380fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
38119ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong                out << " // " << comment;
38219ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            }
38319ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
38419ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << "\n";
3852831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        }
3862831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    }
3872831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3882831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.unindent();
3892831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "};\n\n";
3902831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3912831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return OK;
3922831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
3932831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3945158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
395c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
396c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong
397bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "name: \"" << fullName() << "\"\n";
398c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
399c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "enum_value: {\n";
4005158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.indent();
401864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
402c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "scalar_type: \""
403c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong        << scalarType->getVtsScalarType()
404c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang        << "\"\n\n";
405864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    std::vector<const EnumType *> chain;
406864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
407864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
408864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
409864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const auto &type = *it;
410864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
411864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (const auto &entry : type->values()) {
412864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            out << "enumerator: \"" << entry->name() << "\"\n";
413c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "scalar_value: {\n";
414c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.indent();
415c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            // use autofilled values for vts.
416c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            std::string value = entry->value(scalarType->getKind());
417c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            CHECK(!value.empty());
418c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            out << mStorageType->resolveToScalarType()->getVtsScalarType()
419c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << ": "
420c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << value
421c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << "\n";
422c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.unindent();
423c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "}\n";
424864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
4255158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
426864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
4275158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.unindent();
4285158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "}\n";
4295158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
4305158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
4315158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
432864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangstatus_t EnumType::emitVtsAttributeType(Formatter &out) const {
433c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
434bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "predefined_type: \"" << fullName() << "\"\n";
4355158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
4365158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
4375158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
438864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangvoid EnumType::getTypeChain(std::vector<const EnumType *> *out) const {
439864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    out->clear();
440864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    const EnumType *type = this;
441864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (;;) {
442864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        out->push_back(type);
443864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
444864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const Type *superType = type->storageType();
445864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        if (superType == NULL || !superType->isEnum()) {
446864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            break;
447864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
448864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
449864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        type = static_cast<const EnumType *>(superType);
450864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
451864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang}
452864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
45385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
45485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mStorageType->getAlignmentAndSize(align, size);
45585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
45685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
457019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huberconst Annotation *EnumType::findExportAnnotation() const {
458019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (const auto &annotation : annotations()) {
459019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        if (annotation->name() == "export") {
460019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            return annotation;
461019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
462019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
463019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
464019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return nullptr;
465019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
466019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
467019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Hubervoid EnumType::appendToExportedTypesVector(
468019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::vector<const Type *> *exportedTypes) const {
469019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (findExportAnnotation() != nullptr) {
470019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        exportedTypes->push_back(this);
471019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
472019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
473019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
4741c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huberstatus_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
475019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const Annotation *annotation = findExportAnnotation();
476019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    CHECK(annotation != nullptr);
477019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
478019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::string name = localName();
479019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
480019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const AnnotationParam *nameParam = annotation->getParam("name");
481019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (nameParam != nullptr) {
482db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        name = nameParam->getSingleString();
483db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
484019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
485db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    bool exportParent = true;
486db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
487db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParentParam != nullptr) {
488db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        exportParent = exportParentParam->getSingleBool();
489019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
490019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
491b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    std::string valuePrefix;
492b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
493b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    if (prefixParam != nullptr) {
494db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valuePrefix = prefixParam->getSingleString();
495b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    }
496b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
49773cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    std::string valueSuffix;
49873cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
49973cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    if (suffixParam != nullptr) {
500db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valueSuffix = suffixParam->getSingleString();
50173cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    }
50273cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland
503019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
5041c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    CHECK(scalarType != nullptr);
505019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
506db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    std::vector<const EnumType *> chain;
507db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParent) {
508db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        getTypeChain(&chain);
509db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    } else {
510db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        chain = { this };
511db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
512db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland
5131c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    if (forJava) {
5141c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
5151c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "public final class "
5161c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << name
5171c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << " {\n";
5181c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5191c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.indent();
5201c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        } else {
5211c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "// Values declared in " << localName() << " follow.\n";
5221c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
5231c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5241c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        const std::string typeName =
5254ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            scalarType->getJavaType(false /* forInitializer */);
5261c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5271c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
5281c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            const auto &type = *it;
5291c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5301c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            for (const auto &entry : type->values()) {
5311c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "public static final "
5321c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << typeName
5331c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " "
5341c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << valuePrefix
5351c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << entry->name()
53673cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland                    << valueSuffix
5371c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " = ";
5381c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5391c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                // javaValue will make the number signed.
5401c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string value = entry->javaValue(scalarType->getKind());
5411c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                CHECK(!value.empty()); // use autofilled values for java.
5421c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << value;
5431c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5441c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << ";";
5451c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5461c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string comment = entry->comment();
5471c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                if (!comment.empty() && comment != value) {
5481c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    out << " // " << comment;
5491c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                }
5501c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5511c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "\n";
5521c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            }
5531c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
5541c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5551c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
5561c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.unindent();
5571c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "};\n";
5581c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
5591c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        out << "\n";
5601c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5611c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        return OK;
5621c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    }
563019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
564019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
565019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << "typedef ";
566019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
567019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
568019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "enum {\n";
569019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
570019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.indent();
571019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
572019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
573019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        const auto &type = *it;
574019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
575019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        for (const auto &entry : type->values()) {
57673cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland            out << valuePrefix << entry->name() << valueSuffix;
577019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
578019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string value = entry->cppValue(scalarType->getKind());
579019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            CHECK(!value.empty()); // use autofilled values for c++.
580019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << " = " << value;
581019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
582019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << ",";
583019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
584019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string comment = entry->comment();
585019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            if (!comment.empty() && comment != value) {
586019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber                out << " // " << comment;
587019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            }
588019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
589019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << "\n";
590019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
591019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
592019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
593019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.unindent();
594019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "}";
595019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
596019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
597019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << " " << name;
598019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
599019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
600019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << ";\n\n";
601019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
602019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return OK;
603019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
604019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
60531629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber////////////////////////////////////////////////////////////////////////////////
60631629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
607f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongEnumValue::EnumValue(const char *name, ConstantExpression *value)
60831629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    : mName(name),
609f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mValue(value),
610f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mIsAutoFill(false) {
61131629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
61231629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
61331629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huberstd::string EnumValue::name() const {
61431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    return mName;
61531629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
61631629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
617c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hongstd::string EnumValue::value(ScalarType::Kind castKind) const {
618f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
619c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    return mValue->value(castKind);
6205788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
6215788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
622fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::cppValue(ScalarType::Kind castKind) const {
623f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
624f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->cppValue(castKind);
6255788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
626fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::javaValue(ScalarType::Kind castKind) const {
627f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
628f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->javaValue(castKind);
62919ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong}
6305788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
631fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::comment() const {
632f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
633f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->description();
634f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
635f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
636f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongConstantExpression *EnumValue::constExpr() const {
637f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
638f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue;
639f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
640f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
641f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongvoid EnumValue::autofill(const EnumValue *prev, const ScalarType *type) {
642f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    if(mValue != nullptr)
643f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        return;
644f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mIsAutoFill = true;
645f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    ConstantExpression *value = new ConstantExpression();
646f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    if(prev == nullptr) {
647f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        *value = ConstantExpression::Zero(type->getKind());
648f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    } else {
649f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        CHECK(prev->mValue != nullptr);
650f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        *value = prev->mValue->addOne();
651f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
652f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mValue = value;
653f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
654f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
655f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isAutoFill() const {
656f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mIsAutoFill;
657f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
658f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
659f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isEnumValue() const {
660f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return true;
66131629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
66231629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
663abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong////////////////////////////////////////////////////////////////////////////////
664abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
665abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hongbool BitFieldType::isBitField() const {
666abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong    return true;
667abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong}
668abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
669c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::typeName() const {
670c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return "mask" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
671c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
672c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
673c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::addNamedTypesToSet(std::set<const FQName> &) const {
674c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
675c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
676c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongbool BitFieldType::isCompatibleElementType(Type *elementType) const {
677c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return elementType->isEnum();
678c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
679c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
680c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongconst ScalarType *BitFieldType::resolveToScalarType() const {
681c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return mElementType->resolveToScalarType();
682c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
683c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
684c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getCppType(StorageMode mode,
685c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                                 bool specifyNamespaces) const {
686c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getCppType(mode, specifyNamespaces);
687c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
688c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
689c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaType(bool forInitializer) const {
690c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaType(forInitializer);
691c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
692c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
693c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaSuffix() const {
694c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaSuffix();
695c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
696c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
697c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaWrapperType() const {
698c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaWrapperType();
699c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
700c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
701c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getVtsType() const {
702c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return "TYPE_MASK";
703c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
704c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
7058c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hongbool BitFieldType::isElidableType() const {
7068c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong    return resolveToScalarType()->isElidableType();
7078c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong}
7088c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong
7097d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hongbool BitFieldType::canCheckEquality() const {
7107d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong    return resolveToScalarType()->canCheckEquality();
7117d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong}
7127d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong
713c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstatus_t BitFieldType::emitVtsAttributeType(Formatter &out) const {
714c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "type: " << getVtsType() << "\n";
715132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang    out << "scalar_type: \""
716132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << mElementType->resolveToScalarType()->getVtsScalarType()
717132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << "\"\n";
71836ccc72a467965067544cd40f17c2f3408d4c97bKeun Soo Yim    out << "predefined_type: \""
71936ccc72a467965067544cd40f17c2f3408d4c97bKeun Soo Yim        << static_cast<NamedType *>(mElementType)->fullName() << "\"\n";
720c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return OK;
721c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
722c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
723c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
724c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->getAlignmentAndSize(align, size);
725c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
726c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
727c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitReaderWriter(
728c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
729c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &name,
730c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelObj,
731c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool parcelObjIsPointer,
732c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader,
733c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        ErrorMode mode) const {
734c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->emitReaderWriterWithCast(
735c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out,
736c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            name,
737c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObj,
738c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObjIsPointer,
739c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            isReader,
740c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            mode,
741c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            true /* needsCast */);
742c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
743c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
744f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// a bitfield maps to the underlying scalar type in C++, so operator<< is
745f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// already defined. We can still emit useful information if the bitfield is
746f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// in a struct / union by overriding emitDump as below.
747f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hongvoid BitFieldType::emitDump(
748f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        Formatter &out,
749f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &streamName,
750f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &name) const {
751f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    CHECK(mElementType->isEnum());
752f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    const EnumType *enumType = static_cast<EnumType *>(mElementType);
753f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << streamName << " += "<< enumType->fqName().cppNamespace()
754f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "::toString<" << enumType->getCppStackType()
755f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << ">(" << name << ");\n";
756f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
757f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
758c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitJavaFieldReaderWriter(
759c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
760c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        size_t depth,
761c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelName,
762c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &blobName,
763c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &fieldName,
764c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &offset,
765c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader) const {
766c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->emitJavaFieldReaderWriter(
767c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out, depth, parcelName, blobName, fieldName, offset, isReader);
768c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
769c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
770c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
771c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
772