Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r3d8d7a7 r6e3eaa57  
    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 : Mon Jun  4 21:24:45 2018
     13// Update Count     : 802
    1414//
    1515
     
    5151extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
    5252
    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'; }
     53static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
     54static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
     55static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
     56static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
    5657static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
    5758static 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'; }
    6159static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
    6260static inline bool checkB( char c ) { return c == 'b' || c == 'B'; }
    6361static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    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;
     62
     63static 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
     68static 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;
    8279                } 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
    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
     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
    10995
    11096Expression * build_constantInteger( string & str ) {
    111         static const BasicType::Kind kind[2][7] = {
    112                 // short (h) must be before char (hh) because shorter type has the longer suffix
     97        static const BasicType::Kind kind[2][6] = {
     98                // short (h) must be before char (hh)
    11399                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
    114100                { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },
    115101        };
    116102
    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
     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
    121106
    122107        unsigned long long int v;                                                       // converted integral value
    123108        size_t last = str.length() - 1;                                         // last subscript of constant
    124109        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
    130110
    131111        // special constants
     
    139119        } // if
    140120
    141         // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate
     121        // Cannot be "0"
    142122
    143123        if ( str[0] == '0' ) {                                                          // radix character ?
     
    147127                        //printf( "%llx %llu\n", v, v );
    148128                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    149                         v = 0;                                                                          // compute value
    150                         for ( unsigned int i = 2;; ) {                          // ignore prefix
     129                        v = 0;
     130                        for ( unsigned int i = 2;; i += 1 ) {           // compute value
    151131                                if ( str[i] == '1' ) v |= 1;
    152                                 i += 1;
    153                           if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
     132                          if ( i == last ) break;
    154133                                v <<= 1;
    155134                        } // for
    156                         //printf( "%#llx %llu\n", v, v );
     135                        //printf( "%llx %llu\n", v, v );
    157136                } else {                                                                                // octal constant
    158137                        sscanf( (char *)str.c_str(), "%llo", &v );
    159                         //printf( "%#llo %llu\n", v, v );
     138                        //printf( "%llo %llu\n", v, v );
    160139                } // if
    161140        } else {                                                                                        // decimal constant ?
    162141                sscanf( (char *)str.c_str(), "%llu", &v );
    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 
     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;
     170                        } // 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 );
    209209        // 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 ?
     210        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
     211        if ( Unsigned && size < 2 ) {                                           // hh or h, less than int ?
    212212                // 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 ) );
    221                         } // if
    222                 } // if
    223         } // if
    224 
    225   CLEANUP: ;
     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
    226224        delete &str;                                                                            // created by lex
    227225        return ret;
     
    229227
    230228
    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
     229static inline void checkLNFloat( string & str, int & lnth, int & size ) {
     230        string::size_type posn = str.find_first_of( "lL" ), start = posn;
    240231  if ( posn == string::npos ) return;
    241         explnth = true;
     232        size = 2;                                                                                       // assume largest size
     233        lnth = 0;
    242234        posn += 1;                                                                                      // advance to size
    243235        if ( str[posn] == '3' ) {                                                       // 32
    244                 if ( str[last] != 'x' ) type = 6;
    245                 else type = 7;
     236                size = 0;
    246237        } else if ( str[posn] == '6' ) {                                        // 64
    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
     238                size = 1;
     239        } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128
     240                size = 2;
     241                if ( str[posn] == '1' ) posn += 1;
    258242        } else {
    259243                assertf( false, "internal error, bad floating point length %s", str.c_str() );
    260244        } // if
    261 } // checkFnxFloat
     245        posn += 1;
     246        str.erase( start, posn - start + 1 );                           // remove length suffix
     247} // checkLNFloat
    262248
    263249
    264250Expression * build_constantFloat( string & str ) {
    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 },
     251        static const BasicType::Kind kind[2][3] = {
     252                { BasicType::Float, BasicType::Double, BasicType::LongDouble },
     253                { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
    268254        };
    269255
    270         // floating-point constant has minimum of 2 characters 1. or .1
     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
    271260        size_t last = str.length() - 1;
    272261        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
    276262
    277263        sscanf( str.c_str(), "%lg", &v );
     
    283269
    284270        if ( checkF( str[last] ) ) {                                            // float ?
    285                 type = 0;
     271                size = 0;
    286272        } else if ( checkD( str[last] ) ) {                                     // double ?
    287                 type = 1;
     273                size = 1;
    288274        } else if ( checkL( str[last] ) ) {                                     // long double ?
    289                 type = 2;
    290         } else if ( checkF80( str[last] ) ) {                           // __float80 ?
    291                 type = 3;
    292         } else if ( checkF128( str[last] ) ) {                          // __float128 ?
    293                 type = 4;
     275                size = 2;
    294276        } else {
    295                 type = 1;                                                                               // double (default if no suffix)
    296                 checkFnxFloat( str, last, explnth, type );
    297         } // if
    298 
     277                size = 1;                                                                               // double (default)
     278                checkLNFloat( str, lnth, size );
     279        } // if
    299280        if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
    300281                complx = true;
    301282        } // if
    302283
    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 );
     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 );
    307288        } // if
    308289
Note: See TracChangeset for help on using the changeset viewer.