Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r013b028 r3c67255  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 20 14:01:46 2020
    13 // Update Count     : 1076
     12// Last Modified On : Wed Dec 18 21:14:58 2019
     13// Update Count     : 981
    1414//
    1515
     
    6565
    6666void lnthSuffix( string & str, int & type, int & ltype ) {
    67         // 'u' can appear before or after length suffix
    6867        string::size_type posn = str.find_last_of( "lL" );
    6968
    7069        if ( posn == string::npos ) return;                                     // no suffix
    71         size_t end = str.length() - 1;
    72         if ( posn == end ) { type = 3; return; }                        // no length after 'l' => long
    73        
     70        if ( posn == str.length() - 1 ) { type = 3; return; } // no length => long
     71
    7472        string::size_type next = posn + 1;                                      // advance to length
    7573        if ( str[next] == '3' ) {                                                       // 32
     
    8684                } // if
    8785        } // if
    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
     86        // remove "lL" for these cases because it may not imply long
     87        str.erase( posn );                                                                      // remove length
    9688} // lnthSuffix
    9789
     
    116108} // valueToType
    117109
    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 
    129110Expression * build_constantInteger( string & str ) {
    130111        static const BasicType::Kind kind[2][6] = {
    131112                // short (h) must be before char (hh) because shorter type has the longer suffix
    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, },
     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, },
    134115        };
    135116
     
    139120        }; // lnthsInt
    140121
    141         string str2( "0x0" );
    142         unsigned long long int v, v2 = 0;                                       // converted integral value
    143         Expression * ret, * ret2;
     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 );
    144126
    145127        int type = -1;                                                                          // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     
    157139        } // if
    158140
    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 
    193141        // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate
    194142
    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        
    199143        if ( str[0] == '0' ) {                                                          // radix character ?
    200144                dec = false;
    201145                if ( checkX( str[1] ) ) {                                               // hex constant ?
    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
     146                        sscanf( (char *)str.c_str(), "%llx", &v );
    216147                        //printf( "%llx %llu\n", v, v );
    217148                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    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 );
     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
    228156                        //printf( "%#llx %llu\n", v, v );
    229157                } else {                                                                                // octal constant
    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
     158                        sscanf( (char *)str.c_str(), "%llo", &v );
    258159                        //printf( "%#llo %llu\n", v, v );
    259160                } // if
    260161        } else {                                                                                        // decimal constant ?
    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
     162                sscanf( (char *)str.c_str(), "%llu", &v );
    291163                //printf( "%llu\n", v );
    292164        } // if
    293165
    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 ); */
     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
    298205
    299206        //if ( !( 0 <= type && type <= 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); }
     
    307214        } else if ( ltype != -1 ) {                                                     // explicit length ?
    308215                if ( ltype == 6 ) {                                                             // int128, (int128)constant
    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 ) );
     216                        ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    313217                } else {                                                                                // explicit length, (length_type)constant
    314218                        ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false );
     
    438342                if ( str[1] == '8' ) goto Default;                              // utf-8 characters => array of char
    439343                // lookup type of associated typedef
    440                 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false );
     344                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "char16_t", false );
    441345                break;
    442346          case 'U':
    443                 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false );
     347                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "char32_t", false );
    444348                break;
    445349          case 'L':
    446                 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false );
     350                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "wchar_t", false );
    447351                break;
    448352          Default:                                                                                      // char default string type
    449353          default:
    450                 strtype = new BasicType( Type::Qualifiers( ), BasicType::Char );
     354                strtype = new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char );
    451355        } // switch
    452356        ArrayType * at = new ArrayType( noQualifiers, strtype,
Note: See TracChangeset for help on using the changeset viewer.