Changeset 933f32f for src/Parser


Ignore:
Timestamp:
May 24, 2019, 10:19:41 AM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, 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:
d908563
Parents:
6a9d4b4 (diff), 292642a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into cleanup-dtors

Location:
src/Parser
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov  1 20:54:26 2018
    13 // Update Count     : 1108
     12// Last Modified On : Fri Feb  1 16:49:17 2019
     13// Update Count     : 1113
    1414//
    1515
     
    4141
    4242// These must harmonize with the corresponding DeclarationNode enumerations.
    43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "int128", "float80", "float128", "NoBasicTypeNames" };
    44 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "_Imaginary", "NoComplexTypeNames" };
     43const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "int128",
     44                                                                                                   "float", "double", "long double", "float80", "float128",
     45                                                                                                   "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" };
     46const char * DeclarationNode::complexTypeNames[] = { "_Complex", "NoComplexTypeNames", "_Imaginary" }; // Imaginary unsupported => parse, but make invisible and print error message
    4547const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
    4648const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" };
  • src/Parser/ExpressionNode.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun  4 21:24:45 2018
    13 // Update Count     : 802
     12// Last Modified On : Sun Mar 10 16:10:32 2019
     13// Update Count     : 976
    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 checkL( char c ) { return c == 'l' || c == 'L'; }
    55 static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
    56 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
     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'; }
    5756static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
    5857static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     58static inline bool checkF80( char c ) { return c == 'w' || c == 'W'; }
     59static inline bool checkF128( char c ) { return c == 'q' || c == 'Q'; }
     60static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
    5961static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
    6062static inline bool checkB( char c ) { return c == 'b' || c == 'B'; }
    6163static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    62 
    63 static 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 
    68 static 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;
     64// static inline bool checkN( char c ) { return c == 'n' || c == 'N'; }
     65
     66void 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;
    7982                } 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
     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
     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
    95109
    96110Expression * build_constantInteger( string & str ) {
    97         static const BasicType::Kind kind[2][6] = {
    98                 // short (h) must be before char (hh)
     111        static const BasicType::Kind kind[2][7] = {
     112                // short (h) must be before char (hh) because shorter type has the longer suffix
    99113                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
    100114                { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },
    101115        };
    102116
    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
     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
    106121
    107122        unsigned long long int v;                                                       // converted integral value
    108123        size_t last = str.length() - 1;                                         // last subscript of constant
    109124        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
    110130
    111131        // special constants
     
    119139        } // if
    120140
    121         // Cannot be "0"
     141        // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate
    122142
    123143        if ( str[0] == '0' ) {                                                          // radix character ?
     
    127147                        //printf( "%llx %llu\n", v, v );
    128148                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    129                         v = 0;
    130                         for ( unsigned int i = 2;; i += 1 ) {           // compute value
     149                        v = 0;                                                                          // compute value
     150                        for ( unsigned int i = 2;; ) {                          // ignore prefix
    131151                                if ( str[i] == '1' ) v |= 1;
    132                           if ( i == last ) break;
     152                                i += 1;
     153                          if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
    133154                                v <<= 1;
    134155                        } // for
    135                         //printf( "%llx %llu\n", v, v );
     156                        //printf( "%#llx %llu\n", v, v );
    136157                } else {                                                                                // octal constant
    137158                        sscanf( (char *)str.c_str(), "%llo", &v );
    138                         //printf( "%llo %llu\n", v, v );
     159                        //printf( "%#llo %llu\n", v, v );
    139160                } // if
    140161        } else {                                                                                        // decimal constant ?
    141162                sscanf( (char *)str.c_str(), "%llu", &v );
    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;
     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
     209        // 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 ?
     212                // 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 ) );
    170221                        } // 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 );
    209         // Constant type is correct for overload resolving.
    210         ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
    211         if ( Unsigned && size < 2 ) {                                           // hh or h, less than int ?
    212                 // 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][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 
     222                } // if
     223        } // if
     224
     225  CLEANUP: ;
    224226        delete &str;                                                                            // created by lex
    225227        return ret;
     
    227229
    228230
    229 static inline void checkLNFloat( string & str, int & lnth, int & size ) {
    230         string::size_type posn = str.find_first_of( "lL" ), start = posn;
     231static 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
    231240  if ( posn == string::npos ) return;
    232         size = 2;                                                                                       // assume largest size
    233         lnth = 0;
     241        explnth = true;
    234242        posn += 1;                                                                                      // advance to size
    235243        if ( str[posn] == '3' ) {                                                       // 32
    236                 size = 0;
     244                if ( str[last] != 'x' ) type = 6;
     245                else type = 7;
    237246        } else if ( str[posn] == '6' ) {                                        // 64
    238                 size = 1;
    239         } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128
    240                 size = 2;
    241                 if ( str[posn] == '1' ) posn += 1;
     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
    242258        } else {
    243259                assertf( false, "internal error, bad floating point length %s", str.c_str() );
    244260        } // if
    245         posn += 1;
    246         str.erase( start, posn - start + 1 );                           // remove length suffix
    247 } // checkLNFloat
     261} // checkFnxFloat
    248262
    249263
    250264Expression * build_constantFloat( string & str ) {
    251         static const BasicType::Kind kind[2][3] = {
    252                 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
    253                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
     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 },
    254268        };
    255269
    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
     270        // floating-point constant has minimum of 2 characters 1. or .1
    260271        size_t last = str.length() - 1;
    261272        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
    262276
    263277        sscanf( str.c_str(), "%lg", &v );
     
    269283
    270284        if ( checkF( str[last] ) ) {                                            // float ?
    271                 size = 0;
     285                type = 0;
    272286        } else if ( checkD( str[last] ) ) {                                     // double ?
    273                 size = 1;
     287                type = 1;
    274288        } else if ( checkL( str[last] ) ) {                                     // long double ?
    275                 size = 2;
     289                type = 2;
     290        } else if ( checkF80( str[last] ) ) {                           // __float80 ?
     291                type = 3;
     292        } else if ( checkF128( str[last] ) ) {                          // __float128 ?
     293                type = 4;
    276294        } else {
    277                 size = 1;                                                                               // double (default)
    278                 checkLNFloat( str, lnth, size );
    279         } // if
     295                type = 1;                                                                               // double (default if no suffix)
     296                checkFnxFloat( str, last, explnth, type );
     297        } // if
     298
    280299        if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
    281300                complx = true;
    282301        } // if
    283302
    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 );
     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 );
    288307        } // if
    289308
  • src/Parser/ParseNode.h

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov  1 20:54:53 2018
    13 // Update Count     : 854
     12// Last Modified On : Mon Apr 15 14:22:39 2019
     13// Update Count     : 874
    1414//
    1515
     
    132132        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
    133133
    134         Expression *get_expr() const { return expr.get(); }
    135134        template<typename T>
    136135        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
    137136
    138137        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
     138
     139        std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
    139140  private:
    140141        bool extension = false;
    141         std::unique_ptr<Expression> expr;
    142142}; // ExpressionNode
    143143
     
    206206class DeclarationNode : public ParseNode {
    207207  public:
    208         // These enumerations must harmonize with their names.
    209         enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
     208        // These enumerations must harmonize with their names in DeclarationNode.cc.
     209        enum BasicType { Void, Bool, Char, Int, Int128,
     210                                         Float, Double, LongDouble, uuFloat80, uuFloat128,
     211                                         uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
    210212        static const char * basicTypeNames[];
    211         enum ComplexType { Complex, Imaginary, NoComplexType };
     213        enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
    212214        static const char * complexTypeNames[];
    213215        enum Signedness { Signed, Unsigned, NoSignedness };
  • src/Parser/TypeData.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov  2 07:54:26 2018
    13 // Update Count     : 624
     12// Last Modified On : Wed Feb 13 18:16:23 2019
     13// Update Count     : 649
    1414//
    1515
     
    666666
    667667          case DeclarationNode::Float:
    668           case DeclarationNode::Float80:
    669           case DeclarationNode::Float128:
    670668          case DeclarationNode::Double:
    671669          case DeclarationNode::LongDouble:                                     // not set until below
    672                 static BasicType::Kind floattype[3][3] = {
    673                         { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
    674                         { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary },
    675                         { BasicType::Float, BasicType::Double, BasicType::LongDouble },
     670          case DeclarationNode::uuFloat80:
     671          case DeclarationNode::uuFloat128:
     672          case DeclarationNode::uFloat16:
     673          case DeclarationNode::uFloat32:
     674          case DeclarationNode::uFloat32x:
     675          case DeclarationNode::uFloat64:
     676          case DeclarationNode::uFloat64x:
     677          case DeclarationNode::uFloat128:
     678          case DeclarationNode::uFloat128x:
     679                static BasicType::Kind floattype[2][12] = {
     680                        { 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, },
     681                        { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x, },
    676682                };
    677683
     
    686692                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
    687693                } // if
     694                if ( td->complextype == DeclarationNode::Imaginary ) {
     695                        genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
     696                } // if
     697                if ( (td->basictype == DeclarationNode::uuFloat80 || td->basictype == DeclarationNode::uuFloat128) && td->complextype == DeclarationNode::Complex ) { // gcc unsupported
     698                        genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
     699                } // if
    688700                if ( td->length == DeclarationNode::Long ) {
    689701                        const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
    690702                } // if
    691703
    692                 if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) {
    693                         // if ( td->complextype != DeclarationNode::NoComplexType ) {
    694                         //      genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
    695                         // }
    696                         if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80;
    697                         else ret = BasicType::Float128;
    698                         break;
    699                 }
    700 
    701704                ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
     705                //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, DeclarationNode::Float, ret );
    702706                break;
    703707
  • src/Parser/TypeData.h

    r6a9d4b4 r933f32f  
    3131        struct Aggregate_t {
    3232                DeclarationNode::Aggregate kind;
    33                 const std::string * name;
    34                 DeclarationNode * params;
    35                 ExpressionNode * actuals;                                               // holds actual parameters later applied to AggInst
    36                 DeclarationNode * fields;
     33                const std::string * name = nullptr;
     34                DeclarationNode * params = nullptr;
     35                ExpressionNode * actuals = nullptr;                                             // holds actual parameters later applied to AggInst
     36                DeclarationNode * fields = nullptr;
    3737                bool body;
    3838                bool anon;
    3939
    4040                bool tagged;
    41                 const std::string * parent;
     41                const std::string * parent = nullptr;
    4242        };
    4343
    4444        struct AggInst_t {
    45                 TypeData * aggregate;
    46                 ExpressionNode * params;
     45                TypeData * aggregate = nullptr;
     46                ExpressionNode * params = nullptr;
    4747                bool hoistType;
    4848        };
    4949
    5050        struct Array_t {
    51                 ExpressionNode * dimension;
     51                ExpressionNode * dimension = nullptr;
    5252                bool isVarLen;
    5353                bool isStatic;
     
    5555
    5656        struct Enumeration_t {
    57                 const std::string * name;
    58                 DeclarationNode * constants;
     57                const std::string * name = nullptr;
     58                DeclarationNode * constants = nullptr;
    5959                bool body;
    6060                bool anon;
     
    6262
    6363        struct Function_t {
    64                 mutable DeclarationNode * params;                               // mutables modified in buildKRFunction
    65                 mutable DeclarationNode * idList;                               // old-style
    66                 mutable DeclarationNode * oldDeclList;
    67                 StatementNode * body;
    68                 ExpressionNode * withExprs;                                             // expressions from function's with_clause
     64                mutable DeclarationNode * params = nullptr;                             // mutables modified in buildKRFunction
     65                mutable DeclarationNode * idList = nullptr;                             // old-style
     66                mutable DeclarationNode * oldDeclList = nullptr;
     67                StatementNode * body = nullptr;
     68                ExpressionNode * withExprs = nullptr;                                           // expressions from function's with_clause
    6969        };
    7070
    7171        struct Symbolic_t {
    72                 const std::string * name;
     72                const std::string * name = nullptr;
    7373                bool isTypedef;                                                                 // false => TYPEGENname, true => TYPEDEFname
    74                 DeclarationNode * params;
    75                 ExpressionNode * actuals;
    76                 DeclarationNode * assertions;
     74                DeclarationNode * params = nullptr;
     75                ExpressionNode * actuals = nullptr;
     76                DeclarationNode * assertions = nullptr;
    7777        };
    7878
    7979        struct Qualified_t {                                                            // qualified type S.T
    80                 TypeData * parent;
    81                 TypeData * child;
     80                TypeData * parent = nullptr;
     81                TypeData * child = nullptr;
    8282        };
    8383
     
    9393
    9494        Type::Qualifiers qualifiers;
    95         DeclarationNode * forall;
     95        DeclarationNode * forall = nullptr;
    9696
    9797        Aggregate_t aggregate;
     
    102102        Symbolic_t symbolic;
    103103        Qualified_t qualified;
    104         DeclarationNode * tuple;
    105         ExpressionNode * typeexpr;
     104        DeclarationNode * tuple = nullptr;
     105        ExpressionNode * typeexpr = nullptr;
    106106
    107107        TypeData( Kind k = Unknown );
  • src/Parser/lex.ll

    r6a9d4b4 r933f32f  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Nov  1 20:57:35 2018
    13  * Update Count     : 687
     12 * Last Modified On : Wed May 15 21:25:27 2019
     13 * Update Count     : 708
    1414 */
    1515
     
    3939using namespace std;
    4040
     41#include "config.h"                                                                             // configure info
    4142#include "ParseNode.h"
    4243#include "TypedefTable.h"
     
    5960#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    6061#define ATTRIBUTE_RETURN()      RETURN_VAL( ATTR_IDENTIFIER )
     62
     63#ifdef HAVE_KEYWORDS_FLOATXX                                                            // GCC >= 7 => keyword, otherwise typedef
     64#define FLOATXX(v) KEYWORD_RETURN(v);
     65#else
     66#define FLOATXX(v) IDENTIFIER_RETURN();
     67#endif // HAVE_KEYWORDS_FLOATXX
    6168
    6269void rm_underscore() {
     
    9299hex_quad {hex}("_"?{hex}){3}
    93100size_opt (8|16|32|64|128)?
    94 length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hH])
    95 integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))?
     101                                // CFA: explicit l8/l16/l32/l64/l128, char 'hh', short 'h', int 'n'
     102length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hHnN])
     103                                // CFA: size_t 'z', pointer 'p', which define a sign and length
     104integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]|[pP]))?
    96105
    97106octal_digits ({octal})|({octal}({octal}|"_")*{octal})
     
    112121                                // GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
    113122exponent "_"?[eE]"_"?[+-]?{decimal_digits}
    114 floating_size 32|64|80|128
    115 floating_length ([fFdDlL]|[lL]{floating_size})
     123floating_size 16|32|32x|64|64x|80|128|128x
     124floating_length ([fFdDlLwWqQ]|[fF]{floating_size})
    116125floating_suffix ({floating_length}?[iI]?)|([iI]{floating_length})
    117126floating_suffix_opt ("_"?({floating_suffix}|"DL"))?
     
    217226char                    { KEYWORD_RETURN(CHAR); }
    218227choose                  { KEYWORD_RETURN(CHOOSE); }                             // CFA
     228coerce                  { KEYWORD_RETURN(COERCE); }                             // CFA
    219229_Complex                { KEYWORD_RETURN(COMPLEX); }                    // C99
    220230__complex               { KEYWORD_RETURN(COMPLEX); }                    // GCC
     
    240250finally                 { KEYWORD_RETURN(FINALLY); }                    // CFA
    241251float                   { KEYWORD_RETURN(FLOAT); }
    242 _Float32                { KEYWORD_RETURN(FLOAT); }                              // GCC
    243 _Float32x               { KEYWORD_RETURN(FLOAT); }                              // GCC
    244 _Float64                { KEYWORD_RETURN(DOUBLE); }                             // GCC
    245 _Float64x               { KEYWORD_RETURN(DOUBLE); }                             // GCC
    246 __float80               { KEYWORD_RETURN(FLOAT80); }                    // GCC
    247 float80                 { KEYWORD_RETURN(FLOAT80); }                    // GCC
    248 _Float128               { KEYWORD_RETURN(FLOAT128); }                   // GCC
    249 _Float128x              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    250 __float128              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    251 float128                { KEYWORD_RETURN(FLOAT128); }                   // GCC
     252__float80               { KEYWORD_RETURN(uuFLOAT80); }                  // GCC
     253float80                 { KEYWORD_RETURN(uuFLOAT80); }                  // GCC
     254__float128              { KEYWORD_RETURN(uuFLOAT128); }                 // GCC
     255float128                { KEYWORD_RETURN(uuFLOAT128); }                 // GCC
     256_Float16                { FLOATXX(uFLOAT16); }                                  // GCC
     257_Float32                { FLOATXX(uFLOAT32); }                                  // GCC
     258_Float32x               { FLOATXX(uFLOAT32X); }                                 // GCC
     259_Float64                { FLOATXX(uFLOAT64); }                                  // GCC
     260_Float64x               { FLOATXX(uFLOAT64X); }                                 // GCC
     261_Float128               { FLOATXX(uFLOAT128); }                                 // GCC
     262_Float128x              { FLOATXX(uFLOAT128); }                                 // GCC
    252263for                             { KEYWORD_RETURN(FOR); }
    253264forall                  { KEYWORD_RETURN(FORALL); }                             // CFA
    254265fortran                 { KEYWORD_RETURN(FORTRAN); }
    255266ftype                   { KEYWORD_RETURN(FTYPE); }                              // CFA
     267generator               { KEYWORD_RETURN(GENERATOR); }                  // CFA
    256268_Generic                { KEYWORD_RETURN(GENERIC); }                    // C11
    257269goto                    { KEYWORD_RETURN(GOTO); }
  • src/Parser/module.mk

    r6a9d4b4 r933f32f  
    3131       Parser/parserutility.cc
    3232
     33SRCDEMANGLE += \
     34        Parser/LinkageSpec.cc
     35
     36
    3337MOSTLYCLEANFILES += Parser/lex.cc Parser/parser.cc Parser/parser.hh Parser/parser.output
  • src/Parser/parser.yy

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov  8 18:08:23 2018
    13 // Update Count     : 4052
     12// Last Modified On : Wed May 15 21:25:27 2019
     13// Update Count     : 4296
    1414//
    1515
     
    9999        // distribute declaration_specifier across all declared variables, e.g., static, const, __attribute__.
    100100        DeclarationNode * cur = declList, * cl = (new DeclarationNode)->addType( specifier );
    101         //cur->addType( specifier );
    102         for ( cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
     101        for ( cur = dynamic_cast<DeclarationNode *>( cur->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) {
    103102                cl->cloneBaseType( cur );
    104103        } // for
    105104        declList->addType( cl );
    106 //      delete cl;
    107105        return declList;
    108106} // distAttr
     
    175173DeclarationNode * fieldDecl( DeclarationNode * typeSpec, DeclarationNode * fieldList ) {
    176174        if ( ! fieldList ) {                                                            // field declarator ?
    177                 if ( ! ( typeSpec->type && typeSpec->type->kind == TypeData::Aggregate ) ) {
     175                if ( ! ( typeSpec->type && (typeSpec->type->kind == TypeData::Aggregate || typeSpec->type->kind == TypeData::Enum) ) ) {
    178176                        stringstream ss;
    179177                        typeSpec->type->print( ss );
     
    187185
    188186ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    189         ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->get_expr());
     187        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
    190188        if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
    191189        type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
     
    193191        return new ForCtrl(
    194192                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
    195                 new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ),
    196                 new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    197                                                                                           OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) );
     193                // NULL comp/inc => leave blank
     194                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,
     195                inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
     196                                                        OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0 );
    198197} // forCtrl
    199198
    200199ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    201         if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->get_expr()) ) {
     200        if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {
    202201                return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     202        } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {
     203                if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) {
     204                        return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     205                } else {
     206                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr;
     207                } // if
    203208        } else {
    204209                SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr;
     
    260265%token RESTRICT                                                                                 // C99
    261266%token ATOMIC                                                                                   // C11
    262 %token FORALL MUTEX VIRTUAL                                                             // CFA
     267%token FORALL MUTEX VIRTUAL COERCE                                              // CFA
    263268%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
    264269%token BOOL COMPLEX IMAGINARY                                                   // C99
    265 %token INT128 FLOAT80 FLOAT128                                                  // GCC
     270%token INT128 uuFLOAT80 uuFLOAT128                                              // GCC
     271%token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC
    266272%token ZERO_T ONE_T                                                                             // CFA
    267273%token VALIST                                                                                   // GCC
     
    269275%token ENUM STRUCT UNION
    270276%token EXCEPTION                                                                                // CFA
    271 %token COROUTINE MONITOR THREAD                                                 // CFA
     277%token GENERATOR COROUTINE MONITOR THREAD                               // CFA
    272278%token OTYPE FTYPE DTYPE TTYPE TRAIT                                    // CFA
    273279%token SIZEOF OFFSETOF
     
    324330%type<en> argument_expression_list              argument_expression                     default_initialize_opt
    325331%type<ifctl> if_control_expression
    326 %type<fctl> for_control_expression
     332%type<fctl> for_control_expression              for_control_expression_list
    327333%type<compop> inclexcl
    328334%type<en> subrange
    329335%type<decl> asm_name_opt
    330 %type<en> asm_operands_opt asm_operands_list asm_operand
     336%type<en> asm_operands_opt                              asm_operands_list                       asm_operand
    331337%type<label> label_list
    332338%type<en> asm_clobbers_list_opt
    333339%type<flag> asm_volatile_opt
    334340%type<en> handler_predicate_opt
    335 %type<genexpr> generic_association generic_assoc_list
     341%type<genexpr> generic_association              generic_assoc_list
    336342
    337343// statements
     
    671677        // empty
    672678                { $$ = nullptr; }
    673         | '?'                                                                                           // CFA, default parameter
     679        | '@'                                                                                           // CFA, default parameter
    674680                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
    675681                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
     
    789795        | '(' type_no_function ')' cast_expression
    790796                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     797                // keyword cast cannot be grouped because of reduction in aggregate_key
     798        | '(' GENERATOR '&' ')' cast_expression                         // CFA
     799                { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
    791800        | '(' COROUTINE '&' ')' cast_expression                         // CFA
    792801                { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
     
    800809        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    801810                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); }
     811        | '(' RETURN type_no_function ')' cast_expression       // CFA
     812                { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
     813        | '(' COERCE type_no_function ')' cast_expression       // CFA
     814                { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
     815        | '(' qualifier_cast_list ')' cast_expression           // CFA
     816                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    802817//      | '(' type_no_function ')' tuple
    803818//              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     819        ;
     820
     821qualifier_cast_list:
     822        cast_modifier type_qualifier_name
     823        | cast_modifier MUTEX
     824        | qualifier_cast_list cast_modifier type_qualifier_name
     825        | qualifier_cast_list cast_modifier MUTEX
     826        ;
     827
     828cast_modifier:
     829        '-'
     830        | '+'
    804831        ;
    805832
     
    9841011                // labels cannot be identifiers 0 or 1 or ATTR_IDENTIFIER
    9851012        identifier_or_type_name ':' attribute_list_opt statement
    986                 {
    987                         $$ = $4->add_label( $1, $3 );
    988                 }
     1013                { $$ = $4->add_label( $1, $3 ); }
    9891014        ;
    9901015
     
    10021027        statement_decl
    10031028        | statement_decl_list statement_decl
    1004                 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
     1029                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
    10051030        ;
    10061031
     
    10091034                { $$ = new StatementNode( $1 ); }
    10101035        | EXTENSION declaration                                                         // GCC
    1011                 {
    1012                         distExt( $2 );
    1013                         $$ = new StatementNode( $2 );
    1014                 }
     1036                { distExt( $2 ); $$ = new StatementNode( $2 ); }
    10151037        | function_definition
    10161038                { $$ = new StatementNode( $1 ); }
    10171039        | EXTENSION function_definition                                         // GCC
    1018                 {
    1019                         distExt( $2 );
    1020                         $$ = new StatementNode( $2 );
    1021                 }
     1040                { distExt( $2 ); $$ = new StatementNode( $2 ); }
    10221041        | statement
    10231042        ;
     
    10261045        statement
    10271046        | statement_list_nodecl statement
    1028                 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
     1047                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
    10291048        ;
    10301049
     
    11381157        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    11391158                { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), $2 ) ); }
    1140         | FOR '(' push for_control_expression ')' statement pop
     1159        | FOR '(' push for_control_expression_list ')' statement pop
    11411160                { $$ = new StatementNode( build_for( $4, $6 ) ); }
    11421161        | FOR '(' ')' statement                                                         // CFA => for ( ;; )
     
    11441163        ;
    11451164
     1165for_control_expression_list:
     1166        for_control_expression
     1167        | for_control_expression_list ':' for_control_expression
     1168                // ForCtrl + ForCtrl:
     1169                //    init + init => multiple declaration statements that are hoisted
     1170                //    condition + condition => (expression) && (expression)
     1171                //    change + change => (expression), (expression)
     1172                {
     1173                        $1->init->set_last( $3->init );
     1174                        if ( $1->condition ) {
     1175                                if ( $3->condition ) {
     1176                                        $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
     1177                                } // if
     1178                        } else $1->condition = $3->condition;
     1179                        if ( $1->change ) {
     1180                                if ( $3->change ) {
     1181                                        $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
     1182                                } // if
     1183                        } else $1->change = $3->change;
     1184                        $$ = $1;
     1185                }
     1186        ;
     1187
    11461188for_control_expression:
    1147         comma_expression                                                                        // CFA
     1189        ';' comma_expression_opt ';' comma_expression_opt
     1190                { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
     1191        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
     1192                { $$ = new ForCtrl( $1, $3, $5 ); }
     1193        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
     1194                { $$ = new ForCtrl( $1, $2, $4 ); }
     1195
     1196        | comma_expression                                                                      // CFA
    11481197                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    11491198                                                OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1150         | constant_expression inclexcl constant_expression      // CFA
     1199        | comma_expression inclexcl comma_expression            // CFA
    11511200                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1152         | constant_expression inclexcl constant_expression '~' constant_expression // CFA
     1201        | comma_expression inclexcl comma_expression '~' comma_expression // CFA
    11531202                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); }
    11541203        | comma_expression ';' comma_expression                         // CFA
    11551204                { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    11561205                                                OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1157         | comma_expression ';' constant_expression inclexcl constant_expression // CFA
     1206        | comma_expression ';' comma_expression inclexcl comma_expression // CFA
    11581207                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1159         | comma_expression ';' constant_expression inclexcl constant_expression '~' constant_expression // CFA
     1208        | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
    11601209                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
    1161         | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    1162                 { $$ = new ForCtrl( $1, $3, $5 ); }
    1163         | ';' comma_expression_opt ';' comma_expression_opt
    1164                 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
    1165         | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    1166                 { $$ = new ForCtrl( $1, $2, $4 ); }
     1210
     1211                // There is a S/R conflicit if ~ and -~ are factored out.
     1212        | comma_expression ';' comma_expression '~' '@'         // CFA
     1213                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1214        | comma_expression ';' comma_expression ErangeDown '@' // CFA
     1215                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1216        | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
     1217                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
     1218        | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA
     1219                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); }
     1220        | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA
     1221                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); }
    11671222        ;
    11681223
     
    17711826        | FLOAT
    17721827                { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
    1773         | FLOAT80
    1774                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float80 ); }
    1775         | FLOAT128
    1776                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float128 ); }
    17771828        | DOUBLE
    17781829                { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
     1830        | uuFLOAT80
     1831                { $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat80 ); }
     1832        | uuFLOAT128
     1833                { $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat128 ); }
     1834        | uFLOAT16
     1835                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat16 ); }
     1836        | uFLOAT32
     1837                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32 ); }
     1838        | uFLOAT32X
     1839                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32x ); }
     1840        | uFLOAT64
     1841                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64 ); }
     1842        | uFLOAT64X
     1843                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64x ); }
     1844        | uFLOAT128
     1845                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat128 ); }
    17791846        | COMPLEX                                                                                       // C99
    17801847                { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); }
     
    19962063        | EXCEPTION
    19972064                { yyy = true; $$ = DeclarationNode::Exception; }
     2065        | GENERATOR
     2066                { yyy = true; $$ = DeclarationNode::Coroutine; }
    19982067        | COROUTINE
    19992068                { yyy = true; $$ = DeclarationNode::Coroutine; }
Note: See TracChangeset for help on using the changeset viewer.