1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "ConstantExpression.h" 18 19#include <stdio.h> 20#include <string> 21#include <android-base/parseint.h> 22#include <android-base/logging.h> 23#include <sstream> 24 25#include "EnumType.h" 26 27// The macros are really nasty here. Consider removing 28// as many macros as possible. 29 30#define STREQ(__x__, __y__) (strcmp((__x__), (__y__)) == 0) 31#define OPEQ(__y__) STREQ(op, __y__) 32#define COMPUTE_UNARY(__op__) if(OPEQ(#__op__)) return __op__ val; 33#define COMPUTE_BINARY(__op__) if(OPEQ(#__op__)) return lval __op__ rval; 34#define OP_IS_BIN_ARITHMETIC (OPEQ("+") || OPEQ("-") || OPEQ("*") || OPEQ("/") || OPEQ("%")) 35#define OP_IS_BIN_BITFLIP (OPEQ("|") || OPEQ("^") || OPEQ("&")) 36#define OP_IS_BIN_COMP (OPEQ("<") || OPEQ(">") || OPEQ("<=") || OPEQ(">=") || OPEQ("==") || OPEQ("!=")) 37#define OP_IS_BIN_SHIFT (OPEQ(">>") || OPEQ("<<")) 38#define OP_IS_BIN_LOGICAL (OPEQ("||") || OPEQ("&&")) 39#define SK(__x__) ScalarType::Kind::KIND_##__x__ 40#define SHOULD_NOT_REACH() CHECK(false) << __LINE__ << ": should not reach here: " 41 42#define SWITCH_KIND(__cond__, __action__, __def__) \ 43 switch(__cond__) { \ 44 case SK(BOOL): __action__(bool) \ 45 case SK(UINT8): __action__(uint8_t) \ 46 case SK(INT8): __action__(int8_t) \ 47 case SK(UINT16): __action__(uint16_t) \ 48 case SK(INT16): __action__(int16_t) \ 49 case SK(UINT32): __action__(uint32_t) \ 50 case SK(INT32): __action__(int32_t) \ 51 case SK(UINT64): __action__(uint64_t) \ 52 case SK(INT64): __action__(int64_t) \ 53 default: __def__ \ 54 } \ 55 56namespace android { 57 58static inline bool isSupported(ScalarType::Kind kind) { 59 return SK(BOOL) == kind || ScalarType(kind).isValidEnumStorageType(); 60} 61 62/* See docs at the end for details on integral promotion. */ 63ScalarType::Kind integralPromotion(ScalarType::Kind in) { 64 return SK(INT32) < in ? in : SK(INT32); // note that KIND_INT32 < KIND_UINT32 65} 66 67/* See docs at the end for details on usual arithmetic conversion. */ 68ScalarType::Kind usualArithmeticConversion(ScalarType::Kind lft, 69 ScalarType::Kind rgt) { 70 CHECK(isSupported(lft) && isSupported(rgt)); 71 // Kinds in concern: bool, (u)int[8|16|32|64] 72 if(lft == rgt) return lft; // easy case 73 if(lft == SK(BOOL)) return rgt; 74 if(rgt == SK(BOOL)) return lft; 75 bool isLftSigned = (lft == SK(INT8)) || (lft == SK(INT16)) 76 || (lft == SK(INT32)) || (lft == SK(INT64)); 77 bool isRgtSigned = (rgt == SK(INT8)) || (rgt == SK(INT16)) 78 || (rgt == SK(INT32)) || (rgt == SK(INT64)); 79 if(isLftSigned == isRgtSigned) return lft < rgt ? rgt : lft; 80 ScalarType::Kind unsignedRank = isLftSigned ? rgt : lft; 81 ScalarType::Kind signedRank = isLftSigned ? lft : rgt; 82 if(unsignedRank >= signedRank) return unsignedRank; 83 if(signedRank > unsignedRank) return signedRank; 84 85 // Although there is such rule to return "the unsigned counterpart of 86 // the signed operand", it should not reach here in our HIDL grammar. 87 LOG(FATAL) << "Could not do usual arithmetic conversion for type " 88 << lft << "and" << rgt; 89 switch(signedRank) { 90 case SK(INT8): return SK(UINT8); 91 case SK(INT16): return SK(UINT16); 92 case SK(INT32): return SK(UINT32); 93 case SK(INT64): return SK(UINT64); 94 default: return SK(UINT64); 95 } 96} 97 98template <class T> 99T handleUnary(const char *op, T val) { 100 COMPUTE_UNARY(+) 101 COMPUTE_UNARY(-) 102 COMPUTE_UNARY(!) 103 COMPUTE_UNARY(~) 104 // Should not reach here. 105 SHOULD_NOT_REACH() << "Could not handleUnary for " << op << " " << val; 106 return static_cast<T>(0xdeadbeef); 107} 108 109template <class T> 110T handleBinaryCommon(T lval, const char *op, T rval) { 111 COMPUTE_BINARY(+) 112 COMPUTE_BINARY(-) 113 COMPUTE_BINARY(*) 114 COMPUTE_BINARY(/) 115 COMPUTE_BINARY(%) 116 COMPUTE_BINARY(|) 117 COMPUTE_BINARY(^) 118 COMPUTE_BINARY(&) 119 // comparison operators: return 0 or 1 by nature. 120 COMPUTE_BINARY(==) 121 COMPUTE_BINARY(!=) 122 COMPUTE_BINARY(<) 123 COMPUTE_BINARY(>) 124 COMPUTE_BINARY(<=) 125 COMPUTE_BINARY(>=) 126 // Should not reach here. 127 SHOULD_NOT_REACH() << "Could not handleBinaryCommon for " 128 << lval << " " << op << " " << rval; 129 return static_cast<T>(0xdeadbeef); 130} 131 132template <class T> 133T handleShift(T lval, const char *op, int64_t rval) { 134 // just cast rval to int64_t and it should fit. 135 COMPUTE_BINARY(>>) 136 COMPUTE_BINARY(<<) 137 // Should not reach here. 138 SHOULD_NOT_REACH() << "Could not handleShift for" 139 << lval << " " << op << " " << rval; 140 return static_cast<T>(0xdeadbeef); 141} 142 143bool handleLogical(bool lval, const char *op, bool rval) { 144 COMPUTE_BINARY(||); 145 COMPUTE_BINARY(&&); 146 // Should not reach here. 147 SHOULD_NOT_REACH() << "Could not handleLogical for" 148 << lval << " " << op << " " << rval; 149 return false; 150} 151 152ConstantExpression::ConstantExpression() { 153} 154 155ConstantExpression ConstantExpression::Zero(ScalarType::Kind kind) { 156 ConstantExpression ce = ValueOf(kind, 0); 157 ce.mExpr = "0"; 158 return ce; 159} 160 161ConstantExpression ConstantExpression::One(ScalarType::Kind kind) { 162 ConstantExpression ce = ValueOf(kind, 1); 163 ce.mExpr = "1"; 164 return ce; 165} 166 167ConstantExpression ConstantExpression::ValueOf(ScalarType::Kind kind, uint64_t value) { 168 ConstantExpression ce; 169 CHECK(isSupported(kind)); 170 171 ce.mExpr = ""; 172 ce.mType = kConstExprLiteral; 173 ce.mValueKind = kind; 174 ce.mValue = value; 175 ce.mTrivialDescription = true; 176 return ce; 177} 178ConstantExpression::ConstantExpression(const ConstantExpression& other) { 179 *this = other; 180} 181 182/* Copy constructor, with the expr overriden and treated non-trivial */ 183ConstantExpression::ConstantExpression(const ConstantExpression& other, std::string expr) { 184 *this = other; 185 mExpr = expr; 186 mTrivialDescription = false; 187} 188 189ConstantExpression& ConstantExpression::operator=(const ConstantExpression& other) { 190 mType = other.mType; 191 mValueKind = other.mValueKind; 192 mValue = other.mValue; 193 mExpr = other.mExpr; 194 mTrivialDescription = other.mTrivialDescription; 195 return *this; 196} 197 198/* Literals. */ 199ConstantExpression::ConstantExpression(const char *value) 200 : mExpr(value), mType(kConstExprLiteral), mTrivialDescription(true) { 201 const char* head = value, *tail = head + strlen(value) - 1; 202 bool isLong = false, isUnsigned = false; 203 bool isHex = (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')); 204 while(tail >= head && (*tail == 'u' || *tail == 'U' || *tail == 'l' || *tail == 'L')) { 205 isUnsigned |= (*tail == 'u' || *tail == 'U'); 206 isLong |= (*tail == 'l' || *tail == 'L'); 207 tail--; 208 } 209 char *newVal = strndup(value, tail - head + 1); 210 bool parseOK = base::ParseUint(newVal, &mValue); 211 free(newVal); 212 CHECK(parseOK) << "Could not parse as integer: " << value; 213 214 // guess literal type. 215 if(isLong) { 216 if(isUnsigned) // ul 217 mValueKind = SK(UINT64); 218 else // l 219 mValueKind = SK(INT64); 220 } else { // no l suffix 221 if(isUnsigned) { // u 222 if(mValue <= UINT32_MAX) 223 mValueKind = SK(UINT32); 224 else 225 mValueKind = SK(UINT64); 226 } else { // no suffix 227 if(isHex) { 228 if(mValue <= INT32_MAX) // mValue always >= 0 229 mValueKind = SK(INT32); 230 else if(mValue <= UINT32_MAX) 231 mValueKind = SK(UINT32); 232 else if(mValue <= INT64_MAX) // mValue always >= 0 233 mValueKind = SK(INT64); 234 else if(mValue <= UINT64_MAX) 235 mValueKind = SK(UINT64); 236 } else { 237 if(mValue <= INT32_MAX) // mValue always >= 0 238 mValueKind = SK(INT32); 239 else 240 mValueKind = SK(INT64); 241 } 242 } 243 } 244} 245 246/* Unary operations. */ 247ConstantExpression::ConstantExpression(const char *op, 248 const ConstantExpression *value) 249 : mExpr(std::string("(") + op + value->mExpr + ")"), 250 mType(kConstExprUnary), 251 mValueKind(value->mValueKind) { 252 253#define CASE_UNARY(__type__)\ 254 mValue = handleUnary(op, static_cast<__type__>(value->mValue)); return; 255 256 SWITCH_KIND(mValueKind, CASE_UNARY, SHOULD_NOT_REACH(); return;) 257} 258 259/* Binary operations. */ 260ConstantExpression::ConstantExpression(const ConstantExpression *lval, 261 const char *op, 262 const ConstantExpression* rval) 263 : mExpr(std::string("(") + lval->mExpr + " " + op + " " + rval->mExpr + ")"), 264 mType(kConstExprBinary) 265{ 266 267 bool isArithmeticOrBitflip = OP_IS_BIN_ARITHMETIC || OP_IS_BIN_BITFLIP; 268 269 // CASE 1: + - * / % | ^ & < > <= >= == != 270 if(isArithmeticOrBitflip || OP_IS_BIN_COMP) { 271 // promoted kind for both operands. 272 ScalarType::Kind promoted = usualArithmeticConversion( 273 integralPromotion(lval->mValueKind), 274 integralPromotion(rval->mValueKind)); 275 // result kind. 276 mValueKind = isArithmeticOrBitflip 277 ? promoted // arithmetic or bitflip operators generates promoted type 278 : SK(BOOL); // comparison operators generates bool 279 280#define CASE_BINARY_COMMON(__type__)\ 281 mValue = handleBinaryCommon(static_cast<__type__>(lval->mValue), op, static_cast<__type__>(rval->mValue)); return; 282 283 SWITCH_KIND(promoted, CASE_BINARY_COMMON, SHOULD_NOT_REACH(); return;) 284 } 285 286 // CASE 2: << >> 287 if(OP_IS_BIN_SHIFT) { 288 mValueKind = integralPromotion(lval->mValueKind); 289 // instead of promoting rval, simply casting it to int64 should also be good. 290 int64_t numBits = rval->cast<int64_t>(); 291 if(numBits < 0) { 292 // shifting with negative number of bits is undefined in C. In HIDL it 293 // is defined as shifting into the other direction. 294 op = OPEQ("<<") ? ">>" : "<<"; 295 numBits = -numBits; 296 } 297 298#define CASE_SHIFT(__type__)\ 299 mValue = handleShift(static_cast<__type__>(lval->mValue), op, numBits); return; 300 301 SWITCH_KIND(mValueKind, CASE_SHIFT, SHOULD_NOT_REACH(); return;) 302 } 303 304 // CASE 3: && || 305 if(OP_IS_BIN_LOGICAL) { 306 mValueKind = SK(BOOL); 307 // easy; everything is bool. 308 mValue = handleLogical(lval->mValue, op, rval->mValue); 309 return; 310 } 311 312 SHOULD_NOT_REACH(); 313} 314 315/* Ternary ?: operation. */ 316ConstantExpression::ConstantExpression(const ConstantExpression *cond, 317 const ConstantExpression *trueVal, 318 const ConstantExpression *falseVal) 319 : mExpr(std::string("(") + cond->mExpr + "?" + trueVal->mExpr 320 + ":" + falseVal->mExpr + ")"), 321 mType(kConstExprTernary) { 322 323 // note: for ?:, unlike arithmetic ops, integral promotion is not necessary. 324 mValueKind = usualArithmeticConversion(trueVal->mValueKind, 325 falseVal->mValueKind); 326 327#define CASE_TERNARY(__type__)\ 328 mValue = cond->mValue ? (static_cast<__type__>(trueVal->mValue)) : (static_cast<__type__>(falseVal->mValue)); return; 329 330 SWITCH_KIND(mValueKind, CASE_TERNARY, SHOULD_NOT_REACH(); return;) 331} 332 333ConstantExpression ConstantExpression::addOne() const { 334 ConstantExpression myOne = ConstantExpression::One(mValueKind); 335 return ConstantExpression(this, "+", &myOne).toLiteral(); 336} 337 338ConstantExpression &ConstantExpression::toLiteral() { 339 mExpr = value(); 340 mType = kConstExprLiteral; 341 return *this; 342} 343 344const std::string &ConstantExpression::description() const { 345 return mExpr; 346} 347 348bool ConstantExpression::descriptionIsTrivial() const { 349 return mTrivialDescription; 350} 351 352std::string ConstantExpression::value() const { 353 return rawValue(mValueKind); 354} 355 356std::string ConstantExpression::value(ScalarType::Kind castKind) const { 357 return rawValue(castKind); 358} 359 360std::string ConstantExpression::cppValue() const { 361 return cppValue(mValueKind); 362} 363 364std::string ConstantExpression::cppValue(ScalarType::Kind castKind) const { 365 std::string literal(rawValue(castKind)); 366 // this is a hack to translate 367 // enum x : int64_t { y = 1l << 63 }; 368 // into 369 // enum class x : int64_t { y = (int64_t)-9223372036854775808ull }; 370 // by adding the explicit cast. 371 // Because 9223372036854775808 is uint64_t, and 372 // -(uint64_t)9223372036854775808 == 9223372036854775808 could not 373 // be narrowed to int64_t. 374 if(castKind == SK(INT64) && (int64_t)mValue == INT64_MIN) { 375 return strdup(("static_cast<" 376 + ScalarType(SK(INT64)).getCppStackType() // "int64_t" 377 + ">(" + literal + "ull)").c_str()); 378 } 379 380 // add suffix if necessary. 381 if(castKind == SK(UINT32) || castKind == SK(UINT64)) literal += "u"; 382 if(castKind == SK(UINT64) || castKind == SK(INT64)) literal += "ll"; 383 return literal; 384} 385 386std::string ConstantExpression::javaValue() const { 387 return javaValue(mValueKind); 388} 389 390std::string ConstantExpression::javaValue(ScalarType::Kind castKind) const { 391 switch(castKind) { 392 case SK(UINT64): return rawValue(SK(INT64)) + "L"; 393 case SK(INT64): return rawValue(SK(INT64)) + "L"; 394 case SK(UINT32): return rawValue(SK(INT32)); 395 case SK(UINT16): return rawValue(SK(INT16)); 396 case SK(UINT8) : return rawValue(SK(INT8)); 397 case SK(BOOL) : 398 return this->cast<bool>() ? strdup("true") : strdup("false"); 399 default: break; 400 } 401 return rawValue(castKind); 402} 403 404std::string ConstantExpression::rawValue(ScalarType::Kind castKind) const { 405 406#define CASE_STR(__type__) return std::to_string(this->cast<__type__>()); 407 408 SWITCH_KIND(castKind, CASE_STR, SHOULD_NOT_REACH(); return 0; ); 409} 410 411template<typename T> 412T ConstantExpression::cast() const { 413 414#define CASE_CAST_T(__type__) return static_cast<T>(static_cast<__type__>(mValue)); 415 416 SWITCH_KIND(mValueKind, CASE_CAST_T, SHOULD_NOT_REACH(); return 0; ); 417} 418 419size_t ConstantExpression::castSizeT() const { 420 return this->cast<size_t>(); 421} 422 423/* 424 425Evaluating expressions in HIDL language 426 427The following rules are mostly like that in: 428http://en.cppreference.com/w/cpp/language/operator_arithmetic 429http://en.cppreference.com/w/cpp/language/operator_logical 430http://en.cppreference.com/w/cpp/language/operator_comparison 431http://en.cppreference.com/w/cpp/language/operator_other 432 433The type of literal is the first type which the value 434can fit from the list of types depending on the suffix and bases. 435 436suffix decimal bases hexadecimal bases 437no suffix int32_t int32_t 438 int64_t uint32_t 439 int64_t 440 uint64_t 441 442u/U uint32_t (same as left) 443 uint64_t 444 445l/L int64_t int64_t 446 447ul/UL/uL/Ul uint64_t uint64_t 448 449 450Note: There are no negative integer literals. 451 -1 is the unary minus applied to 1. 452 453Unary arithmetic and bitwise operators (~ + -): 454 don't change the type of the argument. 455 (so -1u = -(1u) has type uint32_t) 456 457Binary arithmetic and bitwise operators (except shifts) (+ - * / % & | ^): 4581. Integral promotion is first applied on both sides. 4592. If both operands have the same type, no promotion is necessary. 4603. Usual arithmetic conversions. 461 462Integral promotion: if an operand is of a type with less than 32 bits, 463(including bool), it is promoted to int32_t. 464 465Usual arithmetic conversions: 4661. If operands are both signed or both unsigned, lesser conversion rank is 467 converted to greater conversion rank. 4682. Otherwise, if unsigned's rank >= signed's rank, -> unsigned's type 4693. Otherwise, if signed's type can hold all values in unsigned's type, 470 -> signed's type 4714. Otherwise, both converted to the unsigned counterpart of the signed operand's 472 type. 473rank: bool < int8_t < int16_t < int32_t < int64_t 474 475 476Shift operators (<< >>): 4771. Integral promotion is applied on both sides. 4782. For unsigned a, a << b discards bits that shifts out. 479 For signed non-negative a, a << b is legal if no bits shifts out, otherwise error. 480 For signed negative a, a << b gives error. 4813. For unsigned and signed non-negative a, a >> b discards bits that shifts out. 482 For signed negative a, a >> b discards bits that shifts out, and the signed 483 bit gets extended. ("arithmetic right shift") 4844. Shifting with negative number of bits is undefined. (Currently, the 485 parser will shift into the other direction. This behavior may change.) 4865. Shifting with number of bits exceeding the width of the type is undefined. 487 (Currently, 1 << 32 == 1. This behavior may change.) 488 489Logical operators (!, &&, ||): 4901. Convert first operand to bool. (true if non-zero, false otherwise) 4912. If short-circuited, return the result as type bool, value 1 or 0. 4923. Otherwise, convert second operand to bool, evaluate the result, and return 493 the result in the same fashion. 494 495Arithmetic comparison operators (< > <= >= == !=): 4961. Promote operands in the same way as binary arithmetic and bitwise operators. 497 (Integral promotion + Usual arithmetic conversions) 4982. Return type bool, value 0 or 1 the same way as logical operators. 499 500Ternary conditional operator (?:): 5011. Evaluate the conditional and evaluate the operands. 5022. Return type of expression is the type under usual arithmetic conversions on 503 the second and third operand. (No integral promotions necessary.) 504 505*/ 506 507} // namespace android 508 509