Ignore:
Timestamp:
Mar 10, 2019, 10:54:33 PM (6 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
9e6955d
Parents:
7579ac0
Message:

clean up constant code and add pointer suffix

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r7579ac0 r0a616e0  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 28 21:36:38 2019
    13 // Update Count     : 933
     12// Last Modified On : Sun Mar 10 16:10:32 2019
     13// Update Count     : 976
    1414//
    1515
     
    6666void lnthSuffix( string & str, int & type, int & ltype ) {
    6767        string::size_type posn = str.find_last_of( "lL" );
    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
     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
    8588} // lnthSuffix
    8689
     90void 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
    87110Expression * build_constantInteger( string & str ) {
    88         static const BasicType::Kind kind[2][6] = {
     111        static const BasicType::Kind kind[2][7] = {
    89112                // short (h) must be before char (hh) because shorter type has the longer suffix
    90113                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
     
    92115        };
    93116
    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", },
     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", },
    97120        }; // 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
    102121
    103122        unsigned long long int v;                                                       // converted integral value
    104123        size_t last = str.length() - 1;                                         // last subscript of constant
    105124        Expression * ret;
    106         string fred( str );
     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
    107130
    108131        // special constants
     
    116139        } // if
    117140
    118         // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall so always generate
     141        // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate
    119142
    120143        if ( str[0] == '0' ) {                                                          // radix character ?
     
    125148                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    126149                        v = 0;                                                                          // compute value
    127                         for ( unsigned int i = 2;; ) {
     150                        for ( unsigned int i = 2;; ) {                          // ignore prefix
    128151                                if ( str[i] == '1' ) v |= 1;
    129152                                i += 1;
     
    145168        if ( isdigit( str[last] ) ) {                                           // no suffix ?
    146169                lnthSuffix( str, type, ltype );                                 // could have length suffix
    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
     170                if ( type == -1 ) {                                                             // no suffix
     171                        valueToType( v, dec, type, Unsigned );
    165172                } // if
    166173        } else {
    167174                // At least one digit in integer constant, so safe to backup while looking for suffix.
    168175
     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
    169183                if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true;
    170184
     
    181195                if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; }
    182196
    183                 posn = str.find_last_of( "zZ" );
    184                 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
    185 
    186197                if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; }
    187198
    188199                lnthSuffix( str, type, ltype );                                 // must be after check for "ll"
    189                 if ( type == -1 ) { type = 3; goto FINI; }
     200                if ( type == -1 ) {                                                             // only 'u' suffix ?
     201                        valueToType( v, dec, type, Unsigned );
     202                } // if
    190203          FINI: ;
    191204        } // if
    192205
    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 );
     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 );
    195208
    196209        // Constant type is correct for overload resolving.
     
    200213                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    201214        } else if ( ltype != -1 ) {                                                     // explicit length ?
    202                 if ( ltype == 5 ) {                                                             // int128 ?
    203                         type = 5;
     215                if ( ltype == 6 ) {                                                             // int128, (int128)constant
    204216                        ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    205                 } else {
     217                } else {                                                                                // explicit length, (length_type)constant
    206218                        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
    207222                } // if
    208223        } // if
Note: See TracChangeset for help on using the changeset viewer.