Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    rb81fd95 r3c67255  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 15 08:24:08 2020
    13 // Update Count     : 1046
     12// Last Modified On : Wed Dec 18 21:14:58 2019
     13// Update Count     : 981
    1414//
    1515
     
    8585        } // if
    8686        // remove "lL" for these cases because it may not imply long
    87         str.erase( posn );                                                                      // remove length suffix and "uU"
     87        str.erase( posn );                                                                      // remove length
    8888} // lnthSuffix
    8989
     
    108108} // valueToType
    109109
    110 static void scanbin( string & str, unsigned long long int & v ) {
    111         v = 0;
    112         size_t last = str.length() - 1;                                         // last subscript of constant
    113         for ( unsigned int i = 2;; ) {                                          // ignore prefix
    114                 if ( str[i] == '1' ) v |= 1;
    115                 i += 1;
    116           if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
    117                 v <<= 1;
    118         } // for
    119 } // scanbin
    120 
    121110Expression * build_constantInteger( string & str ) {
    122111        static const BasicType::Kind kind[2][6] = {
    123112                // short (h) must be before char (hh) because shorter type has the longer suffix
    124                 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ BasicType::LongLongSignedInt, },
    125                 { 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, },
    126115        };
    127116
     
    131120        }; // lnthsInt
    132121
    133         string str2( "0x0" );
    134         unsigned long long int v, v2 = 0;                                       // converted integral value
    135         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 );
    136126
    137127        int type = -1;                                                                          // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     
    149139        } // if
    150140
    151         string::size_type posn;
    152 
    153         // 'u' can appear before or after length suffix
    154         if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true;
    155 
    156         if ( isdigit( str[str.length() - 1] ) ) {                       // no suffix ?
    157                 lnthSuffix( str, type, ltype );                                 // could have length suffix
    158                 if ( type == 5 && Unsigned ) str.erase( str.length() - 1 ); // L128 and terminating "uU" ?
    159         } else {
    160                 // At least one digit in integer constant, so safe to backup while looking for suffix.
    161 
    162                 posn = str.find_last_of( "pP" );                                // pointer value
    163                 if ( posn != string::npos ) { ltype = 5; str.erase( posn, 1 ); goto FINI; }
    164 
    165                 posn = str.find_last_of( "zZ" );                                // size_t
    166                 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
    167 
    168                 posn = str.rfind( "hh" );                                               // char
    169                 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
    170 
    171                 posn = str.rfind( "HH" );                                               // char
    172                 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
    173 
    174                 posn = str.find_last_of( "hH" );                                // short
    175                 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; }
    176 
    177                 posn = str.find_last_of( "nN" );                                // int (natural number)
    178                 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; }
    179 
    180                 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; }
    181 
    182                 lnthSuffix( str, type, ltype );                                 // must be after check for "ll"
    183           FINI: ;
    184         } // if
    185 
    186141        // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate
    187142
    188 #if ! defined(__SIZEOF_INT128__)
    189         if ( type == 5 ) SemanticError( yylloc, "int128 constant is not supported on this target " + str );
    190 #endif // ! __SIZEOF_INT128__
    191        
    192143        if ( str[0] == '0' ) {                                                          // radix character ?
    193144                dec = false;
    194145                if ( checkX( str[1] ) ) {                                               // hex constant ?
    195                         if ( type < 5 ) {                                                       // not L128 ?
    196                                 sscanf( (char *)str.c_str(), "%llx", &v );
    197                         } else {                                                                        // hex int128 constant
    198                                 unsigned int len = str.length();
    199                                 if ( len > (2 + 16 + 16) ) SemanticError( yylloc, "128-bit hexadecimal constant to large " + str );
    200                           if ( len <= (2 + 16) ) goto FHEX1;            // hex digits < 2^64
    201                                 str2 = "0x" + str.substr( len - 16 );
    202                                 sscanf( (char *)str2.c_str(), "%llx", &v2 );
    203                                 str = str.substr( 0, len - 16 );
    204                           FHEX1: ;
    205                                 sscanf( (char *)str.c_str(), "%llx", &v );
    206                         } // if
     146                        sscanf( (char *)str.c_str(), "%llx", &v );
    207147                        //printf( "%llx %llu\n", v, v );
    208148                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    209                         unsigned int len = str.length();
    210                         if ( type == 5 && len > 2 + 64 ) {
    211                                 if ( len > 2 + 64 + 64 ) SemanticError( yylloc, "128-bit binary constant to large " + str );
    212                                 str2 = "0b" + str.substr( len - 64 );
    213                                 str = str.substr( 0, len - 64 );
    214                                 scanbin( str2, v2 );
    215                         } // if
    216                         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
    217156                        //printf( "%#llx %llu\n", v, v );
    218157                } else {                                                                                // octal constant
    219                         if ( type < 5 ) {                                                       // not L128 ?
    220                                 sscanf( (char *)str.c_str(), "%llo", &v );
    221 #if defined(__SIZEOF_INT128__)
    222                         } else {                                                                        // octal int128 constant
    223                                 unsigned int len = str.length();
    224                                 if ( len > 1 + 43 || (len == 1 + 43 && str[0] > '3') ) SemanticError( yylloc, "128-bit octal constant to large " + str );
    225                                 if ( len <= 1 + 21 ) {                                  // value < 21 octal digitis
    226                                         sscanf( (char *)str.c_str(), "%llo", &v ); // leave value in octal
    227                                 } else {
    228                                         sscanf( &str[len - 21], "%llo", &v );
    229                                         __int128 val = v;                                       // accumulate bits
    230                                         str[len - 21] ='\0';                            // shorten string
    231                                         sscanf( &str[len == 43 ? 1 : 0], "%llo", &v );
    232                                         val |= (__int128)v << 63;                       // store bits
    233                                         if ( len == 1 + 43 ) {                          // most significant 2 bits ?
    234                                                 str[2] = '\0';                                  // shorten string
    235                                                 sscanf( &str[1], "%llo", &v );  // process most significant 2 bits
    236                                                 val |= (__int128)v << 126;              // store bits
    237                                         } // if
    238                                         v = val >> 64; v2 = (uint64_t)val;      // replace octal constant with 2 hex constants
    239                                         char buf[32];
    240                                         sprintf( buf, "%#llx", v2 );
    241                                         str2 = buf;
    242                                         sprintf( buf, "%#llx", v );
    243                                         str = buf;
    244                                 } // if
    245 #endif // __SIZEOF_INT128__
    246                         } // if
     158                        sscanf( (char *)str.c_str(), "%llo", &v );
    247159                        //printf( "%#llo %llu\n", v, v );
    248160                } // if
    249161        } else {                                                                                        // decimal constant ?
    250                 if ( type < 5 ) {                                                               // not L128 ?
    251                         sscanf( (char *)str.c_str(), "%llu", &v );
    252 #if defined(__SIZEOF_INT128__)
    253                 } else {                                                                                // decimal int128 constant
    254                         #define P10_UINT64 10'000'000'000'000'000'000ULL // 19 zeroes
    255                         unsigned int len = str.length();
    256                         if ( str.length() == 39 && str > (Unsigned ? "340282366920938463463374607431768211455" : "170141183460469231731687303715884105727") )
    257                                 SemanticError( yylloc, "128-bit decimal constant to large " + str );
    258                         if ( len <= 19 ) {                                                      // value < 19 decimal digitis
    259                                 sscanf( (char *)str.c_str(), "%llu", &v ); // leave value in decimal
    260                         } else {
    261                                 sscanf( &str[len - 19], "%llu", &v );
    262                                 __int128 val = v;                                               // accumulate bits
    263                                 str[len - 19] ='\0';                                    // shorten string
    264                                 sscanf( &str[len == 39 ? 1 : 0], "%llu", &v );
    265                                 val += (__int128)v * (__int128)P10_UINT64; // store bits
    266                                 if ( len == 39 ) {                                              // most significant 2 bits ?
    267                                         str[1] = '\0';                                          // shorten string
    268                                         sscanf( &str[0], "%llu", &v );          // process most significant 2 bits
    269                                         val += (__int128)v * (__int128)P10_UINT64 * (__int128)P10_UINT64; // store bits
    270                                 } // if
    271                                 v = val >> 64; v2 = (uint64_t)val;              // replace decimal constant with 2 hex constants
    272                                 char buf[32];
    273                                 sprintf( buf, "%#llx", v2 );
    274                                 str2 = buf;
    275                                 sprintf( buf, "%#llx", v );
    276                                 str = buf;
    277                         } // if
    278 #endif // __SIZEOF_INT128__
    279                 } // if
     162                sscanf( (char *)str.c_str(), "%llu", &v );
    280163                //printf( "%llu\n", v );
    281164        } // if
    282165
    283         if ( type == -1 ) {                                                                     // no suffix => determine type from value size
    284                 valueToType( v, dec, type, Unsigned );
    285         } // if
    286         /* 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
    287205
    288206        //if ( !( 0 <= type && type <= 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); }
     
    296214        } else if ( ltype != -1 ) {                                                     // explicit length ?
    297215                if ( ltype == 6 ) {                                                             // int128, (int128)constant
    298 //                      ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    299                         ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) );
    300                         ret = build_compoundLiteral( DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ),
    301                                                                                  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 );
    302217                } else {                                                                                // explicit length, (length_type)constant
    303218                        ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false );
     
    427342                if ( str[1] == '8' ) goto Default;                              // utf-8 characters => array of char
    428343                // lookup type of associated typedef
    429                 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false );
     344                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "char16_t", false );
    430345                break;
    431346          case 'U':
    432                 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false );
     347                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "char32_t", false );
    433348                break;
    434349          case 'L':
    435                 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false );
     350                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "wchar_t", false );
    436351                break;
    437352          Default:                                                                                      // char default string type
    438353          default:
    439                 strtype = new BasicType( Type::Qualifiers( ), BasicType::Char );
     354                strtype = new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char );
    440355        } // switch
    441356        ArrayType * at = new ArrayType( noQualifiers, strtype,
Note: See TracChangeset for help on using the changeset viewer.