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 56 namespace android { 57 58 static 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. */ 63 ScalarType::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. */ 68 ScalarType::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 98 template <class T> 99 T 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 109 template <class T> 110 T 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 132 template <class T> 133 T 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 143 bool 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 152 ConstantExpression::ConstantExpression() { 153 } 154 155 // static 156 ConstantExpression ConstantExpression::Zero(ScalarType::Kind kind) { 157 ConstantExpression ce = ValueOf(kind, 0); 158 ce.mExpr = "0"; 159 return ce; 160 } 161 162 // static 163 ConstantExpression ConstantExpression::One(ScalarType::Kind kind) { 164 ConstantExpression ce = ValueOf(kind, 1); 165 ce.mExpr = "1"; 166 return ce; 167 } 168 169 // static 170 ConstantExpression ConstantExpression::ValueOf(ScalarType::Kind kind, uint64_t value) { 171 ConstantExpression ce; 172 CHECK(isSupported(kind)); 173 174 ce.mExpr = ""; 175 ce.mType = kConstExprLiteral; 176 ce.mValueKind = kind; 177 ce.mValue = value; 178 ce.mTrivialDescription = true; 179 return ce; 180 } 181 ConstantExpression::ConstantExpression(const ConstantExpression& other) { 182 *this = other; 183 } 184 185 /* Copy constructor, with the expr overriden and treated non-trivial */ 186 ConstantExpression::ConstantExpression(const ConstantExpression& other, std::string expr) { 187 *this = other; 188 mExpr = expr; 189 mTrivialDescription = false; 190 } 191 192 ConstantExpression& ConstantExpression::operator=(const ConstantExpression& other) { 193 mType = other.mType; 194 mValueKind = other.mValueKind; 195 mValue = other.mValue; 196 mExpr = other.mExpr; 197 mTrivialDescription = other.mTrivialDescription; 198 return *this; 199 } 200 201 /* Literals. */ 202 ConstantExpression::ConstantExpression(const char *value) 203 : mExpr(value), mType(kConstExprLiteral), mTrivialDescription(true) { 204 const char* head = value, *tail = head + strlen(value) - 1; 205 bool isLong = false, isUnsigned = false; 206 bool isHex = (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')); 207 while(tail >= head && (*tail == 'u' || *tail == 'U' || *tail == 'l' || *tail == 'L')) { 208 isUnsigned |= (*tail == 'u' || *tail == 'U'); 209 isLong |= (*tail == 'l' || *tail == 'L'); 210 tail--; 211 } 212 char *newVal = strndup(value, tail - head + 1); 213 bool parseOK = base::ParseUint(newVal, &mValue); 214 free(newVal); 215 CHECK(parseOK) << "Could not parse as integer: " << value; 216 217 // guess literal type. 218 if(isLong) { 219 if(isUnsigned) // ul 220 mValueKind = SK(UINT64); 221 else // l 222 mValueKind = SK(INT64); 223 } else { // no l suffix 224 if(isUnsigned) { // u 225 if(mValue <= UINT32_MAX) 226 mValueKind = SK(UINT32); 227 else 228 mValueKind = SK(UINT64); 229 } else { // no suffix 230 if(isHex) { 231 if(mValue <= INT32_MAX) // mValue always >= 0 232 mValueKind = SK(INT32); 233 else if(mValue <= UINT32_MAX) 234 mValueKind = SK(UINT32); 235 else if(mValue <= INT64_MAX) // mValue always >= 0 236 mValueKind = SK(INT64); 237 else if(mValue <= UINT64_MAX) 238 mValueKind = SK(UINT64); 239 } else { 240 if(mValue <= INT32_MAX) // mValue always >= 0 241 mValueKind = SK(INT32); 242 else 243 mValueKind = SK(INT64); 244 } 245 } 246 } 247 } 248 249 /* Unary operations. */ 250 ConstantExpression::ConstantExpression(const char *op, 251 const ConstantExpression *value) 252 : mExpr(std::string("(") + op + value->mExpr + ")"), 253 mType(kConstExprUnary), 254 mValueKind(value->mValueKind) { 255 256 #define CASE_UNARY(__type__)\ 257 mValue = handleUnary(op, static_cast<__type__>(value->mValue)); return; 258 259 SWITCH_KIND(mValueKind, CASE_UNARY, SHOULD_NOT_REACH(); return;) 260 } 261 262 /* Binary operations. */ 263 ConstantExpression::ConstantExpression(const ConstantExpression *lval, 264 const char *op, 265 const ConstantExpression* rval) 266 : mExpr(std::string("(") + lval->mExpr + " " + op + " " + rval->mExpr + ")"), 267 mType(kConstExprBinary) 268 { 269 270 bool isArithmeticOrBitflip = OP_IS_BIN_ARITHMETIC || OP_IS_BIN_BITFLIP; 271 272 // CASE 1: + - * / % | ^ & < > <= >= == != 273 if(isArithmeticOrBitflip || OP_IS_BIN_COMP) { 274 // promoted kind for both operands. 275 ScalarType::Kind promoted = usualArithmeticConversion( 276 integralPromotion(lval->mValueKind), 277 integralPromotion(rval->mValueKind)); 278 // result kind. 279 mValueKind = isArithmeticOrBitflip 280 ? promoted // arithmetic or bitflip operators generates promoted type 281 : SK(BOOL); // comparison operators generates bool 282 283 #define CASE_BINARY_COMMON(__type__)\ 284 mValue = handleBinaryCommon(static_cast<__type__>(lval->mValue), op, static_cast<__type__>(rval->mValue)); return; 285 286 SWITCH_KIND(promoted, CASE_BINARY_COMMON, SHOULD_NOT_REACH(); return;) 287 } 288 289 // CASE 2: << >> 290 if(OP_IS_BIN_SHIFT) { 291 mValueKind = integralPromotion(lval->mValueKind); 292 // instead of promoting rval, simply casting it to int64 should also be good. 293 int64_t numBits = rval->cast<int64_t>(); 294 if(numBits < 0) { 295 // shifting with negative number of bits is undefined in C. In HIDL it 296 // is defined as shifting into the other direction. 297 op = OPEQ("<<") ? ">>" : "<<"; 298 numBits = -numBits; 299 } 300 301 #define CASE_SHIFT(__type__)\ 302 mValue = handleShift(static_cast<__type__>(lval->mValue), op, numBits); return; 303 304 SWITCH_KIND(mValueKind, CASE_SHIFT, SHOULD_NOT_REACH(); return;) 305 } 306 307 // CASE 3: && || 308 if(OP_IS_BIN_LOGICAL) { 309 mValueKind = SK(BOOL); 310 // easy; everything is bool. 311 mValue = handleLogical(lval->mValue, op, rval->mValue); 312 return; 313 } 314 315 SHOULD_NOT_REACH(); 316 } 317 318 /* Ternary ?: operation. */ 319 ConstantExpression::ConstantExpression(const ConstantExpression *cond, 320 const ConstantExpression *trueVal, 321 const ConstantExpression *falseVal) 322 : mExpr(std::string("(") + cond->mExpr + "?" + trueVal->mExpr 323 + ":" + falseVal->mExpr + ")"), 324 mType(kConstExprTernary) { 325 326 // note: for ?:, unlike arithmetic ops, integral promotion is not necessary. 327 mValueKind = usualArithmeticConversion(trueVal->mValueKind, 328 falseVal->mValueKind); 329 330 #define CASE_TERNARY(__type__)\ 331 mValue = cond->mValue ? (static_cast<__type__>(trueVal->mValue)) : (static_cast<__type__>(falseVal->mValue)); return; 332 333 SWITCH_KIND(mValueKind, CASE_TERNARY, SHOULD_NOT_REACH(); return;) 334 } 335 336 ConstantExpression ConstantExpression::addOne() const { 337 ConstantExpression myOne = ConstantExpression::One(mValueKind); 338 return ConstantExpression(this, "+", &myOne).toLiteral(); 339 } 340 341 ConstantExpression &ConstantExpression::toLiteral() { 342 mExpr = value(); 343 mType = kConstExprLiteral; 344 return *this; 345 } 346 347 const std::string &ConstantExpression::description() const { 348 return mExpr; 349 } 350 351 bool ConstantExpression::descriptionIsTrivial() const { 352 return mTrivialDescription; 353 } 354 355 std::string ConstantExpression::value() const { 356 return rawValue(mValueKind); 357 } 358 359 std::string ConstantExpression::value(ScalarType::Kind castKind) const { 360 return rawValue(castKind); 361 } 362 363 std::string ConstantExpression::cppValue() const { 364 return cppValue(mValueKind); 365 } 366 367 std::string ConstantExpression::cppValue(ScalarType::Kind castKind) const { 368 std::string literal(rawValue(castKind)); 369 // this is a hack to translate 370 // enum x : int64_t { y = 1l << 63 }; 371 // into 372 // enum class x : int64_t { y = (int64_t)-9223372036854775808ull }; 373 // by adding the explicit cast. 374 // Because 9223372036854775808 is uint64_t, and 375 // -(uint64_t)9223372036854775808 == 9223372036854775808 could not 376 // be narrowed to int64_t. 377 if(castKind == SK(INT64) && (int64_t)mValue == INT64_MIN) { 378 return strdup(("static_cast<" 379 + ScalarType(SK(INT64)).getCppStackType() // "int64_t" 380 + ">(" + literal + "ull)").c_str()); 381 } 382 383 // add suffix if necessary. 384 if(castKind == SK(UINT32) || castKind == SK(UINT64)) literal += "u"; 385 if(castKind == SK(UINT64) || castKind == SK(INT64)) literal += "ll"; 386 return literal; 387 } 388 389 std::string ConstantExpression::javaValue() const { 390 return javaValue(mValueKind); 391 } 392 393 std::string ConstantExpression::javaValue(ScalarType::Kind castKind) const { 394 switch(castKind) { 395 case SK(UINT64): return rawValue(SK(INT64)) + "L"; 396 case SK(INT64): return rawValue(SK(INT64)) + "L"; 397 case SK(UINT32): return rawValue(SK(INT32)); 398 case SK(UINT16): return rawValue(SK(INT16)); 399 case SK(UINT8) : return rawValue(SK(INT8)); 400 case SK(BOOL) : 401 return this->cast<bool>() ? strdup("true") : strdup("false"); 402 default: break; 403 } 404 return rawValue(castKind); 405 } 406 407 std::string ConstantExpression::rawValue(ScalarType::Kind castKind) const { 408 409 #define CASE_STR(__type__) return std::to_string(this->cast<__type__>()); 410 411 SWITCH_KIND(castKind, CASE_STR, SHOULD_NOT_REACH(); return 0; ); 412 } 413 414 template<typename T> 415 T ConstantExpression::cast() const { 416 417 #define CASE_CAST_T(__type__) return static_cast<T>(static_cast<__type__>(mValue)); 418 419 SWITCH_KIND(mValueKind, CASE_CAST_T, SHOULD_NOT_REACH(); return 0; ); 420 } 421 422 size_t ConstantExpression::castSizeT() const { 423 return this->cast<size_t>(); 424 } 425 426 /* 427 428 Evaluating expressions in HIDL language 429 430 The following rules are mostly like that in: 431 http://en.cppreference.com/w/cpp/language/operator_arithmetic 432 http://en.cppreference.com/w/cpp/language/operator_logical 433 http://en.cppreference.com/w/cpp/language/operator_comparison 434 http://en.cppreference.com/w/cpp/language/operator_other 435 436 The type of literal is the first type which the value 437 can fit from the list of types depending on the suffix and bases. 438 439 suffix decimal bases hexadecimal bases 440 no suffix int32_t int32_t 441 int64_t uint32_t 442 int64_t 443 uint64_t 444 445 u/U uint32_t (same as left) 446 uint64_t 447 448 l/L int64_t int64_t 449 450 ul/UL/uL/Ul uint64_t uint64_t 451 452 453 Note: There are no negative integer literals. 454 -1 is the unary minus applied to 1. 455 456 Unary arithmetic and bitwise operators (~ + -): 457 don't change the type of the argument. 458 (so -1u = -(1u) has type uint32_t) 459 460 Binary arithmetic and bitwise operators (except shifts) (+ - * / % & | ^): 461 1. Integral promotion is first applied on both sides. 462 2. If both operands have the same type, no promotion is necessary. 463 3. Usual arithmetic conversions. 464 465 Integral promotion: if an operand is of a type with less than 32 bits, 466 (including bool), it is promoted to int32_t. 467 468 Usual arithmetic conversions: 469 1. If operands are both signed or both unsigned, lesser conversion rank is 470 converted to greater conversion rank. 471 2. Otherwise, if unsigned's rank >= signed's rank, -> unsigned's type 472 3. Otherwise, if signed's type can hold all values in unsigned's type, 473 -> signed's type 474 4. Otherwise, both converted to the unsigned counterpart of the signed operand's 475 type. 476 rank: bool < int8_t < int16_t < int32_t < int64_t 477 478 479 Shift operators (<< >>): 480 1. Integral promotion is applied on both sides. 481 2. For unsigned a, a << b discards bits that shifts out. 482 For signed non-negative a, a << b is legal if no bits shifts out, otherwise error. 483 For signed negative a, a << b gives error. 484 3. For unsigned and signed non-negative a, a >> b discards bits that shifts out. 485 For signed negative a, a >> b discards bits that shifts out, and the signed 486 bit gets extended. ("arithmetic right shift") 487 4. Shifting with negative number of bits is undefined. (Currently, the 488 parser will shift into the other direction. This behavior may change.) 489 5. Shifting with number of bits exceeding the width of the type is undefined. 490 (Currently, 1 << 32 == 1. This behavior may change.) 491 492 Logical operators (!, &&, ||): 493 1. Convert first operand to bool. (true if non-zero, false otherwise) 494 2. If short-circuited, return the result as type bool, value 1 or 0. 495 3. Otherwise, convert second operand to bool, evaluate the result, and return 496 the result in the same fashion. 497 498 Arithmetic comparison operators (< > <= >= == !=): 499 1. Promote operands in the same way as binary arithmetic and bitwise operators. 500 (Integral promotion + Usual arithmetic conversions) 501 2. Return type bool, value 0 or 1 the same way as logical operators. 502 503 Ternary conditional operator (?:): 504 1. Evaluate the conditional and evaluate the operands. 505 2. Return type of expression is the type under usual arithmetic conversions on 506 the second and third operand. (No integral promotions necessary.) 507 508 */ 509 510 } // namespace android 511 512