/*
 * Copyright (C) 2016 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.
 */

#include "ConstantExpression.h"

#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>

#include "EnumType.h"
#include "Scope.h"  // LocalIdentifier

// The macros are really nasty here. Consider removing
// as many macros as possible.

#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("!="))
#define OP_IS_BIN_SHIFT       (OPEQ(">>") || OPEQ("<<"))
#define OP_IS_BIN_LOGICAL     (OPEQ("||") || OPEQ("&&"))
#define SK(__x__) ScalarType::Kind::KIND_##__x__
#define SHOULD_NOT_REACH() CHECK(false) << __LINE__ << ": should not reach here: "

// NOLINT to suppress missing parentheses warnings about __def__.
#define SWITCH_KIND(__cond__, __action__, __def__)           \
        switch(__cond__) {                                        \
            case SK(BOOL): __action__(bool)                         \
            case SK(UINT8): __action__(uint8_t)                     \
            case SK(INT8): __action__(int8_t)                       \
            case SK(UINT16): __action__(uint16_t)                   \
            case SK(INT16): __action__(int16_t)                     \
            case SK(UINT32): __action__(uint32_t)                   \
            case SK(INT32): __action__(int32_t)                     \
            case SK(UINT64): __action__(uint64_t)                   \
            case SK(INT64): __action__(int64_t)                     \
            default: __def__                        /* NOLINT */    \
        }

namespace android {

static inline bool isSupported(ScalarType::Kind kind) {
    return SK(BOOL) == kind || ScalarType(kind, nullptr /* parent */).isValidEnumStorageType();
}

/* See docs at the end for details on integral promotion. */
ScalarType::Kind integralPromotion(ScalarType::Kind in) {
    return SK(INT32) < in ? in : SK(INT32); // note that KIND_INT32 < KIND_UINT32
}

/* See docs at the end for details on usual arithmetic conversion. */
ScalarType::Kind usualArithmeticConversion(ScalarType::Kind lft,
                                           ScalarType::Kind rgt) {
    CHECK(isSupported(lft) && isSupported(rgt));
    // Kinds in concern: bool, (u)int[8|16|32|64]
    if(lft == rgt) return lft; // easy case
    if(lft == SK(BOOL)) return rgt;
    if(rgt == SK(BOOL)) return lft;
    bool isLftSigned = (lft == SK(INT8))  || (lft == SK(INT16))
                    || (lft == SK(INT32)) || (lft == SK(INT64));
    bool isRgtSigned = (rgt == SK(INT8))  || (rgt == SK(INT16))
                    || (rgt == SK(INT32)) || (rgt == SK(INT64));
    if(isLftSigned == isRgtSigned) return lft < rgt ? rgt : lft;
    ScalarType::Kind unsignedRank = isLftSigned ? rgt : lft;
    ScalarType::Kind signedRank   = isLftSigned ? lft : rgt;
    if(unsignedRank >= signedRank) return unsignedRank;
    if(signedRank > unsignedRank)  return signedRank;

    // Although there is such rule to return "the unsigned counterpart of
    // the signed operand", it should not reach here in our HIDL grammar.
    CHECK(false) << "Could not do usual arithmetic conversion for type " << lft << "and" << rgt;
    switch(signedRank) {
        case SK(INT8):  return SK(UINT8);
        case SK(INT16): return SK(UINT16);
        case SK(INT32): return SK(UINT32);
        case SK(INT64): return SK(UINT64);
        default: return SK(UINT64);
    }
}

template <class T>
T handleUnary(const std::string& op, T val) {
    COMPUTE_UNARY(+)
    COMPUTE_UNARY(-)
    COMPUTE_UNARY(!)

// bitwise negation of a boolean expression always evaluates to 'true'
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wbool-operation"
    COMPUTE_UNARY(~)
#pragma clang diagnostic pop

    // Should not reach here.
    SHOULD_NOT_REACH() << "Could not handleUnary for " << op << " " << val;
    return static_cast<T>(0xdeadbeef);
}

template <class T>
T handleBinaryCommon(T lval, const std::string& op, T rval) {
    COMPUTE_BINARY(+)
    COMPUTE_BINARY(-)
    COMPUTE_BINARY(*)
    COMPUTE_BINARY(/)
    COMPUTE_BINARY(%)
    COMPUTE_BINARY(|)
    COMPUTE_BINARY(^)
    COMPUTE_BINARY(&)
    // comparison operators: return 0 or 1 by nature.
    COMPUTE_BINARY(==)
    COMPUTE_BINARY(!=)
    COMPUTE_BINARY(<)
    COMPUTE_BINARY(>)
    COMPUTE_BINARY(<=)
    COMPUTE_BINARY(>=)
    // Should not reach here.
    SHOULD_NOT_REACH() << "Could not handleBinaryCommon for "
                       << lval << " " << op << " " << rval;
    return static_cast<T>(0xdeadbeef);
}

template <class T>
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 "
                       << lval << " " << op << " " << rval;
    return static_cast<T>(0xdeadbeef);
}

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 "
                       << lval << " " << op << " " << rval;
    return false;
}

std::unique_ptr<ConstantExpression> ConstantExpression::Zero(ScalarType::Kind kind) {
    return ValueOf(kind, 0);
}

std::unique_ptr<ConstantExpression> ConstantExpression::One(ScalarType::Kind kind) {
    return ValueOf(kind, 1);
}

std::unique_ptr<ConstantExpression> ConstantExpression::ValueOf(ScalarType::Kind kind,
                                                                uint64_t value) {
    return std::make_unique<LiteralConstantExpression>(kind, value);
}

ConstantExpression::ConstantExpression(const std::string& expr) : mExpr(expr) {}

bool ConstantExpression::isEvaluated() const {
    return mIsEvaluated;
}

LiteralConstantExpression::LiteralConstantExpression(ScalarType::Kind kind, uint64_t value,
                                                     const std::string& expr)
    : ConstantExpression(expr) {
    CHECK(!expr.empty());
    CHECK(isSupported(kind));

    mTrivialDescription = std::to_string(value) == expr;
    mValueKind = kind;
    mValue = value;
    mIsEvaluated = true;
}

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());

    bool isLong = false, isUnsigned = false;
    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');
    }
    std::string newVal(value.begin(), rbegin.base());
    CHECK(!newVal.empty());

    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
            kind = SK(UINT64);
        else // l
            kind = SK(INT64);
    } else { // no l suffix
        if(isUnsigned) { // u
            if(rawValue <= UINT32_MAX)
                kind = SK(UINT32);
            else
                kind = SK(UINT64);
        } else { // no suffix
            if(isHex) {
                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
                    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() {
    // Evaluated in constructor
    CHECK(isEvaluated());
}

void UnaryConstantExpression::evaluate() {
    if (isEvaluated()) return;
    CHECK(mUnary->isEvaluated());
    mIsEvaluated = true;

    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;)
}

void BinaryConstantExpression::evaluate() {
    if (isEvaluated()) return;
    CHECK(mLval->isEvaluated());
    CHECK(mRval->isEvaluated());
    mIsEvaluated = true;

    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(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__>(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(mLval->mValueKind);
        // instead of promoting rval, simply casting it to int64 should also be good.
        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.
            newOp = OPEQ("<<") ? std::string(">>") : std::string("<<");
            numBits = -numBits;
        }

#define CASE_SHIFT(__type__)                                                    \
    mValue = handleShift(static_cast<__type__>(mLval->mValue), newOp, numBits); \
    return;

        SWITCH_KIND(mValueKind, CASE_SHIFT, SHOULD_NOT_REACH(); return;)
    }

    // CASE 3: && ||
    if(OP_IS_BIN_LOGICAL) {
        mValueKind = SK(BOOL);
        // easy; everything is bool.
        mValue = handleLogical(mLval->mValue, mOp, mRval->mValue);
        return;
    }

    SHOULD_NOT_REACH();
}

void TernaryConstantExpression::evaluate() {
    if (isEvaluated()) return;
    CHECK(mCond->isEvaluated());
    CHECK(mTrueVal->isEvaluated());
    CHECK(mFalseVal->isEvaluated());
    mIsEvaluated = true;

    // note: for ?:, unlike arithmetic ops, integral promotion is not processed.
    mValueKind = usualArithmeticConversion(mTrueVal->mValueKind, mFalseVal->mValueKind);

#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;)
}

void ReferenceConstantExpression::evaluate() {
    if (isEvaluated()) return;
    CHECK(mReference->constExpr() != nullptr);

    ConstantExpression* expr = mReference->constExpr();
    CHECK(expr->isEvaluated());

    mValueKind = expr->mValueKind;
    mValue = expr->mValue;
    mIsEvaluated = true;
}

status_t AttributeConstantExpression::validate() const {
    if (mTag == "len") {
        if (!mReference->isEnum()) {
            std::cerr << "ERROR: " << mExpr << " refers to " << mReference->typeName()
                      << " but should refer to an enum." << std::endl;
            return UNKNOWN_ERROR;
        }
    } else {
        std::cerr << "ERROR: " << mExpr << " is not a supported tag" << std::endl;
        return UNKNOWN_ERROR;
    }

    return OK;
}

void AttributeConstantExpression::evaluate() {
    if (isEvaluated()) return;

    CHECK(mTag == "len");
    CHECK(mReference->isEnum());

    EnumType* enumType = static_cast<EnumType*>(mReference.get());
    mValue = enumType->numValueNames();

    if (mValue <= INT32_MAX)
        mValueKind = SK(INT32);
    else
        mValueKind = SK(INT64);

    mIsEvaluated = true;
}

std::unique_ptr<ConstantExpression> ConstantExpression::addOne(ScalarType::Kind baseKind) {
    auto ret = std::make_unique<BinaryConstantExpression>(
        this, "+", ConstantExpression::One(baseKind).release());
    return ret;
}

std::string ConstantExpression::value() const {
    return value(mValueKind);
}

std::string ConstantExpression::value(ScalarType::Kind castKind) const {
    CHECK(isEvaluated());
    return rawValue(castKind) + descriptionSuffix();
}

std::string ConstantExpression::cppValue() const {
    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 };
    // into
    //       enum class x : int64_t { y = (int64_t)-9223372036854775808ull };
    // by adding the explicit cast.
    // Because 9223372036854775808 is uint64_t, and
    // -(uint64_t)9223372036854775808 == 9223372036854775808 could not
    // be narrowed to int64_t.
    if(castKind == SK(INT64) && (int64_t)mValue == INT64_MIN) {
        literal = "static_cast<" +
                  ScalarType(SK(INT64), nullptr /* parent */).getCppStackType()  // "int64_t"
                  + ">(" + literal + "ull)";
    } else {
        // add suffix if necessary.
        if (castKind == SK(UINT32) || castKind == SK(UINT64)) literal += "u";
        if (castKind == SK(UINT64) || castKind == SK(INT64)) literal += "ll";
    }

    return literal + descriptionSuffix();
}

std::string ConstantExpression::javaValue() const {
    return javaValue(mValueKind);
}

std::string ConstantExpression::javaValue(ScalarType::Kind castKind) const {
    CHECK(isEvaluated());
    std::string literal;

    switch(castKind) {
        case SK(UINT64):
            literal = rawValue(SK(INT64)) + "L";
            break;
        case SK(INT64):
            literal = rawValue(SK(INT64)) + "L";
            break;
        case SK(UINT32):
            literal = rawValue(SK(INT32));
            break;
        case SK(UINT16):
            literal = rawValue(SK(INT16));
            break;
        case SK(UINT8):
            literal = rawValue(SK(INT8));
            break;
        case SK(BOOL)  :
            literal = this->cast<bool>() ? "true" : "false";
            break;
        default:
            literal = rawValue(castKind);
            break;
    }

    return literal + descriptionSuffix();
}

const std::string& ConstantExpression::expression() const {
    return mExpr;
}

std::string ConstantExpression::rawValue() const {
    return rawValue(mValueKind);
}

std::string ConstantExpression::rawValue(ScalarType::Kind castKind) const {
    CHECK(isEvaluated());

#define CASE_STR(__type__) return std::to_string(this->cast<__type__>());

    SWITCH_KIND(castKind, CASE_STR, SHOULD_NOT_REACH(); return nullptr; );
}

template<typename T>
T ConstantExpression::cast() const {
    CHECK(isEvaluated());

#define CASE_CAST_T(__type__) return static_cast<T>(static_cast<__type__>(mValue));

    SWITCH_KIND(mValueKind, CASE_CAST_T, SHOULD_NOT_REACH(); return 0; );
}

std::string ConstantExpression::descriptionSuffix() const {
    CHECK(isEvaluated());

    if (!mTrivialDescription) {
        CHECK(!mExpr.empty());

        return " /* " + mExpr + " */";
    }
    return "";
}

size_t ConstantExpression::castSizeT() const {
    CHECK(isEvaluated());
    return this->cast<size_t>();
}

bool ConstantExpression::isReferenceConstantExpression() const {
    return false;
}

status_t ConstantExpression::validate() const {
    return OK;
}

std::vector<ConstantExpression*> ConstantExpression::getConstantExpressions() {
    const auto& constRet = static_cast<const ConstantExpression*>(this)->getConstantExpressions();
    std::vector<ConstantExpression*> ret(constRet.size());
    std::transform(constRet.begin(), constRet.end(), ret.begin(),
                   [](const auto* ce) { return const_cast<ConstantExpression*>(ce); });
    return ret;
}

std::vector<Reference<LocalIdentifier>*> ConstantExpression::getReferences() {
    const auto& constRet = static_cast<const ConstantExpression*>(this)->getReferences();
    std::vector<Reference<LocalIdentifier>*> ret(constRet.size());
    std::transform(constRet.begin(), constRet.end(), ret.begin(),
                   [](const auto* ce) { return const_cast<Reference<LocalIdentifier>*>(ce); });
    return ret;
}

std::vector<const Reference<LocalIdentifier>*> ConstantExpression::getReferences() const {
    return {};
}

std::vector<Reference<Type>*> ConstantExpression::getTypeReferences() {
    const auto& constRet = static_cast<const ConstantExpression*>(this)->getTypeReferences();
    std::vector<Reference<Type>*> ret(constRet.size());
    std::transform(constRet.begin(), constRet.end(), ret.begin(),
                   [](const auto* ce) { return const_cast<Reference<Type>*>(ce); });
    return ret;
}

std::vector<const Reference<Type>*> ConstantExpression::getTypeReferences() const {
    return {};
}

status_t ConstantExpression::recursivePass(const std::function<status_t(ConstantExpression*)>& func,
                                           std::unordered_set<const ConstantExpression*>* visited,
                                           bool processBeforeDependencies) {
    if (mIsPostParseCompleted) return OK;

    if (visited->find(this) != visited->end()) return OK;
    visited->insert(this);

    if (processBeforeDependencies) {
        status_t err = func(this);
        if (err != OK) return err;
    }

    for (auto* nextCE : getConstantExpressions()) {
        status_t err = nextCE->recursivePass(func, visited, processBeforeDependencies);
        if (err != OK) return err;
    }

    for (auto* nextRef : getReferences()) {
        auto* nextCE = nextRef->shallowGet()->constExpr();
        CHECK(nextCE != nullptr) << "Local identifier is not a constant expression";
        status_t err = nextCE->recursivePass(func, visited, processBeforeDependencies);
        if (err != OK) return err;
    }

    if (!processBeforeDependencies) {
        status_t err = func(this);
        if (err != OK) return err;
    }

    return OK;
}

status_t ConstantExpression::recursivePass(
    const std::function<status_t(const ConstantExpression*)>& func,
    std::unordered_set<const ConstantExpression*>* visited, bool processBeforeDependencies) const {
    if (mIsPostParseCompleted) return OK;

    if (visited->find(this) != visited->end()) return OK;
    visited->insert(this);

    if (processBeforeDependencies) {
        status_t err = func(this);
        if (err != OK) return err;
    }

    for (const auto* nextCE : getConstantExpressions()) {
        status_t err = nextCE->recursivePass(func, visited, processBeforeDependencies);
        if (err != OK) return err;
    }

    for (const auto* nextRef : getReferences()) {
        const auto* nextCE = nextRef->shallowGet()->constExpr();
        CHECK(nextCE != nullptr) << "Local identifier is not a constant expression";
        status_t err = nextCE->recursivePass(func, visited, processBeforeDependencies);
        if (err != OK) return err;
    }

    if (!processBeforeDependencies) {
        status_t err = func(this);
        if (err != OK) return err;
    }

    return OK;
}

ConstantExpression::CheckAcyclicStatus::CheckAcyclicStatus(
    status_t status, const ConstantExpression* cycleEnd,
    const ReferenceConstantExpression* lastReference)
    : status(status), cycleEnd(cycleEnd), lastReference(lastReference) {
    CHECK(cycleEnd == nullptr || status != OK);
    CHECK((cycleEnd == nullptr) == (lastReference == nullptr));
}

ConstantExpression::CheckAcyclicStatus ConstantExpression::checkAcyclic(
    std::unordered_set<const ConstantExpression*>* visited,
    std::unordered_set<const ConstantExpression*>* stack) const {
    if (stack->find(this) != stack->end()) {
        CHECK(isReferenceConstantExpression())
            << "Only reference constant expression could be the cycle end";

        std::cerr << "ERROR: Cyclic declaration:\n";
        return CheckAcyclicStatus(UNKNOWN_ERROR, this,
                                  static_cast<const ReferenceConstantExpression*>(this));
    }

    if (visited->find(this) != visited->end()) return CheckAcyclicStatus(OK);
    visited->insert(this);
    stack->insert(this);

    for (const auto* nextCE : getConstantExpressions()) {
        auto err = nextCE->checkAcyclic(visited, stack);
        if (err.status != OK) {
            return err;
        }
    }

    for (const auto* nextRef : getReferences()) {
        const auto* nextCE = nextRef->shallowGet()->constExpr();
        CHECK(nextCE != nullptr) << "Local identifier is not a constant expression";
        auto err = nextCE->checkAcyclic(visited, stack);

        if (err.status != OK) {
            if (err.cycleEnd == nullptr) return err;

            // Only ReferenceConstantExpression has references,
            CHECK(isReferenceConstantExpression())
                << "Only reference constant expression could have refereneces";

            // mExpr is defined explicitly before evaluation
            std::cerr << "  '" << err.lastReference->mExpr << "' in '" << mExpr << "' at "
                      << nextRef->location() << "\n";

            if (err.cycleEnd == this) {
                return CheckAcyclicStatus(err.status);
            }
            return CheckAcyclicStatus(err.status, err.cycleEnd,
                                      static_cast<const ReferenceConstantExpression*>(this));
        }
    }

    CHECK(stack->find(this) != stack->end());
    stack->erase(this);
    return CheckAcyclicStatus(OK);
}

void ConstantExpression::setPostParseCompleted() {
    CHECK(!mIsPostParseCompleted);
    mIsPostParseCompleted = true;
}

void ConstantExpression::surroundWithParens() {
    mExpr = "(" + mExpr + ")";
}

std::vector<const ConstantExpression*> LiteralConstantExpression::getConstantExpressions() const {
    return {};
}

UnaryConstantExpression::UnaryConstantExpression(const std::string& op, ConstantExpression* value)
    : ConstantExpression(op + value->mExpr), mUnary(value), mOp(op) {}

std::vector<const ConstantExpression*> UnaryConstantExpression::getConstantExpressions() const {
    return {mUnary};
}

BinaryConstantExpression::BinaryConstantExpression(ConstantExpression* lval, const std::string& op,
                                                   ConstantExpression* rval)
    : ConstantExpression(lval->mExpr + " " + op + " " + rval->mExpr),
      mLval(lval),
      mRval(rval),
      mOp(op) {}

std::vector<const ConstantExpression*> BinaryConstantExpression::getConstantExpressions() const {
    return {mLval, mRval};
}

TernaryConstantExpression::TernaryConstantExpression(ConstantExpression* cond,
                                                     ConstantExpression* trueVal,
                                                     ConstantExpression* falseVal)
    : ConstantExpression(cond->mExpr + "?" + trueVal->mExpr + ":" + falseVal->mExpr),
      mCond(cond),
      mTrueVal(trueVal),
      mFalseVal(falseVal) {}

std::vector<const ConstantExpression*> TernaryConstantExpression::getConstantExpressions() const {
    return {mCond, mTrueVal, mFalseVal};
}

ReferenceConstantExpression::ReferenceConstantExpression(const Reference<LocalIdentifier>& value,
                                                         const std::string& expr)
    : ConstantExpression(expr), mReference(value) {
    mTrivialDescription = mExpr.empty();
}

bool ReferenceConstantExpression::isReferenceConstantExpression() const {
    return true;
}

std::vector<const ConstantExpression*> ReferenceConstantExpression::getConstantExpressions() const {
    // Returns reference instead
    return {};
}

std::vector<const Reference<LocalIdentifier>*> ReferenceConstantExpression::getReferences() const {
    return {&mReference};
}

AttributeConstantExpression::AttributeConstantExpression(const Reference<Type>& value,
                                                         const std::string& fqname,
                                                         const std::string& tag)
    : ConstantExpression(fqname + "#" + tag), mReference(value), mTag(tag) {}

std::vector<const ConstantExpression*> AttributeConstantExpression::getConstantExpressions() const {
    // Returns reference instead
    return {};
}

std::vector<const Reference<Type>*> AttributeConstantExpression::getTypeReferences() const {
    return {&mReference};
}

/*

Evaluating expressions in HIDL language

The following rules are mostly like that in:
http://en.cppreference.com/w/cpp/language/operator_arithmetic
http://en.cppreference.com/w/cpp/language/operator_logical
http://en.cppreference.com/w/cpp/language/operator_comparison
http://en.cppreference.com/w/cpp/language/operator_other

The type of literal is the first type which the value
can fit from the list of types depending on the suffix and bases.

suffix              decimal bases           hexadecimal bases
no suffix           int32_t                 int32_t
                    int64_t                 uint32_t
                                            int64_t
                                            uint64_t

u/U                 uint32_t                (same as left)
                    uint64_t

l/L                 int64_t                 int64_t

ul/UL/uL/Ul         uint64_t                uint64_t


Note: There are no negative integer literals.
      -1 is the unary minus applied to 1.

Unary arithmetic and bitwise operators (~ + -):
  don't change the type of the argument.
  (so -1u = -(1u) has type uint32_t)

Binary arithmetic and bitwise operators (except shifts) (+ - * / % & | ^):
1. Integral promotion is first applied on both sides.
2. If both operands have the same type, no promotion is necessary.
3. Usual arithmetic conversions.

Integral promotion: if an operand is of a type with less than 32 bits,
(including bool), it is promoted to int32_t.

Usual arithmetic conversions:
1. If operands are both signed or both unsigned, lesser conversion rank is
   converted to greater conversion rank.
2. Otherwise, if unsigned's rank >= signed's rank, -> unsigned's type
3. Otherwise, if signed's type can hold all values in unsigned's type,
   -> signed's type
4. Otherwise, both converted to the unsigned counterpart of the signed operand's
   type.
rank: bool < int8_t < int16_t < int32_t < int64_t


Shift operators (<< >>):
1. Integral promotion is applied on both sides.
2. For unsigned a, a << b discards bits that shifts out.
   For signed non-negative a, a << b is legal if no bits shifts out, otherwise error.
   For signed negative a, a << b gives error.
3. For unsigned and signed non-negative a, a >> b discards bits that shifts out.
   For signed negative a, a >> b discards bits that shifts out, and the signed
   bit gets extended. ("arithmetic right shift")
4. Shifting with negative number of bits is undefined. (Currently, the
   parser will shift into the other direction. This behavior may change.)
5. Shifting with number of bits exceeding the width of the type is undefined.
   (Currently, 1 << 32 == 1. This behavior may change.)

Logical operators (!, &&, ||):
1. Convert first operand to bool. (true if non-zero, false otherwise)
2. If short-circuited, return the result as type bool, value 1 or 0.
3. Otherwise, convert second operand to bool, evaluate the result, and return
   the result in the same fashion.

Arithmetic comparison operators (< > <= >= == !=):
1. Promote operands in the same way as binary arithmetic and bitwise operators.
   (Integral promotion + Usual arithmetic conversions)
2. Return type bool, value 0 or 1 the same way as logical operators.

Ternary conditional operator (?:):
1. Evaluate the conditional and evaluate the operands.
2. Return type of expression is the type under usual arithmetic conversions on
   the second and third operand. (No integral promotions necessary.)

*/

}  // namespace android

