Implementing Discriminated Unions in HIDL
This change augments hidl-gen to generate C++ code for HIDL safe_union
constructs. The HIDL declaration is similar to regular structs/unions:
safe_union SafeUnion {
uint8_t a;
string b;
}
The emitted C++ code is:
struct SafeUnion final {
public:
enum class hidl_discriminator : uint8_t {
a,
b,
hidl_no_init
};
SafeUnion();
~SafeUnion();
SafeUnion(const SafeUnion&);
void a(uint8_t);
uint8_t& a();
uint8_t a() const;
void b(const ::android::hardware::hidl_string&);
::android::hardware::hidl_string& b();
const ::android::hardware::hidl_string& b() const;
// Utility method
hidl_discriminator getDiscriminator() const;
private:
void hidl_destructUnion();
union hidl_union final {
uint8_t a __attribute__ ((aligned(1)));
::android::hardware::hidl_string b __attribute__ ((aligned(8)));
hidl_union();
~hidl_union();
} u;
hidl_discriminator d __attribute__ ((aligned(1)))\
{hidl_discriminator::hidl_no_init};
};
Also synthesizes the appropriate toString, operator== and
{read,write}Embedded{From,To}Parcel methods.
Bug: 79878527
Test: Ran the existing hidl_test suite, tested safe_union get/set
methods on a test HAL.
Change-Id: I894c144204ab3bdbe446022b2805a64a211d28b3
Merged-In: I894c144204ab3bdbe446022b2805a64a211d28b3
diff --git a/CompoundType.h b/CompoundType.h
index 7295f40..58961d1 100644
--- a/CompoundType.h
+++ b/CompoundType.h
@@ -29,6 +29,7 @@
enum Style {
STYLE_STRUCT,
STYLE_UNION,
+ STYLE_SAFE_UNION,
};
CompoundType(Style style, const char* localName, const FQName& fullName,
@@ -48,6 +49,7 @@
status_t validate() const override;
status_t validateUniqueNames() const;
+ status_t validateSubTypeNames() const;
std::string getCppType(StorageMode mode,
bool specifyNamespaces) const override;
@@ -142,9 +144,38 @@
bool containsInterface() const;
private:
+
+ struct Layout {
+ size_t offset;
+ size_t align;
+ size_t size;
+
+ Layout() : offset(0), align(1), size(0) {}
+ static size_t getPad(size_t offset, size_t align);
+ };
+
+ struct CompoundLayout {
+ Layout overall;
+ Layout innerStruct;
+ Layout discriminator;
+ };
+
Style mStyle;
std::vector<NamedReference<Type>*>* mFields;
+ void emitLayoutAsserts(Formatter& out, const Layout& localLayout,
+ const std::string& localLayoutName) const;
+
+ void emitInvalidSubTypeNamesError(const std::string& subTypeName,
+ const Location& location) const;
+
+ void emitSafeUnionTypeDefinitions(Formatter& out) const;
+ void emitSafeUnionTypeConstructors(Formatter& out) const;
+ void emitSafeUnionTypeDeclarations(Formatter& out) const;
+ std::unique_ptr<ScalarType> getUnionDiscriminatorType() const;
+
+ CompoundLayout getCompoundAlignmentAndSize() const;
+
void emitStructReaderWriter(
Formatter &out, const std::string &prefix, bool isReader) const;
void emitResolveReferenceDef(Formatter& out, const std::string& prefix, bool isReader) const;