diff options
9 files changed, 46 insertions, 20 deletions
diff --git a/aidl_const_expressions.cpp b/aidl_const_expressions.cpp index b3a1667d..eeeb14b3 100644 --- a/aidl_const_expressions.cpp +++ b/aidl_const_expressions.cpp @@ -343,6 +343,9 @@ AidlConstantValue* AidlConstantValue::Default(const AidlTypeSpecifier& specifier if (name == "boolean") { return Boolean(location, false); } + if (name == "char") { + return Character(location, "'\\0'"); // literal to be used in backends + } if (name == "byte" || name == "int" || name == "long") { return Integral(location, "0"); } @@ -359,13 +362,22 @@ AidlConstantValue* AidlConstantValue::Boolean(const AidlLocation& location, bool return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false"); } -AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, char value) { - const std::string explicit_value = string("'") + value + "'"; - if (!isValidLiteralChar(value)) { - AIDL_ERROR(location) << "Invalid character literal " << value; - return new AidlConstantValue(location, Type::ERROR, explicit_value); +AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, + const std::string& value) { + static const char* kZeroString = "'\\0'"; + + // We should have better supports for escapes in the future, but for now + // allow only what is needed for defaults. + if (value != kZeroString) { + AIDL_FATAL_IF(value.size() != 3 || value[0] != '\'' || value[2] != '\'', location) << value; + + if (!isValidLiteralChar(value[1])) { + AIDL_ERROR(location) << "Invalid character literal " << value[1]; + return new AidlConstantValue(location, Type::ERROR, value); + } } - return new AidlConstantValue(location, Type::CHARACTER, explicit_value); + + return new AidlConstantValue(location, Type::CHARACTER, value); } AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location, @@ -1055,6 +1067,8 @@ bool AidlBinaryConstExpression::evaluate() const { return false; } +// Constructor for integer(byte, int, long) +// Keep parsed integer & literal AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type parsed_type, int64_t parsed_value, const string& checked_value) : AidlNode(location), @@ -1066,6 +1080,8 @@ AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type parsed_t AIDL_FATAL_IF(type_ != Type::INT8 && type_ != Type::INT32 && type_ != Type::INT64, location); } +// Constructor for non-integer(String, char, boolean, float, double) +// Keep literal as it is. (e.g. String literal has double quotes at both ends) AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type, const string& checked_value) : AidlNode(location), @@ -1085,6 +1101,7 @@ AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type, } } +// Constructor for array AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type, std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values, const std::string& value) diff --git a/aidl_language.h b/aidl_language.h index 9b169205..c73618f1 100644 --- a/aidl_language.h +++ b/aidl_language.h @@ -644,7 +644,7 @@ class AidlConstantValue : public AidlNode { } else if constexpr (is_one_of<T, int8_t, int32_t, int64_t>::value) { AIDL_FATAL_IF(final_type_ < Type::INT8 && final_type_ > Type::INT64, this); return static_cast<T>(final_value_); - } else if constexpr (std::is_same<T, char>::value) { + } else if constexpr (std::is_same<T, char16_t>::value) { AIDL_FATAL_IF(final_type_ != Type::CHARACTER, this); return final_string_value_.at(1); // unquote ' } else if constexpr (std::is_same<T, bool>::value) { @@ -669,9 +669,9 @@ class AidlConstantValue : public AidlNode { static AidlConstantValue* Default(const AidlTypeSpecifier& specifier); static AidlConstantValue* Boolean(const AidlLocation& location, bool value); - static AidlConstantValue* Character(const AidlLocation& location, char value); + static AidlConstantValue* Character(const AidlLocation& location, const std::string& value); // example: 123, -5498, maybe any size - static AidlConstantValue* Integral(const AidlLocation& location, const string& value); + static AidlConstantValue* Integral(const AidlLocation& location, const std::string& value); static AidlConstantValue* Floating(const AidlLocation& location, const std::string& value); static AidlConstantValue* Array(const AidlLocation& location, std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values); diff --git a/aidl_language_l.ll b/aidl_language_l.ll index a286a7fa..33054a36 100644 --- a/aidl_language_l.ll +++ b/aidl_language_l.ll @@ -142,9 +142,8 @@ union { yylval->token = new AidlToken("union", comments); {identifier} { yylval->token = new AidlToken(yytext, comments); return yy::parser::token::IDENTIFIER; } -'.' { yylval->character = yytext[1]; - return yy::parser::token::CHARVALUE; - } +'.' { yylval->token = new AidlToken(yytext, comments); + return yy::parser::token::CHARVALUE; } {intvalue} { yylval->token = new AidlToken(yytext, comments); return yy::parser::token::INTVALUE; } {floatvalue} { yylval->token = new AidlToken(yytext, comments); diff --git a/aidl_language_y.yy b/aidl_language_y.yy index 7f0b5bf7..11ab29e9 100644 --- a/aidl_language_y.yy +++ b/aidl_language_y.yy @@ -94,7 +94,6 @@ AidlLocation loc(const yy::parser::location_type& l) { std::vector<std::unique_ptr<AidlDefinedType>>* declarations; } -%destructor { } <character> %destructor { } <direction> %destructor { delete ($$); } <*> @@ -110,7 +109,7 @@ AidlLocation loc(const yy::parser::location_type& l) { %token<token> UNION "union" %token<token> CONST "const" -%token<character> CHARVALUE "char literal" +%token<token> CHARVALUE "char literal" %token<token> FLOATVALUE "float literal" %token<token> HEXVALUE "hex literal" %token<token> INTVALUE "int literal" @@ -408,7 +407,10 @@ interface_members const_expr : TRUE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), true); } | FALSE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), false); } - | CHARVALUE { $$ = AidlConstantValue::Character(loc(@1), $1); } + | CHARVALUE { + $$ = AidlConstantValue::Character(loc(@1), $1->GetText()); + delete $1; + } | INTVALUE { $$ = AidlConstantValue::Integral(loc(@1), $1->GetText()); if ($$ == nullptr) { diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp index c783c0cb..5a975fe6 100644 --- a/aidl_unittest.cpp +++ b/aidl_unittest.cpp @@ -1336,7 +1336,7 @@ TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) { using Ptr = unique_ptr<AidlConstantValue>; const AidlLocation& loc = AIDL_LOCATION_HERE; - EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, 'c'))->EvaluatedValue<char>()); + EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, "'c'"))->EvaluatedValue<char16_t>()); EXPECT_EQ("abc", Ptr(AidlConstantValue::String(loc, "\"abc\""))->EvaluatedValue<string>()); EXPECT_FLOAT_EQ(1.0f, Ptr(AidlConstantValue::Floating(loc, "1.0f"))->EvaluatedValue<float>()); EXPECT_EQ(true, Ptr(AidlConstantValue::Boolean(loc, true))->EvaluatedValue<bool>()); @@ -1354,6 +1354,14 @@ TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) { Ptr(AidlConstantValue::Array(loc, std::move(values)))->EvaluatedValue<vector<string>>()); } +TEST_F(AidlTest, AidlConstantCharacterDefault) { + auto char_type = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "char", false); + auto default_value = unique_ptr<AidlConstantValue>(AidlConstantValue::Default(*char_type)); + EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, cpp::ConstantValueDecorator)); + EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, ndk::ConstantValueDecorator)); + EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, java::ConstantValueDecorator)); +} + TEST_P(AidlTest, FailOnManyDefinedTypes) { AidlError error; const string expected_stderr = diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/FixedSize.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/FixedSize.h index f5f7f734..2e670e35 100644 --- a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/FixedSize.h +++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/FixedSize.h @@ -137,7 +137,7 @@ public: public: bool booleanValue = false; int8_t byteValue = 0; - char16_t charValue; + char16_t charValue = '\0'; int32_t intValue = 0; int64_t longValue = 0L; float floatValue = 0.000000f; diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java index 1f2e5cc4..1b4ca328 100644 --- a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java +++ b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/FixedSize.java @@ -47,7 +47,7 @@ public class FixedSize implements android.os.Parcelable { public boolean booleanValue = false; public byte byteValue = 0; - public char charValue; + public char charValue = '\0'; public int intValue = 0; public long longValue = 0L; public float floatValue = 0.000000f; diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/FixedSize.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/FixedSize.h index f8dcdd2d..2a783746 100644 --- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/FixedSize.h +++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/FixedSize.h @@ -151,7 +151,7 @@ public: bool booleanValue __attribute__((aligned (1))) = false; int8_t byteValue __attribute__((aligned (1))) = 0; - char16_t charValue __attribute__((aligned (2))); + char16_t charValue __attribute__((aligned (2))) = '\0'; int32_t intValue __attribute__((aligned (4))) = 0; int64_t longValue __attribute__((aligned (8))) = 0L; float floatValue __attribute__((aligned (4))) = 0.000000f; diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs index 8cc0baa1..ef73f725 100644 --- a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs +++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/FixedSize.rs @@ -44,7 +44,7 @@ pub mod FixedParcelable { Self { booleanValue: false, byteValue: 0, - charValue: Default::default(), + charValue: '\0' as u16, intValue: 0, longValue: 0, floatValue: 0.000000f32, |