EnumType.cpp revision 132362395dbc1ec52a70a5a4587ce1dd7616a8da
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
270f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<typename>\n"
271f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString("
272f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << resolveToScalarType()->getCppArgumentType()
273f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o);\n";
274f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
275f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString<" << getCppStackType() << ">("
276f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << resolveToScalarType()->getCppArgumentType()
277f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o);\n\n";
278f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
279f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "inline std::string toString("
280f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << getCppArgumentType()
281f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o) ";
282f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
283f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out.block([&] {
284f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "return toString<" << getCppStackType() << ">("
285f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong            << "static_cast<" << resolveToScalarType()->getCppStackType() << ">(o));\n";
286f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    }).endl().endl();
287f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
288f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    return OK;
289f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
290f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
291f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hongstatus_t EnumType::emitTypeDefinitions(Formatter &out, const std::string /* prefix */) const {
292f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
293f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
294f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    CHECK(scalarType != NULL);
295f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
296f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
297f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString<" << getCppStackType() << ">("
298f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << resolveToScalarType()->getCppArgumentType()
299f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o) ";
300f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out.block([&] {
301f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        // include toHexString for scalar types
302f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "using ::android::hardware::details::toHexString;\n"
303f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong            << "std::string os;\n";
304f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "bool first = true;\n";
305f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        for (EnumValue *value : values()) {
306f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong            out.sIf("o & " + fullName() + "::" + value->name(), [&] {
307f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong                out << "os += (first ? \"\" : \" | \"); "
308f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong                    << "first = false;\n"
309f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong                    << "os += \"" << value->name() << "\";\n";
310f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong            }).endl();
311f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        }
312f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "os += \" (\";\n";
313f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        scalarType->emitHexDump(out, "os", "o");
314f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "os += \")\";\n";
315f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
316f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "return os;\n";
317f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    }).endl().endl();
318f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
319e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    return OK;
320e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
321e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
32285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huberstatus_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool) const {
3232831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
3242831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    CHECK(scalarType != NULL);
3252831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3262831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "public final class "
3272831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << localName()
3282831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << " {\n";
3292831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3302831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.indent();
3312831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3324c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    const std::string typeName =
3334ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        scalarType->getJavaType(false /* forInitializer */);
3342831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3352831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    std::vector<const EnumType *> chain;
336864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
3372831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3382831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
3392831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const auto &type = *it;
3402831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3412831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        for (const auto &entry : type->values()) {
3422831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            out << "public static final "
3432831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << typeName
3442831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << " "
345ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << entry->name()
346ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << " = ";
3472831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
348f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            // javaValue will make the number signed.
349fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->javaValue(scalarType->getKind());
350f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for java.
351f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << value;
3522831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
35319ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << ";";
35419ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
355fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
356fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
35719ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong                out << " // " << comment;
35819ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            }
35919ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
36019ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << "\n";
3612831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        }
3622831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    }
3632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3642831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.unindent();
3652831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "};\n\n";
3662831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3672831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return OK;
3682831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
3692831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
3705158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
371c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
372c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong
373bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "name: \"" << fullName() << "\"\n";
374c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
375c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "enum_value: {\n";
3765158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.indent();
377864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
378c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "scalar_type: \""
379c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong        << scalarType->getVtsScalarType()
380c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang        << "\"\n\n";
381864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    std::vector<const EnumType *> chain;
382864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
383864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
384864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
385864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const auto &type = *it;
386864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
387864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (const auto &entry : type->values()) {
388864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            out << "enumerator: \"" << entry->name() << "\"\n";
389c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "scalar_value: {\n";
390c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.indent();
391c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            // use autofilled values for vts.
392c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            std::string value = entry->value(scalarType->getKind());
393c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            CHECK(!value.empty());
394c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            out << mStorageType->resolveToScalarType()->getVtsScalarType()
395c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << ": "
396c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << value
397c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << "\n";
398c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.unindent();
399c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "}\n";
400864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
4015158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
402864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
4035158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.unindent();
4045158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "}\n";
4055158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
4065158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
4075158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
408864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangstatus_t EnumType::emitVtsAttributeType(Formatter &out) const {
409c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
410bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "predefined_type: \"" << fullName() << "\"\n";
4115158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
4125158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
4135158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
414864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangvoid EnumType::getTypeChain(std::vector<const EnumType *> *out) const {
415864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    out->clear();
416864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    const EnumType *type = this;
417864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (;;) {
418864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        out->push_back(type);
419864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
420864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const Type *superType = type->storageType();
421864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        if (superType == NULL || !superType->isEnum()) {
422864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            break;
423864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
424864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
425864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        type = static_cast<const EnumType *>(superType);
426864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
427864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang}
428864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
42985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
43085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mStorageType->getAlignmentAndSize(align, size);
43185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
43285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
433019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huberconst Annotation *EnumType::findExportAnnotation() const {
434019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (const auto &annotation : annotations()) {
435019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        if (annotation->name() == "export") {
436019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            return annotation;
437019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
438019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
439019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
440019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return nullptr;
441019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
442019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
443019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Hubervoid EnumType::appendToExportedTypesVector(
444019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::vector<const Type *> *exportedTypes) const {
445019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (findExportAnnotation() != nullptr) {
446019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        exportedTypes->push_back(this);
447019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
448019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
449019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
4501c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huberstatus_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
451019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const Annotation *annotation = findExportAnnotation();
452019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    CHECK(annotation != nullptr);
453019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
454019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::string name = localName();
455019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
456019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const AnnotationParam *nameParam = annotation->getParam("name");
457019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (nameParam != nullptr) {
458db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        name = nameParam->getSingleString();
459db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
460019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
461db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    bool exportParent = true;
462db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
463db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParentParam != nullptr) {
464db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        exportParent = exportParentParam->getSingleBool();
465019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
466019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
467b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    std::string valuePrefix;
468b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
469b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    if (prefixParam != nullptr) {
470db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valuePrefix = prefixParam->getSingleString();
471b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    }
472b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
47373cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    std::string valueSuffix;
47473cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
47573cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    if (suffixParam != nullptr) {
476db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valueSuffix = suffixParam->getSingleString();
47773cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    }
47873cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland
479019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
4801c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    CHECK(scalarType != nullptr);
481019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
482db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    std::vector<const EnumType *> chain;
483db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParent) {
484db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        getTypeChain(&chain);
485db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    } else {
486db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        chain = { this };
487db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
488db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland
4891c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    if (forJava) {
4901c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
4911c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "public final class "
4921c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << name
4931c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << " {\n";
4941c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4951c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.indent();
4961c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        } else {
4971c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "// Values declared in " << localName() << " follow.\n";
4981c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
4991c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5001c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        const std::string typeName =
5014ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            scalarType->getJavaType(false /* forInitializer */);
5021c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5031c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
5041c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            const auto &type = *it;
5051c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5061c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            for (const auto &entry : type->values()) {
5071c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "public static final "
5081c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << typeName
5091c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " "
5101c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << valuePrefix
5111c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << entry->name()
51273cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland                    << valueSuffix
5131c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " = ";
5141c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5151c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                // javaValue will make the number signed.
5161c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string value = entry->javaValue(scalarType->getKind());
5171c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                CHECK(!value.empty()); // use autofilled values for java.
5181c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << value;
5191c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5201c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << ";";
5211c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5221c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string comment = entry->comment();
5231c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                if (!comment.empty() && comment != value) {
5241c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    out << " // " << comment;
5251c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                }
5261c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5271c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "\n";
5281c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            }
5291c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
5301c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5311c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
5321c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.unindent();
5331c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "};\n";
5341c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
5351c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        out << "\n";
5361c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
5371c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        return OK;
5381c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    }
539019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
540019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
541019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << "typedef ";
542019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
543019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
544019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "enum {\n";
545019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
546019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.indent();
547019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
548019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
549019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        const auto &type = *it;
550019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
551019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        for (const auto &entry : type->values()) {
55273cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland            out << valuePrefix << entry->name() << valueSuffix;
553019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
554019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string value = entry->cppValue(scalarType->getKind());
555019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            CHECK(!value.empty()); // use autofilled values for c++.
556019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << " = " << value;
557019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
558019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << ",";
559019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
560019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string comment = entry->comment();
561019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            if (!comment.empty() && comment != value) {
562019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber                out << " // " << comment;
563019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            }
564019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
565019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << "\n";
566019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
567019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
568019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
569019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.unindent();
570019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "}";
571019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
572019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
573019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << " " << name;
574019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
575019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
576019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << ";\n\n";
577019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
578019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return OK;
579019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
580019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
58131629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber////////////////////////////////////////////////////////////////////////////////
58231629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
583f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongEnumValue::EnumValue(const char *name, ConstantExpression *value)
58431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    : mName(name),
585f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mValue(value),
586f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mIsAutoFill(false) {
58731629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
58831629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
58931629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huberstd::string EnumValue::name() const {
59031629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    return mName;
59131629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
59231629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
593c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hongstd::string EnumValue::value(ScalarType::Kind castKind) const {
594f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
595c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    return mValue->value(castKind);
5965788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
5975788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
598fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::cppValue(ScalarType::Kind castKind) const {
599f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
600f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->cppValue(castKind);
6015788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
602fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::javaValue(ScalarType::Kind castKind) const {
603f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
604f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->javaValue(castKind);
60519ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong}
6065788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
607fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::comment() const {
608f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
609f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->description();
610f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
611f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
612f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongConstantExpression *EnumValue::constExpr() const {
613f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
614f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue;
615f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
616f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
617f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongvoid EnumValue::autofill(const EnumValue *prev, const ScalarType *type) {
618f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    if(mValue != nullptr)
619f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        return;
620f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mIsAutoFill = true;
621f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    ConstantExpression *value = new ConstantExpression();
622f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    if(prev == nullptr) {
623f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        *value = ConstantExpression::Zero(type->getKind());
624f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    } else {
625f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        CHECK(prev->mValue != nullptr);
626f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        *value = prev->mValue->addOne();
627f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
628f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mValue = value;
629f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
630f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
631f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isAutoFill() const {
632f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mIsAutoFill;
633f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
634f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
635f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isEnumValue() const {
636f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return true;
63731629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
63831629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
639abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong////////////////////////////////////////////////////////////////////////////////
640abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
641abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hongbool BitFieldType::isBitField() const {
642abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong    return true;
643abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong}
644abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
645c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::typeName() const {
646c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return "mask" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
647c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
648c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
649c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::addNamedTypesToSet(std::set<const FQName> &) const {
650c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
651c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
652c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongbool BitFieldType::isCompatibleElementType(Type *elementType) const {
653c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return elementType->isEnum();
654c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
655c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
656c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongconst ScalarType *BitFieldType::resolveToScalarType() const {
657c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return mElementType->resolveToScalarType();
658c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
659c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
660c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getCppType(StorageMode mode,
661c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                                 bool specifyNamespaces) const {
662c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getCppType(mode, specifyNamespaces);
663c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
664c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
665c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaType(bool forInitializer) const {
666c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaType(forInitializer);
667c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
668c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
669c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaSuffix() const {
670c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaSuffix();
671c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
672c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
673c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaWrapperType() const {
674c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaWrapperType();
675c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
676c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
677c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getVtsType() const {
678c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return "TYPE_MASK";
679c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
680c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
6818c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hongbool BitFieldType::isElidableType() const {
6828c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong    return resolveToScalarType()->isElidableType();
6838c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong}
6848c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong
685c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstatus_t BitFieldType::emitVtsAttributeType(Formatter &out) const {
686c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "type: " << getVtsType() << "\n";
687132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang    out << "scalar_type: \""
688132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << mElementType->resolveToScalarType()->getVtsScalarType()
689132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << "\"\n";
69036ccc72a467965067544cd40f17c2f3408d4c97bKeun Soo Yim    out << "predefined_type: \""
69136ccc72a467965067544cd40f17c2f3408d4c97bKeun Soo Yim        << static_cast<NamedType *>(mElementType)->fullName() << "\"\n";
692c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return OK;
693c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
694c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
695c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
696c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->getAlignmentAndSize(align, size);
697c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
698c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
699c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitReaderWriter(
700c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
701c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &name,
702c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelObj,
703c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool parcelObjIsPointer,
704c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader,
705c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        ErrorMode mode) const {
706c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->emitReaderWriterWithCast(
707c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out,
708c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            name,
709c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObj,
710c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObjIsPointer,
711c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            isReader,
712c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            mode,
713c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            true /* needsCast */);
714c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
715c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
716f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// a bitfield maps to the underlying scalar type in C++, so operator<< is
717f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// already defined. We can still emit useful information if the bitfield is
718f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// in a struct / union by overriding emitDump as below.
719f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hongvoid BitFieldType::emitDump(
720f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        Formatter &out,
721f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &streamName,
722f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &name) const {
723f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    CHECK(mElementType->isEnum());
724f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    const EnumType *enumType = static_cast<EnumType *>(mElementType);
725f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << streamName << " += "<< enumType->fqName().cppNamespace()
726f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "::toString<" << enumType->getCppStackType()
727f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << ">(" << name << ");\n";
728f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
729f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
730c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitJavaFieldReaderWriter(
731c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
732c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        size_t depth,
733c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelName,
734c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &blobName,
735c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &fieldName,
736c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &offset,
737c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader) const {
738c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->emitJavaFieldReaderWriter(
739c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out, depth, parcelName, blobName, fieldName, offset, isReader);
740c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
741c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
742c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
743c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
744