Merge "Add support for relative package paths."
diff --git a/ConstantExpression.cpp b/ConstantExpression.cpp
index 1b2979d..5f022c8 100644
--- a/ConstantExpression.cpp
+++ b/ConstantExpression.cpp
@@ -170,20 +170,23 @@
return mIsEvaluated;
}
-LiteralConstantExpression::LiteralConstantExpression(ScalarType::Kind kind, uint64_t value) {
+LiteralConstantExpression::LiteralConstantExpression(
+ ScalarType::Kind kind, uint64_t value, const std::string& expr) {
+
+ CHECK(!expr.empty());
CHECK(isSupported(kind));
mTrivialDescription = true;
- mExpr = std::to_string(value);
+ mExpr = expr;
mValueKind = kind;
mValue = value;
mIsEvaluated = true;
}
-LiteralConstantExpression::LiteralConstantExpression(const std::string& value) {
+LiteralConstantExpression::LiteralConstantExpression(ScalarType::Kind kind, uint64_t value)
+ : LiteralConstantExpression(kind, value, std::to_string(value)) {}
+
+LiteralConstantExpression* LiteralConstantExpression::tryParse(const std::string& value) {
CHECK(!value.empty());
- mIsEvaluated = true;
- mTrivialDescription = true;
- mExpr = value;
bool isLong = false, isUnsigned = false;
bool isHex = (value[0] == '0' && value.length() > 1 && (value[1] == 'x' || value[1] == 'X'));
@@ -197,39 +200,50 @@
}
std::string newVal(value.begin(), rbegin.base());
CHECK(!newVal.empty());
- bool parseOK = base::ParseUint(newVal, &mValue);
- CHECK(parseOK) << "Could not parse as integer: " << value;
+
+ uint64_t rawValue = 0;
+
+ bool parseOK = base::ParseUint(newVal, &rawValue);
+ if (!parseOK) {
+ return nullptr;
+ }
+
+ ScalarType::Kind kind;
// guess literal type.
if(isLong) {
if(isUnsigned) // ul
- mValueKind = SK(UINT64);
+ kind = SK(UINT64);
else // l
- mValueKind = SK(INT64);
+ kind = SK(INT64);
} else { // no l suffix
if(isUnsigned) { // u
- if(mValue <= UINT32_MAX)
- mValueKind = SK(UINT32);
+ if(rawValue <= UINT32_MAX)
+ kind = SK(UINT32);
else
- mValueKind = SK(UINT64);
+ kind = SK(UINT64);
} else { // no suffix
if(isHex) {
- if(mValue <= INT32_MAX) // mValue always >= 0
- mValueKind = SK(INT32);
- else if(mValue <= UINT32_MAX)
- mValueKind = SK(UINT32);
- else if(mValue <= INT64_MAX) // mValue always >= 0
- mValueKind = SK(INT64);
- else if(mValue <= UINT64_MAX)
- mValueKind = SK(UINT64);
- } else {
- if(mValue <= INT32_MAX) // mValue always >= 0
- mValueKind = SK(INT32);
+ if(rawValue <= INT32_MAX) // rawValue always >= 0
+ kind = SK(INT32);
+ else if(rawValue <= UINT32_MAX)
+ kind = SK(UINT32);
+ else if(rawValue <= INT64_MAX) // rawValue always >= 0
+ kind = SK(INT64);
+ else if(rawValue <= UINT64_MAX)
+ kind = SK(UINT64);
else
- mValueKind = SK(INT64);
+ return nullptr;
+ } else {
+ if(rawValue <= INT32_MAX) // rawValue always >= 0
+ kind = SK(INT32);
+ else
+ kind = SK(INT64);
}
}
}
+
+ return new LiteralConstantExpression(kind, rawValue, value);
}
void LiteralConstantExpression::evaluate() {
diff --git a/ConstantExpression.h b/ConstantExpression.h
index 0dc9693..9784885 100644
--- a/ConstantExpression.h
+++ b/ConstantExpression.h
@@ -156,9 +156,13 @@
struct LiteralConstantExpression : public ConstantExpression {
LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
- LiteralConstantExpression(const std::string& value);
void evaluate() override;
std::vector<const ConstantExpression*> getConstantExpressions() const override;
+
+ static LiteralConstantExpression* tryParse(const std::string& value);
+
+private:
+ LiteralConstantExpression(ScalarType::Kind kind, uint64_t value, const std::string& expr);
};
struct UnaryConstantExpression : public ConstantExpression {
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index e1d472f..f872e43 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -693,7 +693,15 @@
;
const_expr
- : INTEGER { $$ = new LiteralConstantExpression($1); }
+ : INTEGER {
+ $$ = LiteralConstantExpression::tryParse($1);
+
+ if ($$ == nullptr) {
+ std::cerr << "ERROR: Could not parse literal: "
+ << $1 << " at " << @1 << ".\n";
+ YYERROR;
+ }
+ }
| fqname
{
if(!$1->isValidValueName()) {
@@ -894,6 +902,7 @@
enum_storage_type
: ':' fqtype { $$ = $2; }
+ | /* empty */ { $$ = nullptr; }
;
opt_comma
@@ -904,8 +913,18 @@
named_enum_declaration
: ENUM valid_type_name enum_storage_type
{
+ auto storageType = $3;
+
+ if (storageType == nullptr) {
+ std::cerr << "ERROR: Must explicitly specify enum storage type for "
+ << $2 << " at " << @2 << "\n";
+ ast->addSyntaxError();
+ storageType = new Reference<Type>(
+ new ScalarType(ScalarType::KIND_INT64, *scope), convertYYLoc(@2));
+ }
+
EnumType* enumType = new EnumType(
- $2, ast->makeFullName($2, *scope), convertYYLoc(@2), *$3, *scope);
+ $2, ast->makeFullName($2, *scope), convertYYLoc(@2), *storageType, *scope);
enterScope(ast, scope, enumType);
}
enum_declaration_body
diff --git a/test/error_test/Android.bp b/test/error_test/Android.bp
index 899f99c..e06c6d7 100644
--- a/test/error_test/Android.bp
+++ b/test/error_test/Android.bp
@@ -7,6 +7,7 @@
out: ["TODO_b_37575883.cpp"],
srcs: [
"bad_character/1.0/IFoo.hal",
+ "enum_storage/1.0/IFoo.hal",
"enum_unique_field_names/1.0/IFoo.hal",
"enum_unique_field_names_extends/1.0/IFoo.hal",
"interface_extends_only_interface/1.0/IFoo.hal",
diff --git a/test/error_test/enum_storage/1.0/IFoo.hal b/test/error_test/enum_storage/1.0/IFoo.hal
new file mode 100644
index 0000000..68f17c9
--- /dev/null
+++ b/test/error_test/enum_storage/1.0/IFoo.hal
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package test.bad_character@1.0;
+
+interface IFoo {
+
+ enum A /* missing storage */ {
+ };
+
+};
+
diff --git a/test/error_test/hidl_error_test.sh b/test/error_test/hidl_error_test.sh
index cde1e81..92d0efe 100755
--- a/test/error_test/hidl_error_test.sh
+++ b/test/error_test/hidl_error_test.sh
@@ -1,7 +1,7 @@
#!/bin/bash
if [ $# -ne 1 ]; then
- echo "hidl_errr_test.sh hidl-gen_path"
+ echo "usage: hidl_error_test.sh hidl-gen_path"
exit 1
fi
diff --git a/test/run_all_device_tests.sh b/test/run_all_device_tests.sh
new file mode 100755
index 0000000..3ae7614
--- /dev/null
+++ b/test/run_all_device_tests.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+function run() {
+ local FAILED_TESTS=()
+
+ # Tests directly relevant to HIDL infrustructure but aren't
+ # located in system/tools/hidl
+ local RELATED_RUNTIME_TESTS=(\
+ libhidl_test \
+ )
+
+ local RUN_TIME_TESTS=(\
+ libhidl-gen-utils_test \
+ )
+ RUN_TIME_TESTS+=(${RELATED_RUNTIME_TESTS[@]})
+
+ local SCRIPT_TESTS=(\
+ hidl_test\
+ hidl_test_java\
+ )
+
+ $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode -j \
+ ${RUN_TIME_TESTS[*]} ${SCRIPT_TESTS[*]} || return
+
+ adb sync || return
+
+ local BITNESS=("nativetest" "nativetest64")
+
+ for test in ${RUN_TIME_TESTS[@]}; do
+ for bits in ${BITNESS[@]}; do
+ echo $bits $test
+ adb shell /data/$bits/$test/$test ||
+ FAILED_TESTS+=("$bits:$test")
+ done
+ done
+
+ for test in ${SCRIPT_TESTS[@]}; do
+ echo $test
+ adb shell /data/nativetest64/$test ||
+ FAILED_TESTS+=("$test")
+ done
+
+ echo
+ echo ===== SUMMARY =====
+ echo
+ if [ ${#FAILED_TESTS[@]} -gt 0 ]; then
+ for failed in ${FAILED_TESTS[@]}; do
+ echo "FAILED TEST: $failed"
+ done
+ else
+ echo "SUCCESS"
+ fi
+}
+
+run
\ No newline at end of file