Changeset c5b55c4 for src/Parser


Ignore:
Timestamp:
Aug 20, 2020, 1:56:08 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
013b028
Parents:
03a4c73
Message:

fix missing 'u' suffix for length suffix, change L128 constants to always generate hexadecimal components

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r03a4c73 rc5b55c4  
    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 : Thu Aug 20 11:52:59 2020
     13// Update Count     : 1075
    1414//
    1515
     
    6565
    6666void lnthSuffix( string & str, int & type, int & ltype ) {
     67        // 'u' can appear before or after length suffix
    6768        string::size_type posn = str.find_last_of( "lL" );
    6869
    6970        if ( posn == string::npos ) return;                                     // no suffix
    70         if ( posn == str.length() - 1 ) { type = 3; return; } // no length => long
    71 
     71        size_t end = str.length() - 1;
     72        if ( posn == end ) { type = 3; return; }                        // no length after 'l' => long
     73       
    7274        string::size_type next = posn + 1;                                      // advance to length
    7375        if ( str[next] == '3' ) {                                                       // 32
     
    8486                } // if
    8587        } // if
    86         // remove "lL" for these cases because it may not imply long
    87         str.erase( posn );                                                                      // remove length suffix and "uU"
     88
     89        char fix = '\0';
     90        if ( str[end] == 'u' || str[end] == 'U' ) fix = str[end]; // ends with 'uU' ?
     91        str.erase( posn );                                                                      // remove length suffix and possibly uU
     92        if ( type == 5 ) {                                                                      // L128 does not need uU
     93                end = str.length() - 1;
     94                if ( str[end] == 'u' || str[end] == 'U' ) str.erase( end ); // ends with 'uU' ? remove
     95        } else if ( fix != '\0' ) str += fix;                           // put 'uU' back if removed
    8896} // lnthSuffix
    8997
     
    156164        if ( isdigit( str[str.length() - 1] ) ) {                       // no suffix ?
    157165                lnthSuffix( str, type, ltype );                                 // could have length suffix
    158                 if ( type == 5 && Unsigned ) str.erase( str.length() - 1 ); // L128 and terminating "uU" ?
    159166        } else {
    160167                // At least one digit in integer constant, so safe to backup while looking for suffix.
     
    195202                        if ( type < 5 ) {                                                       // not L128 ?
    196203                                sscanf( (char *)str.c_str(), "%llx", &v );
     204#if defined(__SIZEOF_INT128__)
    197205                        } else {                                                                        // hex int128 constant
    198206                                unsigned int len = str.length();
     
    204212                          FHEX1: ;
    205213                                sscanf( (char *)str.c_str(), "%llx", &v );
     214#endif // __SIZEOF_INT128__
    206215                        } // if
    207216                        //printf( "%llx %llu\n", v, v );
    208217                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    209218                        unsigned int len = str.length();
     219#if defined(__SIZEOF_INT128__)
    210220                        if ( type == 5 && len > 2 + 64 ) {
    211221                                if ( len > 2 + 64 + 64 ) SemanticError( yylloc, "128-bit binary constant to large " + str );
     
    214224                                scanbin( str2, v2 );
    215225                        } // if
     226#endif // __SIZEOF_INT128__
    216227                        scanbin( str, v );
    217228                        //printf( "%#llx %llu\n", v, v );
     
    223234                                unsigned int len = str.length();
    224235                                if ( len > 1 + 43 || (len == 1 + 43 && str[0] > '3') ) SemanticError( yylloc, "128-bit octal constant to large " + str );
     236                                char buf[32];
    225237                                if ( len <= 1 + 21 ) {                                  // value < 21 octal digitis
    226                                         sscanf( (char *)str.c_str(), "%llo", &v ); // leave value in octal
     238                                        sscanf( (char *)str.c_str(), "%llo", &v );
    227239                                } else {
    228240                                        sscanf( &str[len - 21], "%llo", &v );
     
    237249                                        } // if
    238250                                        v = val >> 64; v2 = (uint64_t)val;      // replace octal constant with 2 hex constants
    239                                         char buf[32];
    240251                                        sprintf( buf, "%#llx", v2 );
    241252                                        str2 = buf;
    242                                         sprintf( buf, "%#llx", v );
    243                                         str = buf;
    244253                                } // if
     254                                sprintf( buf, "%#llx", v );
     255                                str = buf;
    245256#endif // __SIZEOF_INT128__
    246257                        } // if
     
    256267                        if ( str.length() == 39 && str > (Unsigned ? "340282366920938463463374607431768211455" : "170141183460469231731687303715884105727") )
    257268                                SemanticError( yylloc, "128-bit decimal constant to large " + str );
     269                        char buf[32];
    258270                        if ( len <= 19 ) {                                                      // value < 19 decimal digitis
    259                                 sscanf( (char *)str.c_str(), "%llu", &v ); // leave value in decimal
     271                                sscanf( (char *)str.c_str(), "%llu", &v );
    260272                        } else {
    261273                                sscanf( &str[len - 19], "%llu", &v );
     
    270282                                } // if
    271283                                v = val >> 64; v2 = (uint64_t)val;              // replace decimal constant with 2 hex constants
    272                                 char buf[32];
    273284                                sprintf( buf, "%#llx", v2 );
    274285                                str2 = buf;
    275                                 sprintf( buf, "%#llx", v );
    276                                 str = buf;
    277286                        } // if
     287                        sprintf( buf, "%#llx", v );
     288                        str = buf;
    278289#endif // __SIZEOF_INT128__
    279290                } // if
Note: See TracChangeset for help on using the changeset viewer.