Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    re15853c r6e3eaa57  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 13 18:07:38 2019
    13 // Update Count     : 902
     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 checkL( char c ) { return c == 'l' || c == 'L'; }
    60 static inline bool checkF128( char c ) { return c == 'q' || c == 'Q'; }
    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'; }
    6462
     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;
     79                } else {                                                                                // 128
     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
     95
    6596Expression * build_constantInteger( string & str ) {
    6697        static const BasicType::Kind kind[2][6] = {
    67                 // short (h) must be before char (hh) because shorter type has the longer suffix
     98                // short (h) must be before char (hh)
    6899                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
    69100                { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },
    70101        };
    71102
    72         static const char * lnthsInt[2][5] = {
    73                 { "int16_t",  "int8_t",  "int32_t",  "int64_t",  "size_t", },
    74                 { "uint16_t", "uint8_t", "uint32_t", "uint64_t", "size_t", },
    75         }; // lnthsInt
    76 
    77103        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    78         int type = -1;                                                                          // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
    79         int ltype = -1;                                                                         // literal length
     104        int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     105        int lnth = -1;                                                                          // literal length
    80106
    81107        unsigned long long int v;                                                       // converted integral value
     
    101127                        //printf( "%llx %llu\n", v, v );
    102128                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    103                         v = 0;                                                                          // compute value
    104                         for ( unsigned int i = 2;; ) {
     129                        v = 0;
     130                        for ( unsigned int i = 2;; i += 1 ) {           // compute value
    105131                                if ( str[i] == '1' ) v |= 1;
    106                                 i += 1;
    107                           if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
     132                          if ( i == last ) break;
    108133                                v <<= 1;
    109134                        } // for
    110                         //printf( "%#llx %llu\n", v, v );
     135                        //printf( "%llx %llu\n", v, v );
    111136                } else {                                                                                // octal constant
    112137                        sscanf( (char *)str.c_str(), "%llo", &v );
    113                         //printf( "%#llo %llu\n", v, v );
     138                        //printf( "%llo %llu\n", v, v );
    114139                } // if
    115140        } else {                                                                                        // decimal constant ?
     
    118143        } // if
    119144
     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
    120162        // At least one digit in integer constant, so safe to backup while looking for suffix.
    121163
    122         string::size_type posn;
    123 
    124         if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true;
    125 
    126         posn = str.rfind( "hh" );
    127         if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
    128 
    129         posn = str.rfind( "HH" );
    130         if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
    131 
    132         posn = str.find_last_of( "hH" );
    133         if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; }
    134 
    135         posn = str.find_last_of( "zZ" );
    136         if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
    137 
    138         if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; }
    139 
    140         posn = str.find_last_of( "lL" );
    141         if ( posn != string::npos ) {
    142                 type = 3;                                                                               // default
    143                 posn += 1;                                                                              // advance to size
    144                 if ( str[posn] == '3' ) {                                               // 32
    145                         type = ltype = 2; str.erase( posn, 2 );
    146                 } else if ( str[posn] == '6' ) {                                // 64
    147                         type = ltype = 3; str.erase( posn, 2 );
    148                 } else if ( str[posn] == '8' ) {                                // 8
    149                         type = ltype = 1; str.erase( posn, 1 );
    150                 } else if ( str[posn] == '1' ) {
    151                         if ( str[posn + 1] == '6' ) {                           // 16
    152                                 type = ltype = 0; str.erase( posn, 2 );
    153                         } else {                                                                        // 128
    154                                 type = ltype = 5; str.erase( posn, 3 );
     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;
    155170                        } // if
    156                 } // if
    157         } // if
    158   FINI:
    159 
    160         if ( type == -1 ) {                                                                     // no suffix type, use value
    161                 if ( v <= INT_MAX ) {                                                   // signed int
    162                         type = 2;
    163                 } else if ( v <= UINT_MAX && ! dec ) {                  // unsigned int
    164                         type = 2;
    165                         Unsigned = true;                                                        // unsigned
    166                 } else if ( v <= LONG_MAX ) {                                   // signed long int
    167                         type = 3;
    168                 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
    169                         type = 3;
    170                         Unsigned = true;                                                        // unsigned long int
    171                 } else if ( v <= LLONG_MAX ) {                                  // signed long long int
    172                         type = 4;
    173                 } else {                                                                                // unsigned long long int
    174                         type = 4;
    175                         Unsigned = true;                                                        // unsigned long long int
    176                 } // if
    177         } // if
    178 
    179         assert( 0 <= type && type < 6 );
     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 );
    180209        // Constant type is correct for overload resolving.
    181         ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) );
    182         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 ?
    183212                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
    184                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    185         } else if ( ltype != -1 ) {                                                     // explicit length ?
    186                 if ( ltype == 5 ) {                                                             // int128 ?
    187                         type = 5;
    188                         ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
     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 );
    189218                } else {
    190                         ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false );
     219                        ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ), false );
    191220                } // if
    192221        } // if
     
    198227
    199228
    200 static inline void checkFnxFloat( string & str, size_t last, bool & explnth, int & type ) {
    201         string::size_type posn;
    202         // floating-point constant has minimum of 2 characters, 1. or .1, so safe to look ahead
    203         if ( str[1] == 'x' ) {                                                          // hex ?
    204                 posn = str.find_last_of( "pP" );                                // back for exponent (must have)
    205                 posn = str.find_first_of( "fF", posn + 1 );             // forward for size (fF allowed in hex constant)
    206         } else {
    207                 posn = str.find_last_of( "fF" );                                // back for size (fF not allowed)
    208         } // if
     229static inline void checkLNFloat( string & str, int & lnth, int & size ) {
     230        string::size_type posn = str.find_first_of( "lL" ), start = posn;
    209231  if ( posn == string::npos ) return;
    210         explnth = true;
     232        size = 2;                                                                                       // assume largest size
     233        lnth = 0;
    211234        posn += 1;                                                                                      // advance to size
    212235        if ( str[posn] == '3' ) {                                                       // 32
    213                 if ( str[last] != 'x' ) type = 6;
    214                 else type = 7;
     236                size = 0;
    215237        } else if ( str[posn] == '6' ) {                                        // 64
    216                 if ( str[last] != 'x' ) type = 8;
    217                 else type = 9;
    218         } else if ( str[posn] == '8' ) {                                        // 80
    219                 type = 3;
    220         } else if ( str[posn] == '1' ) {                                        // 16/128
    221                 if ( str[posn + 1] == '6' ) {                                   // 16
    222                         type = 5;
    223                 } else {                                                                                // 128
    224                         if ( str[last] != 'x' ) type = 10;
    225                         else type = 11;
    226                 } // 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;
    227242        } else {
    228243                assertf( false, "internal error, bad floating point length %s", str.c_str() );
    229244        } // if
    230 } // checkFnxFloat
     245        posn += 1;
     246        str.erase( start, posn - start + 1 );                           // remove length suffix
     247} // checkLNFloat
    231248
    232249
    233250Expression * build_constantFloat( string & str ) {
    234         static const BasicType::Kind kind[2][12] = {
    235                 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x },
    236                 { 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 },
    237254        };
    238255
    239         // 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
    240260        size_t last = str.length() - 1;
    241261        double v;
    242         int type;                                                                                       // 0 => float, 1 => double, 3 => long double, ...
    243         bool complx = false;                                                            // real, complex
    244         bool explnth = false;                                                           // explicit literal length
    245262
    246263        sscanf( str.c_str(), "%lg", &v );
     
    252269
    253270        if ( checkF( str[last] ) ) {                                            // float ?
    254                 type = 0;
     271                size = 0;
    255272        } else if ( checkD( str[last] ) ) {                                     // double ?
    256                 type = 1;
     273                size = 1;
    257274        } else if ( checkL( str[last] ) ) {                                     // long double ?
    258                 type = 2;
    259         } else if ( checkF80( str[last] ) ) {                           // __float80 ?
    260                 type = 3;
    261         } else if ( checkF128( str[last] ) ) {                          // __float128 ?
    262                 type = 4;
     275                size = 2;
    263276        } else {
    264                 type = 1;                                                                               // double (default if no suffix)
    265                 checkFnxFloat( str, last, explnth, type );
    266         } // if
    267 
     277                size = 1;                                                                               // double (default)
     278                checkLNFloat( str, lnth, size );
     279        } // if
    268280        if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
    269281                complx = true;
    270282        } // if
    271283
    272         assert( 0 <= type && type < 12 );
    273         Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) );
    274         if ( explnth ) {                                                                        // explicit length ?
    275                 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 );
    276288        } // if
    277289
Note: See TracChangeset for help on using the changeset viewer.