Enum types now emit operator| and operator|= for easier bitset manipulation.
Bug: 31702236
Change-Id: I166da2fe0019493c81151914ebabf591b705a713
Test: visual check, mma
diff --git a/EnumType.cpp b/EnumType.cpp
index 5513596..8f959e7 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -144,14 +144,15 @@
status_t EnumType::emitTypeDeclarations(Formatter &out) const {
const ScalarType *scalarType = mStorageType->resolveToScalarType();
- CHECK(scalarType != NULL);
+ CHECK(scalarType != nullptr);
std::string extra;
+ const std::string storageType = ((Type *)scalarType)->getCppType(&extra);
out << "enum class "
<< localName()
<< " : "
- << ((Type *)scalarType)->getCppType(&extra)
+ << storageType
<< " {\n";
out.indent();
@@ -186,6 +187,64 @@
return OK;
}
+void EnumType::emitEnumBitwiseOrOperator(Formatter &out, bool mutating) const {
+ const ScalarType *scalarType = mStorageType->resolveToScalarType();
+ CHECK(scalarType != nullptr);
+
+ std::string extra;
+ const std::string storageType = ((Type *)scalarType)->getCppType(&extra);
+
+ out << "inline "
+ << fullName()
+ << (mutating ? " &" : "")
+ << " operator|"
+ << (mutating ? "=" : "")
+ << "(\n";
+
+ out.indent();
+ out.indent();
+
+ out << fullName()
+ << (mutating ? " &" : " ")
+ << "lhs, "
+ << fullName()
+ << " rhs) {\n";
+ out.unindent();
+
+ if (mutating) {
+ out << "lhs = ";
+ } else {
+ out << "return ";
+ }
+ out << "static_cast<"
+ << fullName()
+ << ">(\n";
+ out.indent();
+ out.indent();
+ out << "static_cast<"
+ << storageType
+ << ">(lhs) | static_cast<"
+ << storageType
+ << ">(rhs));\n";
+ out.unindent();
+ out.unindent();
+
+ if (mutating) {
+ out << "return lhs;\n";
+ }
+
+ out.unindent();
+
+ out << "}\n\n";
+}
+
+status_t EnumType::emitGlobalTypeDeclarations(Formatter &out) const {
+ emitEnumBitwiseOrOperator(out, false /* mutating */);
+ emitEnumBitwiseOrOperator(out, true /* mutating */);
+
+ return OK;
+}
+
status_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool) const {
const ScalarType *scalarType = mStorageType->resolveToScalarType();
CHECK(scalarType != NULL);
diff --git a/EnumType.h b/EnumType.h
index b4d0b15..e7823ef 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -72,6 +72,7 @@
bool isReader) const override;
status_t emitTypeDeclarations(Formatter &out) const override;
+ status_t emitGlobalTypeDeclarations(Formatter &out) const override;
status_t emitJavaTypeDeclarations(
Formatter &out, bool atTopLevel) const override;
@@ -90,6 +91,8 @@
void getTypeChain(std::vector<const EnumType *> *out) const;
const Annotation *findExportAnnotation() const;
+ void emitEnumBitwiseOrOperator(Formatter &out, bool mutating) const;
+
std::vector<EnumValue *> mValues;
Type *mStorageType;
diff --git a/Scope.cpp b/Scope.cpp
index 452a41f..c4d07c2 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -141,6 +141,18 @@
return OK;
}
+status_t Scope::emitGlobalTypeDeclarations(Formatter &out) const {
+ for (size_t i = 0; i < mTypes.size(); ++i) {
+ status_t err = mTypes[i]->emitGlobalTypeDeclarations(out);
+
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ return OK;
+}
+
status_t Scope::emitJavaTypeDeclarations(
Formatter &out, bool atTopLevel) const {
for (size_t i = 0; i < mTypes.size(); ++i) {
diff --git a/Scope.h b/Scope.h
index 08683dd..fd6074c 100644
--- a/Scope.h
+++ b/Scope.h
@@ -52,6 +52,7 @@
std::string pickUniqueAnonymousName() const;
status_t emitTypeDeclarations(Formatter &out) const override;
+ status_t emitGlobalTypeDeclarations(Formatter &out) const override;
status_t emitJavaTypeDeclarations(
Formatter &out, bool atTopLevel) const override;
diff --git a/Type.cpp b/Type.cpp
index d81eeef..eafda3a 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -321,6 +321,10 @@
return OK;
}
+status_t Type::emitGlobalTypeDeclarations(Formatter &) const {
+ return OK;
+}
+
status_t Type::emitTypeDefinitions(
Formatter &, const std::string) const {
return OK;
diff --git a/Type.h b/Type.h
index f510340..04141ff 100644
--- a/Type.h
+++ b/Type.h
@@ -164,6 +164,10 @@
virtual status_t emitTypeDeclarations(Formatter &out) const;
+ // Emit any declarations pertaining to this type that have to be
+ // at global scope, i.e. enum class operators.
+ virtual status_t emitGlobalTypeDeclarations(Formatter &out) const;
+
virtual status_t emitTypeDefinitions(
Formatter &out, const std::string prefix) const;
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 680a7b8..f8a5b1a 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -263,7 +263,13 @@
if (isInterface) {
out.unindent();
- out << "};\n";
+ out << "};\n\n";
+ }
+
+ err = mRootScope->emitGlobalTypeDeclarations(out);
+
+ if (err != OK) {
+ return err;
}
out << "\n";