diff options
author | Christopher Wiley <wiley@google.com> | 2016-02-02 17:58:39 -0800 |
---|---|---|
committer | Christopher Wiley <wiley@google.com> | 2016-02-04 17:12:56 +0000 |
commit | fd7dc03fdd1e0cd558df43a155ab1644cbe2b553 (patch) | |
tree | 300b3bbee480021838b64e9c893bfabf5df20b23 | |
parent | 2359cddf18b1d37787cc398c4c567a776802c7ba (diff) | |
download | aidl-fd7dc03fdd1e0cd558df43a155ab1644cbe2b553.tar.gz |
Declare interface constants as enum in C++
While constexpr hints to the compiler that it can optimize
away the address of these integer expressions, it does not
mandate this behavior. This can cause linkage errors when
the same generated header is included from multiple compilation
units and everyone expects the integer constant to defined
elsewhere.
Bug: 26942276
Test: unittests pass
Change-Id: I7dfda08b5226344d5169b3f298413cd8a1ceb692
-rw-r--r-- | ast_cpp.cpp | 19 | ||||
-rw-r--r-- | ast_cpp.h | 17 | ||||
-rw-r--r-- | generate_cpp.cpp | 9 | ||||
-rw-r--r-- | generate_cpp_unittest.cpp | 4 | ||||
-rw-r--r-- | tests/test_helpers.h | 4 |
5 files changed, 23 insertions, 30 deletions
diff --git a/ast_cpp.cpp b/ast_cpp.cpp index b5eb69cb..6cb4a466 100644 --- a/ast_cpp.cpp +++ b/ast_cpp.cpp @@ -72,22 +72,21 @@ void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) { private_members_.push_back(std::move(member)); } -ConstDecl::ConstDecl(const std::string& name, int value) - : name_(name), - value_(value) {} - -void ConstDecl::Write(CodeWriter* to) const { - to->Write("static constexpr int32_t %s = %d;\n", name_.c_str(), value_); -} - Enum::EnumField::EnumField(const string& k, const string& v) : key(k), value(v) {} -Enum::Enum(const string& name) : enum_name_(name) {} +Enum::Enum(const string& name, const string& base_type) + : enum_name_(name), underlying_type_(base_type) {} + +Enum::Enum(const string& name) : Enum(name, "") {} void Enum::Write(CodeWriter* to) const { - to->Write("enum %s {\n", enum_name_.c_str()); + if (underlying_type_.empty()) { + to->Write("enum %s {\n", enum_name_.c_str()); + } else { + to->Write("enum %s : %s {\n", enum_name_.c_str(), underlying_type_.c_str()); + } for (const auto& field : fields_) { if (field.value.empty()) { to->Write(" %s,\n", field.key.c_str()); @@ -73,25 +73,13 @@ class ClassDecl : public Declaration { DISALLOW_COPY_AND_ASSIGN(ClassDecl); }; // class ClassDecl -class ConstDecl : public Declaration { - public: - ConstDecl(const std::string& name, int value); - virtual ~ConstDecl() = default; - - void Write(CodeWriter* to) const override; - - private: - std::string name_; - int value_; - - DISALLOW_COPY_AND_ASSIGN(ConstDecl); -}; // class ConstDecl - class Enum : public Declaration { public: + Enum(const std::string& name, const std::string& base_type); explicit Enum(const std::string& name); virtual ~Enum() = default; + bool HasValues() const { return !fields_.empty(); } void Write(CodeWriter* to) const override; void AddValue(const std::string& key, const std::string& value); @@ -104,6 +92,7 @@ class Enum : public Declaration { }; std::string enum_name_; + std::string underlying_type_; std::vector<EnumField> fields_; DISALLOW_COPY_AND_ASSIGN(Enum); diff --git a/generate_cpp.cpp b/generate_cpp.cpp index de4ab5a9..f9ce9f7b 100644 --- a/generate_cpp.cpp +++ b/generate_cpp.cpp @@ -676,10 +676,13 @@ unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types, "DECLARE_META_INTERFACE", ArgList{vector<string>{ClassName(interface, ClassNames::BASE)}}}}); + unique_ptr<Enum> constant_enum{new Enum{"", "int32_t"}}; for (const auto& constant : interface.GetConstants()) { - unique_ptr<ConstDecl> declaration{ - new ConstDecl(constant->GetName(), constant->GetValue())}; - if_class->AddPublic(std::move(declaration)); + constant_enum->AddValue( + constant->GetName(), std::to_string(constant->GetValue())); + } + if (constant_enum->HasValues()) { + if_class->AddPublic(std::move(constant_enum)); } unique_ptr<Enum> call_enum{new Enum{"Call"}}; diff --git a/generate_cpp_unittest.cpp b/generate_cpp_unittest.cpp index cb72ec19..f5650cb8 100644 --- a/generate_cpp_unittest.cpp +++ b/generate_cpp_unittest.cpp @@ -607,7 +607,9 @@ namespace os { class IComplexTypeInterface : public ::android::IInterface { public: DECLARE_META_INTERFACE(ComplexTypeInterface); -static constexpr int32_t MY_CONSTANT = 3; +enum : int32_t { + MY_CONSTANT = 3, +}; virtual ::android::binder::Status Send(const ::std::unique_ptr<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) = 0; virtual ::android::binder::Status Piff(int32_t times) = 0; virtual ::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) = 0; diff --git a/tests/test_helpers.h b/tests/test_helpers.h index 638eecc2..7d5145bb 100644 --- a/tests/test_helpers.h +++ b/tests/test_helpers.h @@ -28,11 +28,11 @@ namespace aidl { namespace tests { namespace client { -template <typename T> +template <typename T, typename U> bool RepeatPrimitive( const android::sp<android::aidl::tests::ITestService>& service, android::binder::Status(android::aidl::tests::ITestService::*func)(T, T*), - const T input) { + U input) { T reply; android::binder::Status status = (*service.*func)(input, &reply); if (!status.isOk() || input != reply) { |