aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Wiley <wiley@google.com>2016-02-02 17:58:39 -0800
committerChristopher Wiley <wiley@google.com>2016-02-04 17:12:56 +0000
commitfd7dc03fdd1e0cd558df43a155ab1644cbe2b553 (patch)
tree300b3bbee480021838b64e9c893bfabf5df20b23
parent2359cddf18b1d37787cc398c4c567a776802c7ba (diff)
downloadaidl-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.cpp19
-rw-r--r--ast_cpp.h17
-rw-r--r--generate_cpp.cpp9
-rw-r--r--generate_cpp_unittest.cpp4
-rw-r--r--tests/test_helpers.h4
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());
diff --git a/ast_cpp.h b/ast_cpp.h
index 291e7eba..fded9938 100644
--- a/ast_cpp.h
+++ b/ast_cpp.h
@@ -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) {