Merge "Remove unnecessary folders in error_test"
diff --git a/AST.h b/AST.h
index 1fe514f..dc39c0a 100644
--- a/AST.h
+++ b/AST.h
@@ -31,13 +31,15 @@
namespace android {
struct Coordinator;
+struct EnumValue;
struct Formatter;
struct Interface;
struct Location;
struct Method;
struct NamedType;
-struct TypedVar;
-struct EnumValue;
+template <class T>
+struct NamedReference;
+struct Type;
struct AST {
AST(const Coordinator *coordinator, const std::string &path);
@@ -242,35 +244,20 @@
InstrumentationEvent event,
const Method *method) const;
- void declareCppReaderLocals(
- Formatter &out,
- const std::vector<TypedVar *> &arg,
- bool forResults) const;
+ void declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& arg,
+ bool forResults) const;
- void emitCppReaderWriter(
- Formatter &out,
- const std::string &parcelObj,
- bool parcelObjIsPointer,
- const TypedVar *arg,
- bool isReader,
- Type::ErrorMode mode,
- bool addPrefixToName) const;
+ void emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
+ const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
+ bool addPrefixToName) const;
- void emitCppResolveReferences(
- Formatter &out,
- const std::string &parcelObj,
- bool parcelObjIsPointer,
- const TypedVar *arg,
- bool isReader,
- Type::ErrorMode mode,
- bool addPrefixToName) const;
+ void emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
+ bool parcelObjIsPointer, const NamedReference<Type>* arg,
+ bool isReader, Type::ErrorMode mode, bool addPrefixToName) const;
- void emitJavaReaderWriter(
- Formatter &out,
- const std::string &parcelObj,
- const TypedVar *arg,
- bool isReader,
- bool addPrefixToName) const;
+ void emitJavaReaderWriter(Formatter& out, const std::string& parcelObj,
+ const NamedReference<Type>* arg, bool isReader,
+ bool addPrefixToName) const;
status_t emitTypeDeclarations(Formatter &out) const;
status_t emitJavaTypeDeclarations(Formatter &out) const;
diff --git a/CompoundType.cpp b/CompoundType.cpp
index da30747..146074e 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -31,8 +31,7 @@
return mStyle;
}
-bool CompoundType::setFields(
- std::vector<CompoundField *> *fields, std::string *errorMsg) {
+bool CompoundType::setFields(std::vector<NamedReference<Type>*>* fields, std::string* errorMsg) {
mFields = fields;
for (const auto &field : *fields) {
@@ -522,7 +521,7 @@
<< "std::string os;\n";
out << "os += \"{\";\n";
- for (const CompoundField *field : *mFields) {
+ for (const NamedReference<Type>* field : *mFields) {
out << "os += \"";
if (field != *(mFields->begin())) {
out << ", ";
@@ -1113,20 +1112,5 @@
}
}
-////////////////////////////////////////////////////////////////////////////////
-
-CompoundField::CompoundField(const char* name, const Reference<Type>& type)
- : mName(name), mType(type) {
- CHECK(!type.isEmptyReference());
-}
-
-std::string CompoundField::name() const {
- return mName;
-}
-
-const Type &CompoundField::type() const {
- return *(mType.get());
-}
-
} // namespace android
diff --git a/CompoundType.h b/CompoundType.h
index 2674544..da986a1 100644
--- a/CompoundType.h
+++ b/CompoundType.h
@@ -25,8 +25,6 @@
namespace android {
-struct CompoundField;
-
struct CompoundType : public Scope {
enum Style {
STYLE_STRUCT,
@@ -37,7 +35,7 @@
Style style() const;
- bool setFields(std::vector<CompoundField *> *fields, std::string *errorMsg);
+ bool setFields(std::vector<NamedReference<Type>*>* fields, std::string* errorMsg);
bool isCompoundType() const override;
@@ -137,7 +135,7 @@
private:
Style mStyle;
- std::vector<CompoundField *> *mFields;
+ std::vector<NamedReference<Type>*>* mFields;
void emitStructReaderWriter(
Formatter &out, const std::string &prefix, bool isReader) const;
@@ -147,19 +145,6 @@
DISALLOW_COPY_AND_ASSIGN(CompoundType);
};
-struct CompoundField {
- CompoundField(const char* name, const Reference<Type>& type);
-
- std::string name() const;
- const Type &type() const;
-
-private:
- std::string mName;
- Reference<Type> mType;
-
- DISALLOW_COPY_AND_ASSIGN(CompoundField);
-};
-
} // namespace android
#endif // COMPOUND_TYPE_H_
diff --git a/ConstantExpression.cpp b/ConstantExpression.cpp
index eba28e1..265f841 100644
--- a/ConstantExpression.cpp
+++ b/ConstantExpression.cpp
@@ -23,14 +23,14 @@
#include <sstream>
#include "EnumType.h"
+#include "Scope.h" // LocalIdentifier
// The macros are really nasty here. Consider removing
// as many macros as possible.
-#define STREQ(__x__, __y__) (strcmp((__x__), (__y__)) == 0)
-#define OPEQ(__y__) STREQ(op, __y__)
-#define COMPUTE_UNARY(__op__) if(OPEQ(#__op__)) return __op__ val;
-#define COMPUTE_BINARY(__op__) if(OPEQ(#__op__)) return lval __op__ rval;
+#define OPEQ(__y__) (std::string(mOp) == std::string(__y__))
+#define COMPUTE_UNARY(__op__) if (op == std::string(#__op__)) return __op__ val;
+#define COMPUTE_BINARY(__op__) if (op == std::string(#__op__)) return lval __op__ rval;
#define OP_IS_BIN_ARITHMETIC (OPEQ("+") || OPEQ("-") || OPEQ("*") || OPEQ("/") || OPEQ("%"))
#define OP_IS_BIN_BITFLIP (OPEQ("|") || OPEQ("^") || OPEQ("&"))
#define OP_IS_BIN_COMP (OPEQ("<") || OPEQ(">") || OPEQ("<=") || OPEQ(">=") || OPEQ("==") || OPEQ("!="))
@@ -96,7 +96,7 @@
}
template <class T>
-T handleUnary(const char *op, T val) {
+T handleUnary(const std::string& op, T val) {
COMPUTE_UNARY(+)
COMPUTE_UNARY(-)
COMPUTE_UNARY(!)
@@ -107,7 +107,7 @@
}
template <class T>
-T handleBinaryCommon(T lval, const char *op, T rval) {
+T handleBinaryCommon(T lval, const std::string& op, T rval) {
COMPUTE_BINARY(+)
COMPUTE_BINARY(-)
COMPUTE_BINARY(*)
@@ -130,85 +130,70 @@
}
template <class T>
-T handleShift(T lval, const char *op, int64_t rval) {
+T handleShift(T lval, const std::string& op, int64_t rval) {
// just cast rval to int64_t and it should fit.
COMPUTE_BINARY(>>)
COMPUTE_BINARY(<<)
// Should not reach here.
- SHOULD_NOT_REACH() << "Could not handleShift for"
+ SHOULD_NOT_REACH() << "Could not handleShift for "
<< lval << " " << op << " " << rval;
return static_cast<T>(0xdeadbeef);
}
-bool handleLogical(bool lval, const char *op, bool rval) {
+bool handleLogical(bool lval, const std::string& op, bool rval) {
COMPUTE_BINARY(||);
COMPUTE_BINARY(&&);
// Should not reach here.
- SHOULD_NOT_REACH() << "Could not handleLogical for"
+ SHOULD_NOT_REACH() << "Could not handleLogical for "
<< lval << " " << op << " " << rval;
return false;
}
-ConstantExpression::ConstantExpression() {
+std::unique_ptr<ConstantExpression> ConstantExpression::Zero(ScalarType::Kind kind) {
+ return ValueOf(kind, 0);
}
-ConstantExpression ConstantExpression::Zero(ScalarType::Kind kind) {
- ConstantExpression ce = ValueOf(kind, 0);
- ce.mExpr = "0";
- return ce;
+std::unique_ptr<ConstantExpression> ConstantExpression::One(ScalarType::Kind kind) {
+ return ValueOf(kind, 1);
}
-ConstantExpression ConstantExpression::One(ScalarType::Kind kind) {
- ConstantExpression ce = ValueOf(kind, 1);
- ce.mExpr = "1";
- return ce;
+std::unique_ptr<ConstantExpression> ConstantExpression::ValueOf(ScalarType::Kind kind,
+ uint64_t value) {
+ return std::make_unique<LiteralConstantExpression>(kind, value);
}
-ConstantExpression ConstantExpression::ValueOf(ScalarType::Kind kind, uint64_t value) {
- ConstantExpression ce;
+bool ConstantExpression::isEvaluated() const {
+ return mIsEvaluated;
+}
+
+LiteralConstantExpression::LiteralConstantExpression(ScalarType::Kind kind, uint64_t value) {
CHECK(isSupported(kind));
-
- ce.mExpr = "";
- ce.mType = kConstExprLiteral;
- ce.mValueKind = kind;
- ce.mValue = value;
- ce.mTrivialDescription = true;
- return ce;
-}
-ConstantExpression::ConstantExpression(const ConstantExpression& other) {
- *this = other;
+ mTrivialDescription = true;
+ mExpr = std::to_string(value);
+ mValueKind = kind;
+ mValue = value;
+ mIsEvaluated = true;
}
-/* Copy constructor, with the expr overriden and treated non-trivial */
-ConstantExpression::ConstantExpression(const ConstantExpression& other, std::string expr) {
- *this = other;
- mExpr = expr;
- mTrivialDescription = false;
-}
+LiteralConstantExpression::LiteralConstantExpression(const std::string& value) {
+ CHECK(!value.empty());
+ mIsEvaluated = true;
+ mTrivialDescription = true;
+ mExpr = value;
-ConstantExpression& ConstantExpression::operator=(const ConstantExpression& other) {
- mType = other.mType;
- mValueKind = other.mValueKind;
- mValue = other.mValue;
- mExpr = other.mExpr;
- mTrivialDescription = other.mTrivialDescription;
- return *this;
-}
-
-/* Literals. */
-ConstantExpression::ConstantExpression(const char *value)
- : mExpr(value), mType(kConstExprLiteral), mTrivialDescription(true) {
- const char* head = value, *tail = head + strlen(value) - 1;
bool isLong = false, isUnsigned = false;
- bool isHex = (value[0] == '0' && (value[1] == 'x' || value[1] == 'X'));
- while(tail >= head && (*tail == 'u' || *tail == 'U' || *tail == 'l' || *tail == 'L')) {
- isUnsigned |= (*tail == 'u' || *tail == 'U');
- isLong |= (*tail == 'l' || *tail == 'L');
- tail--;
+ bool isHex = (value[0] == '0' && value.length() > 1 && (value[1] == 'x' || value[1] == 'X'));
+
+ auto rbegin = value.rbegin();
+ auto rend = value.rend();
+ for (; rbegin != rend && (*rbegin == 'u' || *rbegin == 'U' || *rbegin == 'l' || *rbegin == 'L');
+ ++rbegin) {
+ isUnsigned |= (*rbegin == 'u' || *rbegin == 'U');
+ isLong |= (*rbegin == 'l' || *rbegin == 'L');
}
- char *newVal = strndup(value, tail - head + 1);
+ std::string newVal(value.begin(), rbegin.base());
+ CHECK(!newVal.empty());
bool parseOK = base::ParseUint(newVal, &mValue);
- free(newVal);
CHECK(parseOK) << "Could not parse as integer: " << value;
// guess literal type.
@@ -243,60 +228,70 @@
}
}
-/* Unary operations. */
-ConstantExpression::ConstantExpression(const char *op,
- const ConstantExpression *value)
- : mExpr(std::string("(") + op + value->mExpr + ")"),
- mType(kConstExprUnary),
- mValueKind(value->mValueKind) {
+void LiteralConstantExpression::evaluate() {
+ // Evaluated in constructor
+ CHECK(isEvaluated());
+}
-#define CASE_UNARY(__type__)\
- mValue = handleUnary(op, static_cast<__type__>(value->mValue)); return;
+void UnaryConstantExpression::evaluate() {
+ if (isEvaluated()) return;
+ mUnary->evaluate();
+ mIsEvaluated = true;
+
+ mExpr = std::string("(") + mOp + mUnary->description() + ")";
+ mValueKind = mUnary->mValueKind;
+
+#define CASE_UNARY(__type__) \
+ mValue = handleUnary(mOp, static_cast<__type__>(mUnary->mValue)); \
+ return;
SWITCH_KIND(mValueKind, CASE_UNARY, SHOULD_NOT_REACH(); return;)
}
-/* Binary operations. */
-ConstantExpression::ConstantExpression(const ConstantExpression *lval,
- const char *op,
- const ConstantExpression* rval)
- : mExpr(std::string("(") + lval->mExpr + " " + op + " " + rval->mExpr + ")"),
- mType(kConstExprBinary)
-{
+void BinaryConstantExpression::evaluate() {
+ if (isEvaluated()) return;
+ mLval->evaluate();
+ mRval->evaluate();
+ mIsEvaluated = true;
+
+ mExpr = std::string("(") + mLval->description() + " " + mOp + " " + mRval->description() + ")";
bool isArithmeticOrBitflip = OP_IS_BIN_ARITHMETIC || OP_IS_BIN_BITFLIP;
// CASE 1: + - * / % | ^ & < > <= >= == !=
if(isArithmeticOrBitflip || OP_IS_BIN_COMP) {
// promoted kind for both operands.
- ScalarType::Kind promoted = usualArithmeticConversion(
- integralPromotion(lval->mValueKind),
- integralPromotion(rval->mValueKind));
+ ScalarType::Kind promoted = usualArithmeticConversion(integralPromotion(mLval->mValueKind),
+ integralPromotion(mRval->mValueKind));
// result kind.
mValueKind = isArithmeticOrBitflip
? promoted // arithmetic or bitflip operators generates promoted type
: SK(BOOL); // comparison operators generates bool
-#define CASE_BINARY_COMMON(__type__)\
- mValue = handleBinaryCommon(static_cast<__type__>(lval->mValue), op, static_cast<__type__>(rval->mValue)); return;
+#define CASE_BINARY_COMMON(__type__) \
+ mValue = handleBinaryCommon(static_cast<__type__>(mLval->mValue), mOp, \
+ static_cast<__type__>(mRval->mValue)); \
+ return;
SWITCH_KIND(promoted, CASE_BINARY_COMMON, SHOULD_NOT_REACH(); return;)
}
// CASE 2: << >>
+ std::string newOp = mOp;
if(OP_IS_BIN_SHIFT) {
- mValueKind = integralPromotion(lval->mValueKind);
+ mValueKind = integralPromotion(mLval->mValueKind);
// instead of promoting rval, simply casting it to int64 should also be good.
- int64_t numBits = rval->cast<int64_t>();
+ int64_t numBits = mRval->cast<int64_t>();
if(numBits < 0) {
// shifting with negative number of bits is undefined in C. In HIDL it
// is defined as shifting into the other direction.
- op = OPEQ("<<") ? ">>" : "<<";
+ newOp = OPEQ("<<") ? std::string(">>") : std::string("<<");
numBits = -numBits;
}
-#define CASE_SHIFT(__type__)\
- mValue = handleShift(static_cast<__type__>(lval->mValue), op, numBits); return;
+#define CASE_SHIFT(__type__) \
+ mValue = handleShift(static_cast<__type__>(mLval->mValue), newOp, numBits); \
+ return;
SWITCH_KIND(mValueKind, CASE_SHIFT, SHOULD_NOT_REACH(); return;)
}
@@ -305,63 +300,80 @@
if(OP_IS_BIN_LOGICAL) {
mValueKind = SK(BOOL);
// easy; everything is bool.
- mValue = handleLogical(lval->mValue, op, rval->mValue);
+ mValue = handleLogical(mLval->mValue, mOp, mRval->mValue);
return;
}
SHOULD_NOT_REACH();
}
-/* Ternary ?: operation. */
-ConstantExpression::ConstantExpression(const ConstantExpression *cond,
- const ConstantExpression *trueVal,
- const ConstantExpression *falseVal)
- : mExpr(std::string("(") + cond->mExpr + "?" + trueVal->mExpr
- + ":" + falseVal->mExpr + ")"),
- mType(kConstExprTernary) {
+void TernaryConstantExpression::evaluate() {
+ if (isEvaluated()) return;
+ mCond->evaluate();
+ mTrueVal->evaluate();
+ mFalseVal->evaluate();
+ mIsEvaluated = true;
+
+ mExpr = std::string("(") + mCond->description() + "?" + mTrueVal->description() + ":" +
+ mFalseVal->description() + ")";
// note: for ?:, unlike arithmetic ops, integral promotion is not necessary.
- mValueKind = usualArithmeticConversion(trueVal->mValueKind,
- falseVal->mValueKind);
+ mValueKind = usualArithmeticConversion(mTrueVal->mValueKind, mFalseVal->mValueKind);
-#define CASE_TERNARY(__type__)\
- mValue = cond->mValue ? (static_cast<__type__>(trueVal->mValue)) : (static_cast<__type__>(falseVal->mValue)); return;
+#define CASE_TERNARY(__type__) \
+ mValue = mCond->mValue ? (static_cast<__type__>(mTrueVal->mValue)) \
+ : (static_cast<__type__>(mFalseVal->mValue)); \
+ return;
SWITCH_KIND(mValueKind, CASE_TERNARY, SHOULD_NOT_REACH(); return;)
}
-ConstantExpression ConstantExpression::addOne() const {
- ConstantExpression myOne = ConstantExpression::One(mValueKind);
- return ConstantExpression(this, "+", &myOne).toLiteral();
+void ReferenceConstantExpression::evaluate() {
+ if (isEvaluated()) return;
+
+ ConstantExpression* expr = mReference->constExpr();
+ CHECK(expr != nullptr);
+ expr->evaluate();
+
+ mValueKind = expr->mValueKind;
+ mValue = expr->mValue;
+ mIsEvaluated = true;
}
-ConstantExpression &ConstantExpression::toLiteral() {
- mExpr = value();
- mType = kConstExprLiteral;
- return *this;
+std::unique_ptr<ConstantExpression> ConstantExpression::addOne(ScalarType::Kind baseKind) {
+ auto ret = std::make_unique<BinaryConstantExpression>(
+ this, "+", ConstantExpression::One(baseKind).release());
+ ret->mTrivialDescription = true;
+ return ret;
}
-const std::string &ConstantExpression::description() const {
+const std::string& ConstantExpression::description() const {
+ CHECK(isEvaluated());
return mExpr;
}
bool ConstantExpression::descriptionIsTrivial() const {
+ CHECK(isEvaluated());
return mTrivialDescription;
}
std::string ConstantExpression::value() const {
+ CHECK(isEvaluated());
return rawValue(mValueKind);
}
std::string ConstantExpression::value(ScalarType::Kind castKind) const {
+ CHECK(isEvaluated());
return rawValue(castKind);
}
std::string ConstantExpression::cppValue() const {
+ CHECK(isEvaluated());
return cppValue(mValueKind);
}
std::string ConstantExpression::cppValue(ScalarType::Kind castKind) const {
+ CHECK(isEvaluated());
std::string literal(rawValue(castKind));
// this is a hack to translate
// enum x : int64_t { y = 1l << 63 };
@@ -384,10 +396,12 @@
}
std::string ConstantExpression::javaValue() const {
+ CHECK(isEvaluated());
return javaValue(mValueKind);
}
std::string ConstantExpression::javaValue(ScalarType::Kind castKind) const {
+ CHECK(isEvaluated());
switch(castKind) {
case SK(UINT64): return rawValue(SK(INT64)) + "L";
case SK(INT64): return rawValue(SK(INT64)) + "L";
@@ -402,6 +416,7 @@
}
std::string ConstantExpression::rawValue(ScalarType::Kind castKind) const {
+ CHECK(isEvaluated());
#define CASE_STR(__type__) return std::to_string(this->cast<__type__>());
@@ -410,6 +425,7 @@
template<typename T>
T ConstantExpression::cast() const {
+ CHECK(isEvaluated());
#define CASE_CAST_T(__type__) return static_cast<T>(static_cast<__type__>(mValue));
@@ -417,9 +433,28 @@
}
size_t ConstantExpression::castSizeT() const {
+ CHECK(isEvaluated());
return this->cast<size_t>();
}
+UnaryConstantExpression::UnaryConstantExpression(const std::string& op, ConstantExpression* value)
+ : mUnary(value), mOp(op) {}
+
+BinaryConstantExpression::BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
+ ConstantExpression* rval)
+ : mLval(lval), mRval(rval), mOp(op) {}
+
+TernaryConstantExpression::TernaryConstantExpression(ConstantExpression* cond,
+ ConstantExpression* trueVal,
+ ConstantExpression* falseVal)
+ : mCond(cond), mTrueVal(trueVal), mFalseVal(falseVal) {}
+
+ReferenceConstantExpression::ReferenceConstantExpression(const Reference<LocalIdentifier>& value,
+ const std::string& expr)
+ : mReference(value) {
+ mExpr = expr;
+}
+
/*
Evaluating expressions in HIDL language
diff --git a/ConstantExpression.h b/ConstantExpression.h
index 2c955d4..ebb6c48 100644
--- a/ConstantExpression.h
+++ b/ConstantExpression.h
@@ -19,45 +19,41 @@
#define CONSTANT_EXPRESSION_H_
#include <android-base/macros.h>
+#include <memory>
#include <string>
+
+#include "Reference.h"
#include "ScalarType.h"
namespace android {
+struct LocalIdentifier;
+
+struct LiteralConstantExpression;
+struct UnaryConstantExpression;
+struct BinaryConstantExpression;
+struct TernaryConstantExpression;
+struct ReferenceConstantExpression;
+
/**
* A constant expression is represented by a tree.
*/
struct ConstantExpression {
+ static std::unique_ptr<ConstantExpression> Zero(ScalarType::Kind kind);
+ static std::unique_ptr<ConstantExpression> One(ScalarType::Kind kind);
+ static std::unique_ptr<ConstantExpression> ValueOf(ScalarType::Kind kind, uint64_t value);
- enum ConstExprType {
- kConstExprLiteral,
- kConstExprUnary,
- kConstExprBinary,
- kConstExprTernary
- };
+ virtual ~ConstantExpression() {}
- /* Default constructor. */
- ConstantExpression();
- /* Copy constructor. */
- ConstantExpression(const ConstantExpression& other);
- /* Copy constructor, with the expr overriden. */
- ConstantExpression(const ConstantExpression& other, std::string expr);
- /* Literals */
- ConstantExpression(const char *value);
- /* binary operations */
- ConstantExpression(const ConstantExpression *value1,
- const char *op, const ConstantExpression* value2);
- /* unary operations */
- ConstantExpression(const char *op, const ConstantExpression *value);
- /* ternary ?: */
- ConstantExpression(const ConstantExpression *cond,
- const ConstantExpression *trueVal,
- const ConstantExpression *falseVal);
+ /*
+ * Runs recursive evaluation.
+ * Provides sort of lazy computation,
+ * mainly used for forward identifier reference.
+ */
+ virtual void evaluate() = 0;
- static ConstantExpression Zero(ScalarType::Kind kind);
- static ConstantExpression One(ScalarType::Kind kind);
- static ConstantExpression ValueOf(ScalarType::Kind kind, uint64_t value);
-
+ /* Returns true iff the value has already been evaluated. */
+ bool isEvaluated() const;
/* Evaluated result in a string form. */
std::string value() const;
/* Evaluated result in a string form. */
@@ -70,22 +66,21 @@
std::string cppValue(ScalarType::Kind castKind) const;
/* Evaluated result in a string form, with given contextual kind. */
std::string javaValue(ScalarType::Kind castKind) const;
- /* Original expression with type. */
- const std::string &description() const;
+ /* Formatted expression with type. */
+ const std::string& description() const;
/* See mTrivialDescription */
bool descriptionIsTrivial() const;
/* Return a ConstantExpression that is 1 plus the original. */
- ConstantExpression addOne() const;
- /* Assignment operator. */
- ConstantExpression& operator=(const ConstantExpression& other);
+ std::unique_ptr<ConstantExpression> addOne(ScalarType::Kind baseKind);
size_t castSizeT() const;
-private:
+ private:
+ /* If the result value has been evaluated. */
+ bool mIsEvaluated = false;
+
/* The formatted expression. */
std::string mExpr;
- /* The type of the expression. Hints on its original form. */
- ConstExprType mType;
/* The kind of the result value. */
ScalarType::Kind mValueKind;
/* The stored result value. */
@@ -99,15 +94,65 @@
* digits) converted from mValue.
*/
std::string rawValue(ScalarType::Kind castKind) const;
- /* Trim unnecessary information. Only mValue and mValueKind is kept. */
- ConstantExpression &toLiteral();
/*
* Return the value casted to the given type.
* First cast it according to mValueKind, then cast it to T.
* Assumes !containsIdentifiers()
*/
- template <typename T> T cast() const;
+ template <typename T>
+ T cast() const;
+
+ friend struct LiteralConstantExpression;
+ friend struct UnaryConstantExpression;
+ friend struct BinaryConstantExpression;
+ friend struct TernaryConstantExpression;
+ friend struct ReferenceConstantExpression;
+};
+
+struct LiteralConstantExpression : public ConstantExpression {
+ LiteralConstantExpression(ScalarType::Kind kind, uint64_t value);
+ LiteralConstantExpression(const std::string& value);
+ void evaluate() override;
+};
+
+struct UnaryConstantExpression : public ConstantExpression {
+ UnaryConstantExpression(const std::string& mOp, ConstantExpression* value);
+ void evaluate() override;
+
+ private:
+ ConstantExpression* const mUnary;
+ std::string mOp;
+};
+
+struct BinaryConstantExpression : public ConstantExpression {
+ BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
+ ConstantExpression* rval);
+ void evaluate() override;
+
+ private:
+ ConstantExpression* const mLval;
+ ConstantExpression* const mRval;
+ const std::string mOp;
+};
+
+struct TernaryConstantExpression : public ConstantExpression {
+ TernaryConstantExpression(ConstantExpression* cond, ConstantExpression* trueVal,
+ ConstantExpression* falseVal);
+ void evaluate() override;
+
+ private:
+ ConstantExpression* const mCond;
+ ConstantExpression* const mTrueVal;
+ ConstantExpression* const mFalseVal;
+};
+
+struct ReferenceConstantExpression : public ConstantExpression {
+ ReferenceConstantExpression(const Reference<LocalIdentifier>& value, const std::string& expr);
+ void evaluate() override;
+
+ private:
+ Reference<LocalIdentifier> mReference;
};
} // namespace android
diff --git a/EnumType.cpp b/EnumType.cpp
index 9f70287..02c6c69 100644
--- a/EnumType.cpp
+++ b/EnumType.cpp
@@ -692,18 +692,16 @@
return mValue;
}
-void EnumValue::autofill(const EnumValue *prev, const ScalarType *type) {
- if(mValue != nullptr)
- return;
+void EnumValue::autofill(const EnumValue* prev, const ScalarType* type) {
+ if (mValue != nullptr) return;
mIsAutoFill = true;
- ConstantExpression *value = new ConstantExpression();
- if(prev == nullptr) {
- *value = ConstantExpression::Zero(type->getKind());
+ if (prev == nullptr) {
+ mValue = ConstantExpression::Zero(type->getKind()).release();
} else {
CHECK(prev->mValue != nullptr);
- *value = prev->mValue->addOne();
+ mValue = prev->mValue->addOne(type->getKind()).release();
}
- mValue = value;
+ mValue->evaluate();
}
bool EnumValue::isAutoFill() const {
diff --git a/EnumType.h b/EnumType.h
index 35db597..95a6174 100644
--- a/EnumType.h
+++ b/EnumType.h
@@ -131,14 +131,14 @@
std::string javaValue(ScalarType::Kind castKind) const;
std::string comment() const;
void autofill(const EnumValue *prev, const ScalarType *type);
- ConstantExpression *constExpr() const;
+ ConstantExpression* constExpr() const override;
bool isAutoFill() const;
bool isEnumValue() const override;
std::string mName;
- ConstantExpression *mValue;
+ ConstantExpression* mValue;
bool mIsAutoFill;
DISALLOW_COPY_AND_ASSIGN(EnumValue);
diff --git a/Interface.cpp b/Interface.cpp
index 805d81c..78d42ad 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -28,6 +28,7 @@
#include <unistd.h>
#include <iostream>
+#include <memory>
#include <sstream>
#include <android-base/logging.h>
@@ -287,10 +288,8 @@
}
static void emitDigestChain(
- Formatter &out,
- const std::string &prefix,
- const std::vector<const Interface *> &chain,
- std::function<std::string(const ConstantExpression &)> byteToString) {
+ Formatter& out, const std::string& prefix, const std::vector<const Interface*>& chain,
+ std::function<std::string(std::unique_ptr<ConstantExpression>)> byteToString) {
out.join(chain.begin(), chain.end(), ",\n", [&] (const auto &iface) {
const Hash &hash = Hash::getHash(iface->location().begin().filename());
out << prefix;
@@ -319,8 +318,8 @@
std::vector<const Interface *> chain = typeChain();
out << "_hidl_cb(";
out.block([&] {
- emitDigestChain(out, "(" + digestType->getInternalDataCppType() + ")",
- chain, [](const auto &e){return e.cppValue();});
+ emitDigestChain(out, "(" + digestType->getInternalDataCppType() + ")", chain,
+ [](const auto& e) { return e->cppValue(); });
});
out << ");\n";
out << "return ::android::hardware::Void();\n";
@@ -333,7 +332,7 @@
out.indent(2, [&] {
// No need for dimensions when elements are explicitly provided.
emitDigestChain(out, "new " + digestType->getJavaType(false /* forInitializer */),
- chain, [](const auto &e){return e.javaValue();});
+ chain, [](const auto& e) { return e->javaValue(); });
});
out << "));\n";
} } } /* javaImpl */
diff --git a/Method.cpp b/Method.cpp
index 5a3e248..48eb80e 100644
--- a/Method.cpp
+++ b/Method.cpp
@@ -22,20 +22,14 @@
#include <android-base/logging.h>
#include <hidl-util/Formatter.h>
+#include <algorithm>
namespace android {
-Method::Method(const char *name,
- std::vector<TypedVar *> *args,
- std::vector<TypedVar *> *results,
- bool oneway,
- std::vector<Annotation *> *annotations)
- : mName(name),
- mArgs(args),
- mResults(results),
- mOneway(oneway),
- mAnnotations(annotations) {
-}
+Method::Method(const char* name, std::vector<NamedReference<Type>*>* args,
+ std::vector<NamedReference<Type>*>* results, bool oneway,
+ std::vector<Annotation*>* annotations)
+ : mName(name), mArgs(args), mResults(results), mOneway(oneway), mAnnotations(annotations) {}
void Method::fillImplementation(
size_t serial,
@@ -57,11 +51,11 @@
return mName;
}
-const std::vector<TypedVar *> &Method::args() const {
+const std::vector<NamedReference<Type>*>& Method::args() const {
return *mArgs;
}
-const std::vector<TypedVar *> &Method::results() const {
+const std::vector<NamedReference<Type>*>& Method::results() const {
return *mResults;
}
@@ -121,7 +115,7 @@
}
void Method::generateCppReturnType(Formatter &out, bool specifyNamespaces) const {
- const TypedVar *elidedReturn = canElideCallback();
+ const NamedReference<Type>* elidedReturn = canElideCallback();
const std::string space = (specifyNamespaces ? "::android::hardware::" : "");
if (elidedReturn == nullptr) {
@@ -149,9 +143,9 @@
out << ")";
}
-static void emitCppArgResultSignature(Formatter &out,
- const std::vector<TypedVar *> &args,
- bool specifyNamespaces) {
+static void emitCppArgResultSignature(Formatter& out,
+ const std::vector<NamedReference<Type>*>& args,
+ bool specifyNamespaces) {
out.join(args.begin(), args.end(), ", ", [&](auto arg) {
out << arg->type().getCppArgumentType(specifyNamespaces);
out << " ";
@@ -159,7 +153,8 @@
});
}
-static void emitJavaArgResultSignature(Formatter &out, const std::vector<TypedVar *> &args) {
+static void emitJavaArgResultSignature(Formatter& out,
+ const std::vector<NamedReference<Type>*>& args) {
out.join(args.begin(), args.end(), ", ", [&](auto arg) {
out << arg->type().getJavaType();
out << " ";
@@ -171,7 +166,7 @@
emitCppArgResultSignature(out, args(), specifyNamespaces);
const bool returnsValue = !results().empty();
- const TypedVar *elidedReturn = canElideCallback();
+ const NamedReference<Type>* elidedReturn = canElideCallback();
if (returnsValue && elidedReturn == nullptr) {
if (!args().empty()) {
out << ", ";
@@ -210,28 +205,26 @@
return true;
}
- for (const auto &arg : *mArgs) {
- if (!arg->isJavaCompatible()) {
- return false;
- }
+ if (!std::all_of(mArgs->begin(), mArgs->end(),
+ [](const auto* arg) { return (*arg)->isJavaCompatible(); })) {
+ return false;
}
- for (const auto &result : *mResults) {
- if (!result->isJavaCompatible()) {
- return false;
- }
+ if (!std::all_of(mResults->begin(), mResults->end(),
+ [](const auto* arg) { return (*arg)->isJavaCompatible(); })) {
+ return false;
}
return true;
}
-const TypedVar* Method::canElideCallback() const {
+const NamedReference<Type>* Method::canElideCallback() const {
// Can't elide callback for void or tuple-returning methods
if (mResults->size() != 1) {
return nullptr;
}
- const TypedVar *typedVar = mResults->at(0);
+ const NamedReference<Type>* typedVar = mResults->at(0);
if (typedVar->type().isElidableType()) {
return typedVar;
@@ -242,22 +235,7 @@
////////////////////////////////////////////////////////////////////////////////
-TypedVar::TypedVar(const char* name, const Reference<Type>& type) : mName(name), mType(type) {}
-
-std::string TypedVar::name() const {
- return mName;
-}
-
-const Type &TypedVar::type() const {
- return *(mType.get());
-}
-
-bool TypedVar::isJavaCompatible() const {
- return mType->isJavaCompatible();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-bool TypedVarVector::add(TypedVar *v) {
+bool TypedVarVector::add(NamedReference<Type>* v) {
if (mNames.emplace(v->name()).second) {
push_back(v);
return true;
diff --git a/Method.h b/Method.h
index b77c66f..bb4e20d 100644
--- a/Method.h
+++ b/Method.h
@@ -34,7 +34,6 @@
struct Formatter;
struct ScalarType;
struct Type;
-struct TypedVar;
struct TypedVarVector;
enum MethodImplType {
@@ -48,15 +47,13 @@
using MethodImpl = std::map<MethodImplType, std::function<void(Formatter &)>>;
struct Method {
- Method(const char *name,
- std::vector<TypedVar *> *args,
- std::vector<TypedVar *> *results,
- bool oneway,
- std::vector<Annotation *> *annotations);
+ Method(const char* name, std::vector<NamedReference<Type>*>* args,
+ std::vector<NamedReference<Type>*>* results, bool oneway,
+ std::vector<Annotation*>* annotations);
std::string name() const;
- const std::vector<TypedVar *> &args() const;
- const std::vector<TypedVar *> &results() const;
+ const std::vector<NamedReference<Type>*>& args() const;
+ const std::vector<NamedReference<Type>*>& results() const;
bool isOneway() const { return mOneway; }
bool overridesCppImpl(MethodImplType type) const;
bool overridesJavaImpl(MethodImplType type) const;
@@ -92,7 +89,7 @@
void emitJavaArgSignature(Formatter &out) const;
void emitJavaResultSignature(Formatter &out) const;
- const TypedVar* canElideCallback() const;
+ const NamedReference<Type>* canElideCallback() const;
void dumpAnnotations(Formatter &out) const;
@@ -101,8 +98,8 @@
private:
std::string mName;
size_t mSerial = 0;
- std::vector<TypedVar *> *mArgs;
- std::vector<TypedVar *> *mResults;
+ std::vector<NamedReference<Type>*>* mArgs;
+ std::vector<NamedReference<Type>*>* mResults;
bool mOneway;
std::vector<Annotation *> *mAnnotations;
@@ -115,26 +112,12 @@
DISALLOW_COPY_AND_ASSIGN(Method);
};
-struct TypedVar {
- TypedVar(const char* name, const Reference<Type>& type);
-
- std::string name() const;
- const Type &type() const;
-
- bool isJavaCompatible() const;
-
-private:
- std::string mName;
- Reference<Type> mType;
-
- DISALLOW_COPY_AND_ASSIGN(TypedVar);
-};
-
-struct TypedVarVector : public std::vector<TypedVar *> {
+struct TypedVarVector : public std::vector<NamedReference<Type>*> {
TypedVarVector() = default;
- bool add(TypedVar *v);
-private:
+ bool add(NamedReference<Type>* v);
+
+ private:
std::set<std::string> mNames;
};
diff --git a/Reference.h b/Reference.h
index aab3b8f..afd74cb 100644
--- a/Reference.h
+++ b/Reference.h
@@ -105,6 +105,22 @@
friend struct Reference;
};
+template <class T>
+struct NamedReference {
+ NamedReference(const std::string& name, const Reference<T>& reference)
+ : mName(name), mReference(reference) {}
+
+ const std::string& name() const { return mName; }
+ const T& type() const { return *mReference.get(); }
+ const T* operator->() const { return mReference.get(); }
+
+ private:
+ const std::string mName;
+ const Reference<T> mReference;
+
+ DISALLOW_COPY_AND_ASSIGN(NamedReference<T>);
+};
+
} // namespace android
#endif // REFERENCE_H_
diff --git a/Scope.cpp b/Scope.cpp
index 13a6f28..1cee4f8 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -200,5 +200,9 @@
return false;
}
+ConstantExpression* LocalIdentifier::constExpr() const {
+ return nullptr;
+}
+
} // namespace android
diff --git a/Scope.h b/Scope.h
index 599182f..6a34a59 100644
--- a/Scope.h
+++ b/Scope.h
@@ -25,6 +25,7 @@
namespace android {
+struct ConstantExpression;
struct Formatter;
struct Interface;
struct LocalIdentifier;
@@ -88,6 +89,8 @@
LocalIdentifier();
virtual ~LocalIdentifier();
virtual bool isEnumValue() const;
+
+ virtual ConstantExpression* constExpr() const;
};
} // namespace android
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 368f520..f2147b3 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -18,9 +18,10 @@
#include "Coordinator.h"
#include "EnumType.h"
-#include "Interface.h"
#include "HidlTypeAssertion.h"
+#include "Interface.h"
#include "Method.h"
+#include "Reference.h"
#include "ScalarType.h"
#include "Scope.h"
@@ -489,7 +490,7 @@
out << "\n";
const bool returnsValue = !method->results().empty();
- const TypedVar *elidedReturn = method->canElideCallback();
+ const NamedReference<Type>* elidedReturn = method->canElideCallback();
if (elidedReturn == nullptr && returnsValue) {
out << "using "
@@ -624,9 +625,8 @@
return mRootScope.emitTypeDeclarations(out);
}
-static void wrapPassthroughArg(Formatter &out,
- const TypedVar *arg, bool addPrefixToName,
- std::function<void(void)> handleError) {
+static void wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
+ bool addPrefixToName, std::function<void(void)> handleError) {
if (!arg->type().isInterface()) {
return;
}
@@ -670,7 +670,7 @@
}
const bool returnsValue = !method->results().empty();
- const TypedVar *elidedReturn = method->canElideCallback();
+ const NamedReference<Type>* elidedReturn = method->canElideCallback();
if (returnsValue && elidedReturn == nullptr) {
generateCheckNonNull(out, "_hidl_cb");
@@ -932,7 +932,7 @@
return OK;
}
const bool returnsValue = !method->results().empty();
- const TypedVar *elidedReturn = method->canElideCallback();
+ const NamedReference<Type>* elidedReturn = method->canElideCallback();
if (elidedReturn == nullptr && returnsValue) {
out << "using " << method->name() << "_cb = "
@@ -1233,10 +1233,8 @@
return mRootScope.emitTypeDefinitions(out, ifaceName);
}
-void AST::declareCppReaderLocals(
- Formatter &out,
- const std::vector<TypedVar *> &args,
- bool forResults) const {
+void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
+ bool forResults) const {
if (args.empty()) {
return;
}
@@ -1253,14 +1251,9 @@
out << "\n";
}
-void AST::emitCppReaderWriter(
- Formatter &out,
- const std::string &parcelObj,
- bool parcelObjIsPointer,
- const TypedVar *arg,
- bool isReader,
- Type::ErrorMode mode,
- bool addPrefixToName) const {
+void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
+ const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
+ bool addPrefixToName) const {
const Type &type = arg->type();
type.emitReaderWriter(
@@ -1272,14 +1265,10 @@
mode);
}
-void AST::emitCppResolveReferences(
- Formatter &out,
- const std::string &parcelObj,
- bool parcelObjIsPointer,
- const TypedVar *arg,
- bool isReader,
- Type::ErrorMode mode,
- bool addPrefixToName) const {
+void AST::emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
+ bool parcelObjIsPointer, const NamedReference<Type>* arg,
+ bool isReader, Type::ErrorMode mode,
+ bool addPrefixToName) const {
const Type &type = arg->type();
if(type.needsResolveReferences()) {
type.emitResolveReferences(
@@ -1312,7 +1301,7 @@
out.block([&] {
const bool returnsValue = !method->results().empty();
- const TypedVar *elidedReturn = method->canElideCallback();
+ const NamedReference<Type>* elidedReturn = method->canElideCallback();
method->generateCppReturnType(out);
@@ -1380,7 +1369,7 @@
out << "#endif // __ANDROID_DEBUGGABLE__\n";
const bool returnsValue = !method->results().empty();
- const TypedVar *elidedReturn = method->canElideCallback();
+ const NamedReference<Type>* elidedReturn = method->canElideCallback();
if (returnsValue && elidedReturn == nullptr) {
generateCheckNonNull(out, "_hidl_cb");
}
@@ -1824,7 +1813,7 @@
method);
const bool returnsValue = !method->results().empty();
- const TypedVar *elidedReturn = method->canElideCallback();
+ const NamedReference<Type>* elidedReturn = method->canElideCallback();
const std::string callee = "static_cast<" + klassName + "*>(_hidl_this)->_hidl_mImpl";
if (elidedReturn != nullptr) {
diff --git a/generateCppImpl.cpp b/generateCppImpl.cpp
index ae95590..90331b6 100644
--- a/generateCppImpl.cpp
+++ b/generateCppImpl.cpp
@@ -20,6 +20,7 @@
#include "EnumType.h"
#include "Interface.h"
#include "Method.h"
+#include "Reference.h"
#include "ScalarType.h"
#include "Scope.h"
@@ -62,7 +63,7 @@
out.indent();
out << "// TODO implement\n";
- const TypedVar *elidedReturn = method->canElideCallback();
+ const NamedReference<Type>* elidedReturn = method->canElideCallback();
if (elidedReturn == nullptr) {
out << "return Void();\n";
diff --git a/generateJava.cpp b/generateJava.cpp
index f463b7f..86e785c 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -19,6 +19,7 @@
#include "Coordinator.h"
#include "Interface.h"
#include "Method.h"
+#include "Reference.h"
#include "Scope.h"
#include <hidl-util/Formatter.h>
@@ -26,12 +27,9 @@
namespace android {
-void AST::emitJavaReaderWriter(
- Formatter &out,
- const std::string &parcelObj,
- const TypedVar *arg,
- bool isReader,
- bool addPrefixToName) const {
+void AST::emitJavaReaderWriter(Formatter& out, const std::string& parcelObj,
+ const NamedReference<Type>* arg, bool isReader,
+ bool addPrefixToName) const {
if (isReader) {
out << arg->type().getJavaType()
<< " "
@@ -602,7 +600,7 @@
}
if (!needsCallback && returnsValue) {
- const TypedVar *returnArg = method->results()[0];
+ const NamedReference<Type>* returnArg = method->results()[0];
out << returnArg->type().getJavaType()
<< " _hidl_out_"
@@ -663,7 +661,7 @@
out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
if (returnsValue) {
- const TypedVar *returnArg = method->results()[0];
+ const NamedReference<Type>* returnArg = method->results()[0];
emitJavaReaderWriter(
out,
diff --git a/hidl-gen_y.yy b/hidl-gen_y.yy
index 805f671..664cf8a 100644
--- a/hidl-gen_y.yy
+++ b/hidl-gen_y.yy
@@ -296,12 +296,12 @@
android::TemplatedType *templatedType;
android::FQName *fqName;
android::CompoundType *compoundType;
- android::CompoundField *field;
- std::vector<android::CompoundField *> *fields;
+ android::NamedReference<android::Type>* field;
+ std::vector<android::NamedReference<android::Type>*>* fields;
android::EnumValue *enumValue;
android::ConstantExpression *constantExpression;
std::vector<android::EnumValue *> *enumValues;
- android::TypedVar *typedVar;
+ android::NamedReference<android::Type>* typedVar;
android::TypedVarVector *typedVars;
android::Method *method;
android::CompoundType::Style compoundStyle;
@@ -425,6 +425,7 @@
: const_expr
{
$$ = new std::vector<ConstantExpression *>;
+ $1->evaluate();
$$->push_back($1);
}
| '{' annotation_const_expr_values '}' { $$ = $2; }
@@ -434,11 +435,13 @@
: const_expr
{
$$ = new std::vector<ConstantExpression *>;
+ $1->evaluate();
$$->push_back($1);
}
| annotation_const_expr_values ',' const_expr
{
$$ = $1;
+ $3->evaluate();
$$->push_back($3);
}
;
@@ -757,7 +760,7 @@
;
const_expr
- : INTEGER { $$ = new ConstantExpression($1); }
+ : INTEGER { $$ = new LiteralConstantExpression($1); }
| fqname
{
if(!$1->isValidValueName()) {
@@ -766,6 +769,7 @@
<< @1 << ".\n";
YYERROR;
}
+
if($1->isIdentifier()) {
std::string identifier = $1->name();
LocalIdentifier *iden = (*scope)->lookupIdentifier(identifier);
@@ -779,8 +783,8 @@
<< " is not an enum value at " << @1 << ".\n";
YYERROR;
}
- $$ = new ConstantExpression(
- *(static_cast<EnumValue *>(iden)->constExpr()), $1->string());
+ $$ = new ReferenceConstantExpression(
+ Reference<LocalIdentifier>(iden, convertYYLoc(@1)), $1->string());
} else {
std::string errorMsg;
EnumValue* v = ast->lookupEnumValue(*$1, &errorMsg, *scope);
@@ -789,42 +793,42 @@
YYERROR;
}
- // TODO: Support Reference
- $$ = new ConstantExpression(*(v->constExpr()), $1->string());
+ $$ = new ReferenceConstantExpression(
+ Reference<LocalIdentifier>(v, convertYYLoc(@1)), $1->string());
}
}
| const_expr '?' const_expr ':' const_expr
{
- $$ = new ConstantExpression($1, $3, $5);
+ $$ = new TernaryConstantExpression($1, $3, $5);
}
- | const_expr LOGICAL_OR const_expr { $$ = new ConstantExpression($1, "||", $3); }
- | const_expr LOGICAL_AND const_expr { $$ = new ConstantExpression($1, "&&", $3); }
- | const_expr '|' const_expr { $$ = new ConstantExpression($1, "|" , $3); }
- | const_expr '^' const_expr { $$ = new ConstantExpression($1, "^" , $3); }
- | const_expr '&' const_expr { $$ = new ConstantExpression($1, "&" , $3); }
- | const_expr EQUALITY const_expr { $$ = new ConstantExpression($1, "==", $3); }
- | const_expr NEQ const_expr { $$ = new ConstantExpression($1, "!=", $3); }
- | const_expr '<' const_expr { $$ = new ConstantExpression($1, "<" , $3); }
- | const_expr '>' const_expr { $$ = new ConstantExpression($1, ">" , $3); }
- | const_expr LEQ const_expr { $$ = new ConstantExpression($1, "<=", $3); }
- | const_expr GEQ const_expr { $$ = new ConstantExpression($1, ">=", $3); }
- | const_expr LSHIFT const_expr { $$ = new ConstantExpression($1, "<<", $3); }
- | const_expr RSHIFT const_expr { $$ = new ConstantExpression($1, ">>", $3); }
- | const_expr '+' const_expr { $$ = new ConstantExpression($1, "+" , $3); }
- | const_expr '-' const_expr { $$ = new ConstantExpression($1, "-" , $3); }
- | const_expr '*' const_expr { $$ = new ConstantExpression($1, "*" , $3); }
- | const_expr '/' const_expr { $$ = new ConstantExpression($1, "/" , $3); }
- | const_expr '%' const_expr { $$ = new ConstantExpression($1, "%" , $3); }
- | '+' const_expr %prec UNARY_PLUS { $$ = new ConstantExpression("+", $2); }
- | '-' const_expr %prec UNARY_MINUS { $$ = new ConstantExpression("-", $2); }
- | '!' const_expr { $$ = new ConstantExpression("!", $2); }
- | '~' const_expr { $$ = new ConstantExpression("~", $2); }
+ | const_expr LOGICAL_OR const_expr { $$ = new BinaryConstantExpression($1, "||", $3); }
+ | const_expr LOGICAL_AND const_expr { $$ = new BinaryConstantExpression($1, "&&", $3); }
+ | const_expr '|' const_expr { $$ = new BinaryConstantExpression($1, "|" , $3); }
+ | const_expr '^' const_expr { $$ = new BinaryConstantExpression($1, "^" , $3); }
+ | const_expr '&' const_expr { $$ = new BinaryConstantExpression($1, "&" , $3); }
+ | const_expr EQUALITY const_expr { $$ = new BinaryConstantExpression($1, "==", $3); }
+ | const_expr NEQ const_expr { $$ = new BinaryConstantExpression($1, "!=", $3); }
+ | const_expr '<' const_expr { $$ = new BinaryConstantExpression($1, "<" , $3); }
+ | const_expr '>' const_expr { $$ = new BinaryConstantExpression($1, ">" , $3); }
+ | const_expr LEQ const_expr { $$ = new BinaryConstantExpression($1, "<=", $3); }
+ | const_expr GEQ const_expr { $$ = new BinaryConstantExpression($1, ">=", $3); }
+ | const_expr LSHIFT const_expr { $$ = new BinaryConstantExpression($1, "<<", $3); }
+ | const_expr RSHIFT const_expr { $$ = new BinaryConstantExpression($1, ">>", $3); }
+ | const_expr '+' const_expr { $$ = new BinaryConstantExpression($1, "+" , $3); }
+ | const_expr '-' const_expr { $$ = new BinaryConstantExpression($1, "-" , $3); }
+ | const_expr '*' const_expr { $$ = new BinaryConstantExpression($1, "*" , $3); }
+ | const_expr '/' const_expr { $$ = new BinaryConstantExpression($1, "/" , $3); }
+ | const_expr '%' const_expr { $$ = new BinaryConstantExpression($1, "%" , $3); }
+ | '+' const_expr %prec UNARY_PLUS { $$ = new UnaryConstantExpression("+", $2); }
+ | '-' const_expr %prec UNARY_MINUS { $$ = new UnaryConstantExpression("-", $2); }
+ | '!' const_expr { $$ = new UnaryConstantExpression("!", $2); }
+ | '~' const_expr { $$ = new UnaryConstantExpression("~", $2); }
| '(' const_expr ')' { $$ = $2; }
| '(' error ')'
{
ast->addSyntaxError();
// to avoid segfaults
- $$ = new ConstantExpression(ConstantExpression::Zero(ScalarType::KIND_INT32));
+ $$ = ConstantExpression::Zero(ScalarType::KIND_INT32).release();
}
;
@@ -832,11 +836,11 @@
: error_stmt { $$ = nullptr; }
| opt_annotations valid_identifier '(' typed_vars ')' require_semicolon
{
- $$ = new Method($2, $4, new std::vector<TypedVar *>, false, $1);
+ $$ = new Method($2, $4, new std::vector<NamedReference<Type>*>, false, $1);
}
| opt_annotations ONEWAY valid_identifier '(' typed_vars ')' require_semicolon
{
- $$ = new Method($3, $5, new std::vector<TypedVar *>, true, $1);
+ $$ = new Method($3, $5, new std::vector<NamedReference<Type>*>, true, $1);
}
| opt_annotations valid_identifier '(' typed_vars ')' GENERATES '(' typed_vars ')' require_semicolon
{
@@ -869,7 +873,7 @@
}
;
-typed_var : type valid_identifier { $$ = new TypedVar($2, *$1); }
+typed_var : type valid_identifier { $$ = new NamedReference<Type>($2, *$1); }
;
@@ -915,7 +919,7 @@
;
field_declarations
- : /* empty */ { $$ = new std::vector<CompoundField *>; }
+ : /* empty */ { $$ = new std::vector<NamedReference<Type>*>; }
| field_declarations field_declaration
{
$$ = $1;
@@ -939,7 +943,7 @@
<< @2 << "\n";
YYERROR;
}
- $$ = new CompoundField($2, *$1);
+ $$ = new NamedReference<Type>($2, *$1);
}
| annotated_compound_declaration ';'
{
@@ -1020,7 +1024,7 @@
enum_value
: valid_identifier { $$ = new EnumValue($1); }
- | valid_identifier '=' const_expr { $$ = new EnumValue($1, $3); }
+ | valid_identifier '=' const_expr { $3->evaluate(); $$ = new EnumValue($1, $3); }
;
enum_values
@@ -1096,6 +1100,8 @@
YYERROR;
}
+
+ $3->evaluate();
if (type.isResolved() && type->isArray()) {
$$ = new ArrayType(static_cast<ArrayType*>(type.get()), $3);
} else {
@@ -1105,6 +1111,7 @@
| array_type '[' const_expr ']'
{
$$ = $1;
+ $3->evaluate();
$$->appendDimension($3);
}
;
@@ -1134,8 +1141,6 @@
%%
-#include <android-base/logging.h>
-
void yy::parser::error(
const yy::parser::location_type &where,
const std::string &errstr) {
diff --git a/main.cpp b/main.cpp
index 8c4a760..af53171 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1307,8 +1307,10 @@
}
// hidl is intentionally leaky. Turn off LeakSanitizer by default.
+// Also disable container overflow detection to prevent false
+// positives (b/64564544)
extern "C" const char *__asan_default_options() {
- return "detect_leaks=0";
+ return "detect_leaks=0:detect_container_overflow=0";
}
int main(int argc, char **argv) {