Changeset eef8dfb for src/Parser/ExpressionNode.cc
- Timestamp:
- Jan 7, 2021, 2:55:57 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 58fe85a
- Parents:
- bdfc032 (diff), 44e37ef (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
rbdfc032 reef8dfb 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Dec 18 21:14:58 201913 // Update Count : 98112 // Last Modified On : Thu Aug 20 14:01:46 2020 13 // Update Count : 1076 14 14 // 15 15 … … 65 65 66 66 void lnthSuffix( string & str, int & type, int & ltype ) { 67 // 'u' can appear before or after length suffix 67 68 string::size_type posn = str.find_last_of( "lL" ); 68 69 69 70 if ( posn == string::npos ) return; // no suffix 70 if ( posn == str.length() - 1 ) { type = 3; return; } // no length => long 71 71 size_t end = str.length() - 1; 72 if ( posn == end ) { type = 3; return; } // no length after 'l' => long 73 72 74 string::size_type next = posn + 1; // advance to length 73 75 if ( str[next] == '3' ) { // 32 … … 84 86 } // if 85 87 } // if 86 // remove "lL" for these cases because it may not imply long 87 str.erase( posn ); // remove length 88 89 char fix = '\0'; 90 if ( str[end] == 'u' || str[end] == 'U' ) fix = str[end]; // ends with 'uU' ? 91 str.erase( posn ); // remove length suffix and possibly uU 92 if ( type == 5 ) { // L128 does not need uU 93 end = str.length() - 1; 94 if ( str[end] == 'u' || str[end] == 'U' ) str.erase( end ); // ends with 'uU' ? remove 95 } else if ( fix != '\0' ) str += fix; // put 'uU' back if removed 88 96 } // lnthSuffix 89 97 … … 108 116 } // valueToType 109 117 118 static void scanbin( string & str, unsigned long long int & v ) { 119 v = 0; 120 size_t last = str.length() - 1; // last subscript of constant 121 for ( unsigned int i = 2;; ) { // ignore prefix 122 if ( str[i] == '1' ) v |= 1; 123 i += 1; 124 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break; 125 v <<= 1; 126 } // for 127 } // scanbin 128 110 129 Expression * build_constantInteger( string & str ) { 111 130 static const BasicType::Kind kind[2][6] = { 112 131 // short (h) must be before char (hh) because shorter type has the longer suffix 113 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },114 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },132 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ BasicType::LongLongSignedInt, }, 133 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ BasicType::LongLongUnsignedInt, }, 115 134 }; 116 135 … … 120 139 }; // lnthsInt 121 140 122 unsigned long long int v; // converted integral value 123 size_t last = str.length() - 1; // last subscript of constant 124 Expression * ret; 125 //string fred( str ); 141 string str2( "0x0" ); 142 unsigned long long int v, v2 = 0; // converted integral value 143 Expression * ret, * ret2; 126 144 127 145 int type = -1; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 … … 139 157 } // if 140 158 159 string::size_type posn; 160 161 // 'u' can appear before or after length suffix 162 if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true; 163 164 if ( isdigit( str[str.length() - 1] ) ) { // no suffix ? 165 lnthSuffix( str, type, ltype ); // could have length suffix 166 } else { 167 // At least one digit in integer constant, so safe to backup while looking for suffix. 168 169 posn = str.find_last_of( "pP" ); // pointer value 170 if ( posn != string::npos ) { ltype = 5; str.erase( posn, 1 ); goto FINI; } 171 172 posn = str.find_last_of( "zZ" ); // size_t 173 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; } 174 175 posn = str.rfind( "hh" ); // char 176 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 177 178 posn = str.rfind( "HH" ); // char 179 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; } 180 181 posn = str.find_last_of( "hH" ); // short 182 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; } 183 184 posn = str.find_last_of( "nN" ); // int (natural number) 185 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; } 186 187 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; } 188 189 lnthSuffix( str, type, ltype ); // must be after check for "ll" 190 FINI: ; 191 } // if 192 141 193 // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate 142 194 195 #if ! defined(__SIZEOF_INT128__) 196 if ( type == 5 ) SemanticError( yylloc, "int128 constant is not supported on this target " + str ); 197 #endif // ! __SIZEOF_INT128__ 198 143 199 if ( str[0] == '0' ) { // radix character ? 144 200 dec = false; 145 201 if ( checkX( str[1] ) ) { // hex constant ? 146 sscanf( (char *)str.c_str(), "%llx", &v ); 202 if ( type < 5 ) { // not L128 ? 203 sscanf( (char *)str.c_str(), "%llx", &v ); 204 #if defined(__SIZEOF_INT128__) 205 } else { // hex int128 constant 206 unsigned int len = str.length(); 207 if ( len > (2 + 16 + 16) ) SemanticError( yylloc, "128-bit hexadecimal constant to large " + str ); 208 if ( len <= (2 + 16) ) goto FHEX1; // hex digits < 2^64 209 str2 = "0x" + str.substr( len - 16 ); 210 sscanf( (char *)str2.c_str(), "%llx", &v2 ); 211 str = str.substr( 0, len - 16 ); 212 FHEX1: ; 213 sscanf( (char *)str.c_str(), "%llx", &v ); 214 #endif // __SIZEOF_INT128__ 215 } // if 147 216 //printf( "%llx %llu\n", v, v ); 148 217 } else if ( checkB( str[1] ) ) { // binary constant ? 149 v = 0; // compute value 150 for ( unsigned int i = 2;; ) { // ignore prefix 151 if ( str[i] == '1' ) v |= 1; 152 i += 1; 153 if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break; 154 v <<= 1; 155 } // for 218 #if defined(__SIZEOF_INT128__) 219 unsigned int len = str.length(); 220 if ( type == 5 && len > 2 + 64 ) { 221 if ( len > 2 + 64 + 64 ) SemanticError( yylloc, "128-bit binary constant to large " + str ); 222 str2 = "0b" + str.substr( len - 64 ); 223 str = str.substr( 0, len - 64 ); 224 scanbin( str2, v2 ); 225 } // if 226 #endif // __SIZEOF_INT128__ 227 scanbin( str, v ); 156 228 //printf( "%#llx %llu\n", v, v ); 157 229 } else { // octal constant 158 sscanf( (char *)str.c_str(), "%llo", &v ); 230 if ( type < 5 ) { // not L128 ? 231 sscanf( (char *)str.c_str(), "%llo", &v ); 232 #if defined(__SIZEOF_INT128__) 233 } else { // octal int128 constant 234 unsigned int len = str.length(); 235 if ( len > 1 + 43 || (len == 1 + 43 && str[0] > '3') ) SemanticError( yylloc, "128-bit octal constant to large " + str ); 236 char buf[32]; 237 if ( len <= 1 + 21 ) { // value < 21 octal digitis 238 sscanf( (char *)str.c_str(), "%llo", &v ); 239 } else { 240 sscanf( &str[len - 21], "%llo", &v ); 241 __int128 val = v; // accumulate bits 242 str[len - 21] ='\0'; // shorten string 243 sscanf( &str[len == 43 ? 1 : 0], "%llo", &v ); 244 val |= (__int128)v << 63; // store bits 245 if ( len == 1 + 43 ) { // most significant 2 bits ? 246 str[2] = '\0'; // shorten string 247 sscanf( &str[1], "%llo", &v ); // process most significant 2 bits 248 val |= (__int128)v << 126; // store bits 249 } // if 250 v = val >> 64; v2 = (uint64_t)val; // replace octal constant with 2 hex constants 251 sprintf( buf, "%#llx", v2 ); 252 str2 = buf; 253 } // if 254 sprintf( buf, "%#llx", v ); 255 str = buf; 256 #endif // __SIZEOF_INT128__ 257 } // if 159 258 //printf( "%#llo %llu\n", v, v ); 160 259 } // if 161 260 } else { // decimal constant ? 162 sscanf( (char *)str.c_str(), "%llu", &v ); 261 if ( type < 5 ) { // not L128 ? 262 sscanf( (char *)str.c_str(), "%llu", &v ); 263 #if defined(__SIZEOF_INT128__) 264 } else { // decimal int128 constant 265 #define P10_UINT64 10'000'000'000'000'000'000ULL // 19 zeroes 266 unsigned int len = str.length(); 267 if ( str.length() == 39 && str > (Unsigned ? "340282366920938463463374607431768211455" : "170141183460469231731687303715884105727") ) 268 SemanticError( yylloc, "128-bit decimal constant to large " + str ); 269 char buf[32]; 270 if ( len <= 19 ) { // value < 19 decimal digitis 271 sscanf( (char *)str.c_str(), "%llu", &v ); 272 } else { 273 sscanf( &str[len - 19], "%llu", &v ); 274 __int128 val = v; // accumulate bits 275 str[len - 19] ='\0'; // shorten string 276 sscanf( &str[len == 39 ? 1 : 0], "%llu", &v ); 277 val += (__int128)v * (__int128)P10_UINT64; // store bits 278 if ( len == 39 ) { // most significant 2 bits ? 279 str[1] = '\0'; // shorten string 280 sscanf( &str[0], "%llu", &v ); // process most significant 2 bits 281 val += (__int128)v * (__int128)P10_UINT64 * (__int128)P10_UINT64; // store bits 282 } // if 283 v = val >> 64; v2 = (uint64_t)val; // replace decimal constant with 2 hex constants 284 sprintf( buf, "%#llx", v2 ); 285 str2 = buf; 286 } // if 287 sprintf( buf, "%#llx", v ); 288 str = buf; 289 #endif // __SIZEOF_INT128__ 290 } // if 163 291 //printf( "%llu\n", v ); 164 292 } // if 165 293 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 294 if ( type == -1 ) { // no suffix => determine type from value size 295 valueToType( v, dec, type, Unsigned ); 296 } // if 297 /* printf( "%s %llo %s %llo\n", str.c_str(), v, str2.c_str(), v2 ); */ 205 298 206 299 //if ( !( 0 <= type && type <= 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); } … … 214 307 } else if ( ltype != -1 ) { // explicit length ? 215 308 if ( ltype == 6 ) { // int128, (int128)constant 216 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 309 // ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false ); 310 ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) ); 311 ret = build_compoundLiteral( DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ), 312 new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) ); 217 313 } else { // explicit length, (length_type)constant 218 314 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false ); … … 342 438 if ( str[1] == '8' ) goto Default; // utf-8 characters => array of char 343 439 // lookup type of associated typedef 344 strtype = new TypeInstType( Type::Qualifiers( Type::Const), "char16_t", false );440 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false ); 345 441 break; 346 442 case 'U': 347 strtype = new TypeInstType( Type::Qualifiers( Type::Const), "char32_t", false );443 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false ); 348 444 break; 349 445 case 'L': 350 strtype = new TypeInstType( Type::Qualifiers( Type::Const), "wchar_t", false );446 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false ); 351 447 break; 352 448 Default: // char default string type 353 449 default: 354 strtype = new BasicType( Type::Qualifiers( Type::Const), BasicType::Char );450 strtype = new BasicType( Type::Qualifiers( ), BasicType::Char ); 355 451 } // switch 356 452 ArrayType * at = new ArrayType( noQualifiers, strtype,
Note:
See TracChangeset
for help on using the changeset viewer.