Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    r0bd46fd r7991c7d  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug 27 13:21:28 2022
    13 // Update Count     : 5661
     12// Last Modified On : Fri Jul  1 15:35:08 2022
     13// Update Count     : 5405
    1414//
    1515
     
    5858
    5959// lex uses __null in a boolean context, it's fine.
    60 #ifdef __clang__
    6160#pragma GCC diagnostic ignored "-Wparentheses-equality"
    62 #endif
    6361
    6462extern DeclarationNode * parseTree;
     
    199197} // fieldDecl
    200198
    201 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
    202 #define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
    203 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    204 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
    205 #define MISSING_LOW "Missing low value for up-to range so index is uninitialized."
    206 #define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
    207 
    208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    209         if ( index->initializer ) {
    210                 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
    211         } // if
    212         if ( index->next ) {
    213                 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
    214         } // if
    215         return new ForCtrl( index->addInitializer( new InitializerNode( start ) ),
    216                 // NULL comp/inc => leave blank
    217                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr,
    218                 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    219                                                         OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr );
    220 } // forCtrl
    221 
    222199ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    223200        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
     
    229206                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
    230207                // NULL comp/inc => leave blank
    231                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr,
     208                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,
    232209                inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    233                                                         OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr );
     210                                                        OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0 );
    234211} // forCtrl
    235212
     
    295272%token TYPEDEF
    296273%token EXTERN STATIC AUTO REGISTER
    297 %token THREADLOCALGCC THREADLOCALC11                                            // GCC, C11
     274%token THREADLOCAL                                                                              // C11
    298275%token INLINE FORTRAN                                                                   // C99, extension ISO/IEC 9899:1999 Section J.5.9(1)
    299276%token NORETURN                                                                                 // C11
     
    369346%type<ifctl> conditional_declaration
    370347%type<fctl> for_control_expression              for_control_expression_list
    371 %type<compop> updown updowneq downupdowneq
     348%type<compop> inclexcl
    372349%type<en> subrange
    373350%type<decl> asm_name_opt
     
    637614                { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }
    638615        | type_name '.' identifier                                                      // CFA, nested type
    639                 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
     616                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    640617        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    641618                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    12621239iteration_statement:
    12631240        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1264                 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
     1241                { $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); }
    12651242        | WHILE '(' ')' statement ELSE statement                        // CFA
    12661243                {
    1267                         $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
     1244                        $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) );
    12681245                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12691246                }
     
    12731250                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
    12741251        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1275                 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
     1252                { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }
    12761253        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    12771254                {
    1278                         $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
     1255                        $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );
    12791256                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12801257                }
     
    13271304                { $$ = new ForCtrl( $1, $2, $4 ); }
    13281305
    1329         | '@' ';' comma_expression                                                      // CFA, empty loop-index
    1330                 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }
    1331         | '@' ';' comma_expression ';' comma_expression         // CFA, empty loop-index
    1332                 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }
    1333 
    1334         | comma_expression                                                                      // CFA, anonymous loop-index
    1335                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
    1336         | downupdowneq comma_expression                                         // CFA, anonymous loop-index
    1337                 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
    1338 
    1339         | comma_expression updowneq comma_expression            // CFA, anonymous loop-index
    1340                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
    1341         | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
    1342                 {
    1343                         if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1344                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
    1345                 }
    1346         | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
    1347                 {
    1348                         if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1349                         else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1350                 }
    1351         | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    1352                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
    1353         | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    1354                 {
    1355                         if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1356                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
    1357                 }
    1358         | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
    1359                 {
    1360                         if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1361                         else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1362                 }
    1363         | comma_expression updowneq comma_expression '~' '@' // CFA, error
    1364                 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1365         | '@' updowneq '@'                                                                      // CFA, error
    1366                 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1367         | '@' updowneq comma_expression '~' '@'                         // CFA, error
    1368                 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1369         | comma_expression updowneq '@' '~' '@'                         // CFA, error
    1370                 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1371         | '@' updowneq '@' '~' '@'                                                      // CFA, error
    1372                 { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1373 
     1306        | comma_expression                                                                      // CFA
     1307                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1308                                                OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1309        | '=' comma_expression                                                          // CFA
     1310                { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1311                                                OperKinds::LEThan, $2->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1312        | comma_expression inclexcl comma_expression            // CFA
     1313                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1314        | comma_expression inclexcl comma_expression '~' comma_expression // CFA
     1315                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); }
     1316        | comma_expression ';'                                                          // CFA
     1317                { $$ = forCtrl( new ExpressionNode( build_constantInteger( *new string( "0u" ) ) ), $1, nullptr, OperKinds::LThan, nullptr, nullptr ); }
    13741318        | comma_expression ';' comma_expression                         // CFA
    1375                 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    1376         | comma_expression ';' downupdowneq comma_expression // CFA
    1377                 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
    1378 
    1379         | comma_expression ';' comma_expression updowneq comma_expression // CFA
    1380                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
    1381         | comma_expression ';' '@' updowneq comma_expression // CFA
    1382                 {
    1383                         if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1384                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    1385                 }
    1386         | comma_expression ';' comma_expression updowneq '@' // CFA
    1387                 {
    1388                         if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1389                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1390                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    1391                 }
    1392         | comma_expression ';' '@' updowneq '@'                         // CFA, error
    1393                 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    1394 
    1395         | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    1396                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    1397         | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
    1398                 {
    1399                         if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1400                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
    1401                 }
    1402         | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
    1403                 {
    1404                         if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1405                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1406                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
    1407                 }
    1408         | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    1409                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    1410         | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
    1411                 {
    1412                         if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1413                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
    1414                 }
    1415         | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
    1416                 {
    1417                         if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1418                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1419                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
    1420                 }
    1421         | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
    1422                 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    1423 
    1424         | declaration comma_expression                                          // CFA
    1425                 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    1426         | declaration downupdowneq comma_expression                     // CFA
    1427                 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
    1428 
    1429         | declaration comma_expression updowneq comma_expression // CFA
    1430                 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
    1431         | declaration '@' updowneq comma_expression                     // CFA
    1432                 {
    1433                         if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1434                         else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
    1435                 }
    1436         | declaration comma_expression updowneq '@'                     // CFA
    1437                 {
    1438                         if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1439                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1440                         else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
    1441                 }
    1442 
    1443         | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1444                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
    1445         | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    1446                 {
    1447                         if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1448                         else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
    1449                 }
    1450         | declaration comma_expression updowneq '@' '~' comma_expression // CFA
    1451                 {
    1452                         if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1453                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1454                         else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
    1455                 }
    1456         | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1457                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
    1458         | declaration '@' updowneq comma_expression '~' '@' // CFA
    1459                 {
    1460                         if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1461                         else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
    1462                 }
    1463         | declaration comma_expression updowneq '@' '~' '@'     // CFA
    1464                 {
    1465                         if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1466                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1467                         else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
    1468                 }
    1469         | declaration '@' updowneq '@' '~' '@'                          // CFA, error
    1470                 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1319                { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1320                                                OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1321        | comma_expression ';' '=' comma_expression                     // CFA
     1322                { $$ = forCtrl( $4, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1323                                                OperKinds::LEThan, $4->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1324        | comma_expression ';' comma_expression inclexcl comma_expression // CFA
     1325                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1326        | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
     1327                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
    14711328
    14721329        | comma_expression ';' TYPEDEFname                                      // CFA, array type
    14731330                {
    1474                         SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    1475                         //$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
    1476                 }
    1477         | comma_expression ';' downupdowneq TYPEDEFname         // CFA, array type
    1478                 {
    1479                         if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; }
    1480                         SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    1481                 }
     1331                        SemanticError( yylloc, "Array interator is currently unimplemented." ); $$ = nullptr;
     1332                        $$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
     1333                }
     1334
     1335                // There is a S/R conflicit if ~ and -~ are factored out.
     1336        | comma_expression ';' comma_expression '~' '@'         // CFA
     1337                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1338        | comma_expression ';' comma_expression ErangeDown '@' // CFA
     1339                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1340        | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
     1341                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
     1342        | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA
     1343                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); }
     1344        | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA
     1345                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); }
    14821346        ;
    14831347
    1484 downupdowneq:
    1485         ErangeDown
    1486                 { $$ = OperKinds::GThan; }
     1348inclexcl:
     1349        '~'
     1350                { $$ = OperKinds::LThan; }
    14871351        | ErangeUpEq
    14881352                { $$ = OperKinds::LEThan; }
    1489         | ErangeDownEq
    1490                 { $$ = OperKinds::GEThan; }
    1491         ;
    1492 
    1493 updown:
    1494         '~'
    1495                 { $$ = OperKinds::LThan; }
    14961353        | ErangeDown
    14971354                { $$ = OperKinds::GThan; }
    1498         ;
    1499 
    1500 updowneq:
    1501         updown
    1502         | ErangeUpEq
    1503                 { $$ = OperKinds::LEThan; }
    15041355        | ErangeDownEq
    15051356                { $$ = OperKinds::GEThan; }
     
    20841935        | REGISTER
    20851936                { $$ = DeclarationNode::newStorageClass( Type::Register ); }
    2086         | THREADLOCALGCC                                                                                // GCC
    2087                 { $$ = DeclarationNode::newStorageClass( Type::ThreadlocalGcc ); }
    2088         | THREADLOCALC11                                                                                // C11
    2089                 { $$ = DeclarationNode::newStorageClass( Type::ThreadlocalC11 ); }
     1937        | THREADLOCAL                                                                           // C11
     1938                { $$ = DeclarationNode::newStorageClass( Type::Threadlocal ); }
    20901939                // Put function specifiers here to simplify parsing rules, but separate them semantically.
    20911940        | INLINE                                                                                        // C99
     
    25382387enum_type:
    25392388        ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
    2540                 { $$ = DeclarationNode::newEnum( nullptr, $4, true, false )->addQualifiers( $2 ); }
     2389                { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }
    25412390        | ENUM attribute_list_opt identifier
    25422391                { typedefTable.makeTypedef( *$3 ); }
    25432392          '{' enumerator_list comma_opt '}'
    2544                 { $$ = DeclarationNode::newEnum( $3, $6, true, false )->addQualifiers( $2 ); }
     2393                { $$ = DeclarationNode::newEnum( $3, $6, true )->addQualifiers( $2 ); }
    25452394        | ENUM attribute_list_opt typedef_name                          // unqualified type name
    25462395          '{' enumerator_list comma_opt '}'
    2547                 { $$ = DeclarationNode::newEnum( $3->name, $5, true, false )->addQualifiers( $2 ); }
     2396                { $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); }
    25482397        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    25492398                {
     
    25512400                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    25522401
    2553                         $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 );
    2554                 }
    2555         | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2556                 {
    2557                         $$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 );
     2402                        $$ = DeclarationNode::newEnum( nullptr, $7, true, $3 )->addQualifiers( $5 );
    25582403                }
    25592404        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
     
    25642409          '{' enumerator_list comma_opt '}'
    25652410                {
    2566                         $$ = DeclarationNode::newEnum( $6, $10, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
    2567                 }
    2568         | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt
    2569           '{' enumerator_list comma_opt '}'
    2570                 {
    2571                         $$ = DeclarationNode::newEnum( $5, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );
     2411                        $$ = DeclarationNode::newEnum( $6, $10, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
    25722412                }
    25732413        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}'
    25742414                {
    2575                         $$ = DeclarationNode::newEnum( $6->name, $9, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
    2576                 }
    2577         | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}'
    2578                 {
    2579                         $$ = DeclarationNode::newEnum( $5->name, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );
     2415                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
     2416                        typedefTable.makeTypedef( *$6->name );
     2417                        $$ = DeclarationNode::newEnum( $6->name, $9, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
    25802418                }
    25812419        | enum_type_nobody
     
    25842422enum_type_nobody:                                                                               // enum - {...}
    25852423        ENUM attribute_list_opt identifier
    2586                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
    2587         | ENUM attribute_list_opt type_name
    2588                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
     2424                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 ); }
     2425        | ENUM attribute_list_opt type_name                                     // qualified type name
     2426                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 ); }
    25892427        ;
    25902428
Note: See TracChangeset for help on using the changeset viewer.