Changeset 53bb8f1 for src/Parser/ExpressionNode.cc
- Timestamp:
- Mar 12, 2019, 3:00:54 PM (5 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 30e32b2, a2545593
- Parents:
- 9d9a451 (diff), 91d6584 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/ExpressionNode.cc
r9d9a451 r53bb8f1 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jun 4 21:24:45 201813 // Update Count : 80212 // Last Modified On : Sun Mar 10 16:10:32 2019 13 // Update Count : 976 14 14 // 15 15 … … 51 51 extern const Type::Qualifiers noQualifiers; // no qualifiers on constants 52 52 53 static inline bool checkH( char c ) { return c == 'h' || c == 'H'; } 54 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 55 static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; } 56 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 53 // static inline bool checkH( char c ) { return c == 'h' || c == 'H'; } 54 // static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; } 55 // static inline bool checkU( char c ) { return c == 'u' || c == 'U'; } 57 56 static inline bool checkF( char c ) { return c == 'f' || c == 'F'; } 58 57 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; } 58 static inline bool checkF80( char c ) { return c == 'w' || c == 'W'; } 59 static inline bool checkF128( char c ) { return c == 'q' || c == 'Q'; } 60 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; } 59 61 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; } 60 62 static inline bool checkB( char c ) { return c == 'b' || c == 'B'; } 61 63 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; } 62 63 static const char * lnthsInt[2][6] = { 64 { "int8_t", "int16_t", "int32_t", "int64_t", "size_t", }, 65 { "uint8_t", "uint16_t", "uint32_t", "uint64_t", "size_t", } 66 }; // lnthsInt 67 68 static inline void checkLNInt( string & str, int & lnth, int & size ) { 69 string::size_type posn = str.find_first_of( "lL" ), start = posn; 70 if ( posn == string::npos ) return; 71 size = 4; // assume largest size 72 posn += 1; // advance to size 73 if ( str[posn] == '8' ) { // 8 74 lnth = 0; 75 } else if ( str[posn] == '1' ) { 76 posn += 1; 77 if ( str[posn] == '6' ) { // 16 78 lnth = 1; 64 static inline bool checkN( char c ) { return c == 'n' || c == 'N'; } 65 66 void lnthSuffix( string & str, int & type, int & ltype ) { 67 string::size_type posn = str.find_last_of( "lL" ); 68 69 if ( posn == string::npos ) return; // no suffix 70 if ( posn == str.length() - 1 ) { type = 3; return; } // no length => long 71 72 string::size_type next = posn + 1; // advance to length 73 if ( str[next] == '3' ) { // 32 74 type = ltype = 2; 75 } else if ( str[next] == '6' ) { // 64 76 type = ltype = 3; 77 } else if ( str[next] == '8' ) { // 8 78 type = ltype = 1; 79 } else if ( str[next] == '1' ) { 80 if ( str[next + 1] == '6' ) { // 16 81 type = ltype = 0; 79 82 } else { // 128 80 posn += 1; 81 lnth = 5; 82 } // if 83 } else { 84 if ( str[posn] == '3' ) { // 32 85 lnth = 2; 86 } else if ( str[posn] == '6' ) { // 64 87 lnth = 3; 88 } else { 89 assertf( false, "internal error, bad integral length %s", str.c_str() ); 90 } // if 91 posn += 1; 92 } // if 93 str.erase( start, posn - start + 1 ); // remove length suffix 94 } // checkLNInt 83 type = 5; ltype = 6; 84 } // if 85 } // if 86 // remove "lL" for these cases because it may not imply long 87 str.erase( posn ); // remove length 88 } // lnthSuffix 89 90 void valueToType( unsigned long long int & v, bool dec, int & type, bool & Unsigned ) { 91 // use value to determine type 92 if ( v <= INT_MAX ) { // signed int 93 type = 2; 94 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 95 type = 2; 96 Unsigned = true; // unsigned 97 } else if ( v <= LONG_MAX ) { // signed long int 98 type = 3; 99 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 100 type = 3; 101 Unsigned = true; // unsigned long int 102 } else if ( v <= LLONG_MAX ) { // signed long long int 103 type = 4; 104 } else { // unsigned long long int 105 type = 4; 106 Unsigned = true; // unsigned long long int 107 } // if 108 } // valueToType 95 109 96 110 Expression * build_constantInteger( string & str ) { 97 static const BasicType::Kind kind[2][ 6] = {98 // short (h) must be before char (hh) 111 static const BasicType::Kind kind[2][7] = { 112 // short (h) must be before char (hh) because shorter type has the longer suffix 99 113 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, }, 100 114 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, }, 101 115 }; 102 116 103 bool dec = true, Unsigned = false; // decimal, unsigned constant 104 int size; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 105 int lnth = -1; // literal length 117 static const char * lnthsInt[2][6] = { 118 { "int16_t", "int8_t", "int32_t", "int64_t", "size_t", "uintptr_t", }, 119 { "uint16_t", "uint8_t", "uint32_t", "uint64_t", "size_t", "uintptr_t", }, 120 }; // lnthsInt 106 121 107 122 unsigned long long int v; // converted integral value 108 123 size_t last = str.length() - 1; // last subscript of constant 109 124 Expression * ret; 125 //string fred( str ); 126 127 int type = -1; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 128 int ltype = -1; // 0 => 16 bits, 1 => 8 bits, 2 => 32 bits, 3 => 64 bits, 4 => size_t, 5 => intptr, 6 => pointer 129 bool dec = true, Unsigned = false; // decimal, unsigned constant 110 130 111 131 // special constants … … 119 139 } // if 120 140 121 // Cannot be "0"141 // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate 122 142 123 143 if ( str[0] == '0' ) { // radix character ? … … 127 147 //printf( "%llx %llu\n", v, v ); 128 148 } else if ( checkB( str[1] ) ) { // binary constant ? 129 v = 0; 130 for ( unsigned int i = 2;; i += 1 ) { // compute value149 v = 0; // compute value 150 for ( unsigned int i = 2;; ) { // ignore prefix 131 151 if ( str[i] == '1' ) v |= 1; 132 if ( i == last ) break; 152 i += 1; 153 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break; 133 154 v <<= 1; 134 155 } // for 135 //printf( "% llx %llu\n", v, v );156 //printf( "%#llx %llu\n", v, v ); 136 157 } else { // octal constant 137 158 sscanf( (char *)str.c_str(), "%llo", &v ); 138 //printf( "% llo %llu\n", v, v );159 //printf( "%#llo %llu\n", v, v ); 139 160 } // if 140 161 } else { // decimal constant ? 141 162 sscanf( (char *)str.c_str(), "%llu", &v ); 142 //printf( "%llu %llu\n", v, v ); 143 } // if 144 145 if ( v <= INT_MAX ) { // signed int 146 size = 2; 147 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int 148 size = 2; 149 Unsigned = true; // unsigned 150 } else if ( v <= LONG_MAX ) { // signed long int 151 size = 3; 152 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int 153 size = 3; 154 Unsigned = true; // unsigned long int 155 } else if ( v <= LLONG_MAX ) { // signed long long int 156 size = 4; 157 } else { // unsigned long long int 158 size = 4; 159 Unsigned = true; // unsigned long long int 160 } // if 161 162 // At least one digit in integer constant, so safe to backup while looking for suffix. 163 164 if ( checkU( str[last] ) ) { // suffix 'u' ? 165 Unsigned = true; 166 if ( checkL( str[last - 1] ) ) { // suffix 'l' ? 167 size = 3; 168 if ( checkL( str[last - 2] ) ) { // suffix "ll" ? 169 size = 4; 163 //printf( "%llu\n", v ); 164 } // if 165 166 string::size_type posn; 167 168 if ( isdigit( str[last] ) ) { // no suffix ? 169 lnthSuffix( str, type, ltype ); // could have length suffix 170 if ( type == -1 ) { // no suffix 171 valueToType( v, dec, type, Unsigned ); 172 } // if 173 } else { 174 // At least one digit in integer constant, so safe to backup while looking for suffix. 175 176 posn = str.find_last_of( "pP" ); 177 if ( posn != string::npos ) { valueToType( v, dec, type, Unsigned ); ltype = 5; str.erase( posn, 1 ); goto FINI; } 178 179 posn = str.find_last_of( "zZ" ); 180 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; } 181 182 // 'u' can appear before or after length suffix 183 if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true; 184 185 posn = str.rfind( "hh" ); 186 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 187 188 posn = str.rfind( "HH" ); 189 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 190 191 posn = str.find_last_of( "hH" ); 192 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; } 193 194 posn = str.find_last_of( "nN" ); 195 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; } 196 197 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; } 198 199 lnthSuffix( str, type, ltype ); // must be after check for "ll" 200 if ( type == -1 ) { // only 'u' suffix ? 201 valueToType( v, dec, type, Unsigned ); 202 } // if 203 FINI: ; 204 } // if 205 206 //if ( !( 0 <= type && type <= 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); } 207 assert( 0 <= type && type <= 6 ); 208 209 // Constant type is correct for overload resolving. 210 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) ); 211 if ( Unsigned && type < 2 ) { // hh or h, less than int ? 212 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values. 213 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 214 } else if ( ltype != -1 ) { // explicit length ? 215 if ( ltype == 6 ) { // int128, (int128)constant 216 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 217 } else { // explicit length, (length_type)constant 218 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false ); 219 if ( ltype == 5 ) { // pointer, intptr( (uintptr_t)constant ) 220 ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) ); 170 221 } // if 171 } else if ( checkH( str[last - 1] ) ) { // suffix 'h' ? 172 size = 0; 173 if ( checkH( str[last - 2] ) ) { // suffix "hh" ? 174 size = 1; 175 } // if 176 str.erase( last - size - 1, size + 1 ); // remove 'h'/"hh" 177 } else { // suffix "ln" ? 178 checkLNInt( str, lnth, size ); 179 } // if 180 } else if ( checkL( str[ last ] ) ) { // suffix 'l' ? 181 size = 3; 182 if ( checkL( str[last - 1] ) ) { // suffix 'll' ? 183 size = 4; 184 if ( checkU( str[last - 2] ) ) { // suffix 'u' ? 185 Unsigned = true; 186 } // if 187 } else if ( checkU( str[last - 1] ) ) { // suffix 'u' ? 188 Unsigned = true; 189 } // if 190 } else if ( checkH( str[ last ] ) ) { // suffix 'h' ? 191 size = 0; 192 if ( checkH( str[last - 1] ) ) { // suffix "hh" ? 193 size = 1; 194 if ( checkU( str[last - 2] ) ) { // suffix 'u' ? 195 Unsigned = true; 196 } // if 197 } else if ( checkU( str[last - 1] ) ) { // suffix 'u' ? 198 Unsigned = true; 199 } // if 200 str.erase( last - size, size + 1 ); // remove 'h'/"hh" 201 } else if ( checkZ( str[last] ) ) { // suffix 'z' ? 202 lnth = 4; 203 str.erase( last, 1 ); // remove 'z' 204 } else { // suffix "ln" ? 205 checkLNInt( str, lnth, size ); 206 } // if 207 208 assert( 0 <= size && size < 6 ); 209 // Constant type is correct for overload resolving. 210 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) ); 211 if ( Unsigned && size < 2 ) { // hh or h, less than int ? 212 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values. 213 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false ); 214 } else if ( lnth != -1 ) { // explicit length ? 215 if ( lnth == 5 ) { // int128 ? 216 size = 5; 217 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false ); 218 } else { 219 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ), false ); 220 } // if 221 } // if 222 CLEANUP: 223 222 } // if 223 } // if 224 225 CLEANUP: ; 224 226 delete &str; // created by lex 225 227 return ret; … … 227 229 228 230 229 static inline void checkLNFloat( string & str, int & lnth, int & size ) { 230 string::size_type posn = str.find_first_of( "lL" ), start = posn; 231 static inline void checkFnxFloat( string & str, size_t last, bool & explnth, int & type ) { 232 string::size_type posn; 233 // floating-point constant has minimum of 2 characters, 1. or .1, so safe to look ahead 234 if ( str[1] == 'x' ) { // hex ? 235 posn = str.find_last_of( "pP" ); // back for exponent (must have) 236 posn = str.find_first_of( "fF", posn + 1 ); // forward for size (fF allowed in hex constant) 237 } else { 238 posn = str.find_last_of( "fF" ); // back for size (fF not allowed) 239 } // if 231 240 if ( posn == string::npos ) return; 232 size = 2; // assume largest size 233 lnth = 0; 241 explnth = true; 234 242 posn += 1; // advance to size 235 243 if ( str[posn] == '3' ) { // 32 236 size = 0; 244 if ( str[last] != 'x' ) type = 6; 245 else type = 7; 237 246 } else if ( str[posn] == '6' ) { // 64 238 size = 1; 239 } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128 240 size = 2; 241 if ( str[posn] == '1' ) posn += 1; 247 if ( str[last] != 'x' ) type = 8; 248 else type = 9; 249 } else if ( str[posn] == '8' ) { // 80 250 type = 3; 251 } else if ( str[posn] == '1' ) { // 16/128 252 if ( str[posn + 1] == '6' ) { // 16 253 type = 5; 254 } else { // 128 255 if ( str[last] != 'x' ) type = 10; 256 else type = 11; 257 } // if 242 258 } else { 243 259 assertf( false, "internal error, bad floating point length %s", str.c_str() ); 244 260 } // if 245 posn += 1; 246 str.erase( start, posn - start + 1 ); // remove length suffix 247 } // checkLNFloat 261 } // checkFnxFloat 248 262 249 263 250 264 Expression * build_constantFloat( string & str ) { 251 static const BasicType::Kind kind[2][ 3] = {252 { BasicType::Float, BasicType::Double, BasicType::LongDouble },253 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },265 static const BasicType::Kind kind[2][12] = { 266 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x }, 267 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, (BasicType::Kind)-1, (BasicType::Kind)-1, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex }, 254 268 }; 255 269 256 bool complx = false; // real, complex 257 int size = 1; // 0 => float, 1 => double, 2 => long double 258 int lnth = -1; // literal length 259 // floating-point constant has minimum of 2 characters: 1. or .1 270 // floating-point constant has minimum of 2 characters 1. or .1 260 271 size_t last = str.length() - 1; 261 272 double v; 273 int type; // 0 => float, 1 => double, 3 => long double, ... 274 bool complx = false; // real, complex 275 bool explnth = false; // explicit literal length 262 276 263 277 sscanf( str.c_str(), "%lg", &v ); … … 269 283 270 284 if ( checkF( str[last] ) ) { // float ? 271 size = 0;285 type = 0; 272 286 } else if ( checkD( str[last] ) ) { // double ? 273 size = 1;287 type = 1; 274 288 } else if ( checkL( str[last] ) ) { // long double ? 275 size = 2; 289 type = 2; 290 } else if ( checkF80( str[last] ) ) { // __float80 ? 291 type = 3; 292 } else if ( checkF128( str[last] ) ) { // __float128 ? 293 type = 4; 276 294 } else { 277 size = 1; // double (default) 278 checkLNFloat( str, lnth, size ); 279 } // if 295 type = 1; // double (default if no suffix) 296 checkFnxFloat( str, last, explnth, type ); 297 } // if 298 280 299 if ( ! complx && checkI( str[last - 1] ) ) { // imaginary ? 281 300 complx = true; 282 301 } // if 283 302 284 assert( 0 <= size && size < 3);285 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][ size] ), str, v ) );286 if ( lnth != -1) { // explicit length ?287 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][ size] ), false );303 assert( 0 <= type && type < 12 ); 304 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) ); 305 if ( explnth ) { // explicit length ? 306 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false ); 288 307 } // if 289 308
Note: See TracChangeset
for help on using the changeset viewer.