Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r0a616e0 rf56c32e  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Mar 10 16:10:32 2019
    13 // Update Count     : 976
     12// Last Modified On : Thu Feb 28 21:36:38 2019
     13// Update Count     : 933
    1414//
    1515
     
    6666void lnthSuffix( string & str, int & type, int & ltype ) {
    6767        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;
    82                 } else {                                                                                // 128
    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
     68        if ( posn != string::npos ) {
     69                type = 3;                                                                               // default
     70                posn += 1;                                                                              // advance to size
     71                if ( str[posn] == '3' ) {                                               // 32
     72                        type = ltype = 2; str.erase( posn, 2 );
     73                } else if ( str[posn] == '6' ) {                                // 64
     74                        type = ltype = 3; str.erase( posn, 2 );
     75                } else if ( str[posn] == '8' ) {                                // 8
     76                        type = ltype = 1; str.erase( posn, 1 );
     77                } else if ( str[posn] == '1' ) {
     78                        if ( str[posn + 1] == '6' ) {                           // 16
     79                                type = ltype = 0; str.erase( posn, 2 );
     80                        } else {                                                                        // 128
     81                                type = ltype = 5; str.erase( posn, 3 );
     82                        } // if
     83                } // if
     84        } // if
    8885} // lnthSuffix
    8986
    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
    109 
    11087Expression * build_constantInteger( string & str ) {
    111         static const BasicType::Kind kind[2][7] = {
     88        static const BasicType::Kind kind[2][6] = {
    11289                // short (h) must be before char (hh) because shorter type has the longer suffix
    11390                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
     
    11592        };
    11693
    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", },
     94        static const char * lnthsInt[2][5] = {
     95                { "int16_t",  "int8_t",  "int32_t",  "int64_t",  "size_t", },
     96                { "uint16_t", "uint8_t", "uint32_t", "uint64_t", "size_t", },
    12097        }; // lnthsInt
     98
     99        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
     100        int type = -1;                                                                          // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     101        int ltype = -1;                                                                         // literal length
    121102
    122103        unsigned long long int v;                                                       // converted integral value
    123104        size_t last = str.length() - 1;                                         // last subscript of constant
    124105        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
     106        string fred( str );
    130107
    131108        // special constants
     
    139116        } // if
    140117
    141         // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate
     118        // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall so always generate
    142119
    143120        if ( str[0] == '0' ) {                                                          // radix character ?
     
    148125                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    149126                        v = 0;                                                                          // compute value
    150                         for ( unsigned int i = 2;; ) {                          // ignore prefix
     127                        for ( unsigned int i = 2;; ) {
    151128                                if ( str[i] == '1' ) v |= 1;
    152129                                i += 1;
     
    168145        if ( isdigit( str[last] ) ) {                                           // no suffix ?
    169146                lnthSuffix( str, type, ltype );                                 // could have length suffix
    170                 if ( type == -1 ) {                                                             // no suffix
    171                         valueToType( v, dec, type, Unsigned );
     147                if ( type == -1 ) {
     148                        // no suffix type, use value to determine type
     149                        if ( v <= INT_MAX ) {                                           // signed int
     150                                type = 2;
     151                        } else if ( v <= UINT_MAX && ! dec ) {          // unsigned int
     152                                type = 2;
     153                                Unsigned = true;                                                // unsigned
     154                        } else if ( v <= LONG_MAX ) {                           // signed long int
     155                                type = 3;
     156                        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
     157                                type = 3;
     158                                Unsigned = true;                                                // unsigned long int
     159                        } else if ( v <= LLONG_MAX ) {                          // signed long long int
     160                                type = 4;
     161                        } else {                                                                        // unsigned long long int
     162                                type = 4;
     163                                Unsigned = true;                                                // unsigned long long int
     164                        } // if
    172165                } // if
    173166        } else {
    174167                // At least one digit in integer constant, so safe to backup while looking for suffix.
    175168
    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; }
     169                if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true;
     170
     171                posn = str.rfind( "hh" );
     172                if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
     173
     174                posn = str.rfind( "HH" );
     175                if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
     176
     177                posn = str.find_last_of( "hH" );
     178                if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; }
     179
     180                posn = str.find_last_of( "nN" );
     181                if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; }
    178182
    179183                posn = str.find_last_of( "zZ" );
    180184                if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
    181185
    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 
    197186                if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; }
    198187
    199188                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
     189                if ( type == -1 ) { type = 3; goto FINI; }
    203190          FINI: ;
    204191        } // if
    205192
    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 );
     193        //if ( !( 0 <= type && type < 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); }
     194        assert( 0 <= type && type < 6 );
    208195
    209196        // Constant type is correct for overload resolving.
     
    213200                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    214201        } else if ( ltype != -1 ) {                                                     // explicit length ?
    215                 if ( ltype == 6 ) {                                                             // int128, (int128)constant
     202                if ( ltype == 5 ) {                                                             // int128 ?
     203                        type = 5;
    216204                        ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    217                 } else {                                                                                // explicit length, (length_type)constant
     205                } else {
    218206                        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 ) );                                                             
    221                         } // if
    222207                } // if
    223208        } // if
Note: See TracChangeset for help on using the changeset viewer.