Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    r35718a9 r3ed994e  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 30 20:29:03 2018
    13 // Update Count     : 3432
     12// Last Modified On : Tue May 22 08:41:57 2018
     13// Update Count     : 3353
    1414//
    1515
     
    175175        bool flag;
    176176        CatchStmt::Kind catch_kind;
     177        GenericExpr * genexpr;
    177178}
    178179
     
    259260%type<flag> asm_volatile_opt
    260261%type<en> handler_predicate_opt
     262%type<genexpr> generic_association generic_assoc_list
    261263
    262264// statements
     
    324326%type<decl> cfa_identifier_parameter_declarator_tuple cfa_identifier_parameter_ptr
    325327
    326 %type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_ellipsis_list_opt
     328%type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_type_list_opt
    327329
    328330%type<decl> cfa_typedef_declaration cfa_variable_declaration cfa_variable_specifier
     
    330332%type<decl> c_declaration static_assert
    331333%type<decl> KR_function_declarator KR_function_no_ptr KR_function_ptr KR_function_array
    332 %type<decl> KR_parameter_list KR_parameter_list_opt
     334%type<decl> KR_declaration_list KR_declaration_list_opt
    333335
    334336%type<decl> parameter_declaration parameter_list parameter_type_list_opt
     
    501503                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    502504        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    503                 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
     505                {
     506                        // add the missing control expression to the GenericExpr and return it
     507                        $5->control = maybeMoveBuild<Expression>( $3 );
     508                        $$ = new ExpressionNode( $5 );
     509                }
    504510        ;
    505511
    506512generic_assoc_list:                                                                             // C11
    507         | generic_association
     513        generic_association
    508514        | generic_assoc_list ',' generic_association
     515                {
     516                        // steal the association node from the singleton and delete the wrapper
     517                        $1->associations.splice($1->associations.end(), $3->associations);
     518                        delete $3;
     519                        $$ = $1;
     520                }
    509521        ;
    510522
    511523generic_association:                                                                    // C11
    512524        type_no_function ':' assignment_expression
     525                {
     526                        // create a GenericExpr wrapper with one association pair
     527                        $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>($3) } } );
     528                }
    513529        | DEFAULT ':' assignment_expression
     530                { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>($3) } } ); }
    514531        ;
    515532
     
    835852//      '[' ']'
    836853//              { $$ = new ExpressionNode( build_tuple() ); }
    837 //      | '[' push assignment_expression pop ']'
     854//      '[' push assignment_expression pop ']'
    838855//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    839856        '[' ',' tuple_expression_list ']'
    840857                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    841         | '[' push assignment_expression pop ',' tuple_expression_list ']'
    842                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $6 ) ) ); }
     858        | '[' assignment_expression ',' tuple_expression_list ']'
     859                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$2->set_last( $4 ) ) ); }
    843860        ;
    844861
     
    866883        labeled_statement
    867884        | compound_statement
    868         | expression_statement
     885        | expression_statement                                          { $$ = $1; }
    869886        | selection_statement
    870887        | iteration_statement
     
    892909        '{' '}'
    893910                { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
    894         | '{' push
     911        | '{'
     912                // Two scopes are necessary because the block itself has a scope, but every declaration within the block also
     913                // requires its own scope.
     914          push push
    895915          local_label_declaration_opt                                           // GCC, local labels
    896916          statement_decl_list                                                           // C99, intermix declarations and statements
    897917          pop '}'
    898                 { $$ = new StatementNode( build_compound( $4 ) ); }
     918                { $$ = new StatementNode( build_compound( $5 ) ); }
    899919        ;
    900920
    901921statement_decl_list:                                                                    // C99
    902922        statement_decl
    903         | statement_decl_list statement_decl
    904                 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
     923        | statement_decl_list push statement_decl
     924                { if ( $1 != 0 ) { $1->set_last( $3 ); $$ = $1; } }
    905925        ;
    906926
     
    920940                        $$ = new StatementNode( $2 );
    921941                }
    922         | statement
     942        | statement pop
    923943        ;
    924944
     
    935955
    936956selection_statement:
    937         IF '(' push if_control_expression ')' statement pop             %prec THEN
     957        IF '(' push if_control_expression ')' statement         %prec THEN
    938958                // explicitly deal with the shift/reduce conflict on if/else
    939959                { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); }
    940         | IF '(' push if_control_expression ')' statement ELSE statement pop
     960        | IF '(' push if_control_expression ')' statement ELSE statement
    941961                { $$ = new StatementNode( build_if( $4, $6, $8 ) ); }
    942962        | SWITCH '(' comma_expression ')' case_clause
    943963                { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
    944         | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
     964        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
    945965                {
    946966                        StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
     
    954974        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    955975                { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
    956         | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
     976        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
    957977                {
    958978                        StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );
     
    962982
    963983if_control_expression:
    964         comma_expression
     984        comma_expression pop
    965985                { $$ = new IfCtl( nullptr, $1 ); }
    966         | c_declaration                                                                         // no semi-colon
     986        | c_declaration pop                                                                     // no semi-colon
    967987                { $$ = new IfCtl( $1, nullptr ); }
    968         | cfa_declaration                                                                       // no semi-colon
     988        | cfa_declaration pop                                                           // no semi-colon
    969989                { $$ = new IfCtl( $1, nullptr ); }
    970990        | declaration comma_expression                                          // semi-colon separated
     
    10271047        | DO statement WHILE '(' comma_expression ')' ';'
    10281048                { $$ = new StatementNode( build_while( $5, $2, true ) ); }
    1029         | FOR '(' push for_control_expression ')' statement pop
     1049        | FOR '(' push for_control_expression ')' statement
    10301050                { $$ = new StatementNode( build_for( $4, $6 ) ); }
    10311051        ;
    10321052
    10331053for_control_expression:
    1034         comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt
    1035                 { $$ = new ForCtl( $1, $3, $5 ); }
     1054        comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt
     1055                { $$ = new ForCtl( $1, $4, $6 ); }
    10361056        | declaration comma_expression_opt ';' comma_expression_opt // C99
    10371057                { $$ = new ForCtl( $1, $2, $4 ); }
     
    11801200        type_specifier_nobody
    11811201        | type_specifier_nobody declarator
    1182                 { $$ = $2->addType( $1 ); }
     1202                {
     1203                        $$ = $2->addType( $1 );
     1204                }
    11831205        | type_specifier_nobody variable_abstract_declarator
    11841206                { $$ = $2->addType( $1 ); }
    11851207        | cfa_abstract_declarator_tuple no_attr_identifier      // CFA
    1186                 { $$ = $1->addName( $2 ); }
     1208                {
     1209                        $$ = $1->addName( $2 );
     1210                }
    11871211        | cfa_abstract_declarator_tuple                                         // CFA
    11881212        ;
     
    12621286
    12631287declaration_list_opt:                                                                   // used at beginning of switch statement
     1288        pop
     1289                { $$ = nullptr; }
     1290        | declaration_list
     1291        ;
     1292
     1293declaration_list:
     1294        declaration
     1295        | declaration_list push declaration
     1296                { $$ = $1->appendList( $3 ); }
     1297        ;
     1298
     1299KR_declaration_list_opt:                                                                // used to declare parameter types in K&R style functions
    12641300        // empty
    12651301                { $$ = nullptr; }
    1266         | declaration_list
    1267         ;
    1268 
    1269 declaration_list:
    1270         declaration
    1271         | declaration_list declaration
    1272                 { $$ = $1->appendList( $2 ); }
    1273         ;
    1274 
    1275 KR_parameter_list_opt:                                                          // used to declare parameter types in K&R style functions
    1276         // empty
    1277                 { $$ = nullptr; }
    1278         | KR_parameter_list
    1279         ;
    1280 
    1281 KR_parameter_list:
     1302        | KR_declaration_list
     1303        ;
     1304
     1305KR_declaration_list:
    12821306        push c_declaration pop ';'
    12831307                { $$ = $2; }
    1284         | KR_parameter_list push c_declaration pop ';'
     1308        | KR_declaration_list push c_declaration pop ';'
    12851309                { $$ = $1->appendList( $3 ); }
    12861310        ;
     
    12971321
    12981322local_label_list:                                                                               // GCC, local label
    1299         no_attr_identifier_or_type_name
    1300         | local_label_list ',' no_attr_identifier_or_type_name
     1323        no_attr_identifier_or_type_name                         {}
     1324        | local_label_list ',' no_attr_identifier_or_type_name {}
    13011325        ;
    13021326
    13031327declaration:                                                                                    // old & new style declarations
    1304         c_declaration ';'
    1305         | cfa_declaration ';'                                                           // CFA
     1328        c_declaration pop ';'
     1329        | cfa_declaration pop ';'                                                       // CFA
    13061330        | static_assert
    13071331        ;
     
    13611385        | declaration_qualifier_list type_qualifier_list cfa_function_specifier
    13621386                { $$ = $3->addQualifiers( $1 )->addQualifiers( $2 ); }
    1363         | cfa_function_declaration ',' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
     1387        | cfa_function_declaration ',' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
    13641388                {
    13651389                        // Append the return type at the start (left-hand-side) to each identifier in the list.
    13661390                        DeclarationNode * ret = new DeclarationNode;
    13671391                        ret->type = maybeClone( $1->type->base );
    1368                         $$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $6, nullptr ) );
     1392                        $$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $5, nullptr ) );
    13691393                }
    13701394        ;
    13711395
    13721396cfa_function_specifier:                                                                 // CFA
    1373 //      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
     1397//      '[' ']' identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')' // S/R conflict
    13741398//              {
    13751399//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
    13761400//              }
    1377 //      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
     1401//      '[' ']' identifier '(' push cfa_parameter_type_list_opt pop ')'
    13781402//              {
    13791403//                      typedefTable.setNextIdentifier( *$5 );
    13801404//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    13811405//              }
    1382 //      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
     1406//      | '[' ']' TYPEDEFname '(' push cfa_parameter_type_list_opt pop ')'
    13831407//              {
    13841408//                      typedefTable.setNextIdentifier( *$5 );
     
    13881412                // identifier_or_type_name must be broken apart because of the sequence:
    13891413                //
    1390                 //   '[' ']' identifier_or_type_name '(' cfa_parameter_ellipsis_list_opt ')'
     1414                //   '[' ']' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
    13911415                //   '[' ']' type_specifier
    13921416                //
    13931417                // type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be
    13941418                // flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name.
    1395         cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
     1419        cfa_abstract_tuple identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
    13961420                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    1397                 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
    1398         | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
    1399                 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
     1421                { $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
     1422        | cfa_function_return identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
     1423                { $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
    14001424        ;
    14011425
    14021426cfa_function_return:                                                                    // CFA
    1403         '[' push cfa_parameter_list pop ']'
    1404                 { $$ = DeclarationNode::newTuple( $3 ); }
    1405         | '[' push cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ']'
    1406                 // To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the ']'.
    1407                 { $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
     1427        '[' cfa_parameter_list ']'
     1428                { $$ = DeclarationNode::newTuple( $2 ); }
     1429        | '[' cfa_parameter_list ',' cfa_abstract_parameter_list ']'
     1430                // To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the
     1431                // ']'.
     1432                { $$ = DeclarationNode::newTuple( $2->appendList( $4 ) ); }
    14081433        ;
    14091434
     
    14111436        TYPEDEF cfa_variable_specifier
    14121437                {
    1413                         typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname /*, "1"*/ );
     1438                        typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname );
    14141439                        $$ = $2->addTypedef();
    14151440                }
    14161441        | TYPEDEF cfa_function_specifier
    14171442                {
    1418                         typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname /*, "2"*/ );
     1443                        typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname );
    14191444                        $$ = $2->addTypedef();
    14201445                }
    14211446        | cfa_typedef_declaration pop ',' push no_attr_identifier
    14221447                {
    1423                         typedefTable.addToEnclosingScope( *$5, TYPEDEFname /*, "3"*/ );
     1448                        typedefTable.addToEnclosingScope( *$5, TYPEDEFname );
    14241449                        $$ = $1->appendList( $1->cloneType( $5 ) );
    14251450                }
     
    14321457        TYPEDEF type_specifier declarator
    14331458                {
    1434                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname /*, "4"*/ );
     1459                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname );
    14351460                        $$ = $3->addType( $2 )->addTypedef();
    14361461                }
    14371462        | typedef_declaration pop ',' push declarator
    14381463                {
    1439                         typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname /*, "5"*/ );
     1464                        typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname );
    14401465                        $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
    14411466                }
    14421467        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
    14431468                {
    1444                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname /*, "6"*/ );
     1469                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname );
    14451470                        $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
    14461471                }
    14471472        | type_specifier TYPEDEF declarator
    14481473                {
    1449                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname /*, "7"*/ );
     1474                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname );
    14501475                        $$ = $3->addType( $1 )->addTypedef();
    14511476                }
    14521477        | type_specifier TYPEDEF type_qualifier_list declarator
    14531478                {
    1454                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname /*, "8"*/ );
     1479                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname );
    14551480                        $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
    14561481                }
     
    15791604
    15801605forall:
    1581         FORALL '(' type_parameter_list ')'                                      // CFA
    1582                 { $$ = DeclarationNode::newForall( $3 ); }
     1606        FORALL '('
     1607                {
     1608                        typedefTable.enterScope();
     1609                }
     1610          type_parameter_list ')'                                                       // CFA
     1611                {
     1612                        typedefTable.leaveScope();
     1613                        $$ = DeclarationNode::newForall( $4 );
     1614                }
    15831615        ;
    15841616
     
    19481980        ;
    19491981
    1950 cfa_parameter_ellipsis_list_opt:                                                        // CFA, abstract + real
     1982cfa_parameter_type_list_opt:                                                    // CFA, abstract + real
    19511983        // empty
    19521984                { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
     
    19551987        | cfa_abstract_parameter_list
    19561988        | cfa_parameter_list
    1957         | cfa_parameter_list pop ',' push cfa_abstract_parameter_list
    1958                 { $$ = $1->appendList( $5 ); }
    1959         | cfa_abstract_parameter_list pop ',' push ELLIPSIS
     1989        | cfa_parameter_list ',' cfa_abstract_parameter_list
     1990                { $$ = $1->appendList( $3 ); }
     1991        | cfa_abstract_parameter_list ',' ELLIPSIS
    19601992                { $$ = $1->addVarArgs(); }
    1961         | cfa_parameter_list pop ',' push ELLIPSIS
     1993        | cfa_parameter_list ',' ELLIPSIS
    19621994                { $$ = $1->addVarArgs(); }
    19631995        ;
     
    19671999                // factored out from cfa_parameter_list, flattening the rules to get lookahead to the ']'.
    19682000        cfa_parameter_declaration
    1969         | cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
    1970                 { $$ = $1->appendList( $5 ); }
    1971         | cfa_parameter_list pop ',' push cfa_parameter_declaration
    1972                 { $$ = $1->appendList( $5 ); }
    1973         | cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
    1974                 { $$ = $1->appendList( $5 )->appendList( $9 ); }
     2001        | cfa_abstract_parameter_list ',' cfa_parameter_declaration
     2002                { $$ = $1->appendList( $3 ); }
     2003        | cfa_parameter_list ',' cfa_parameter_declaration
     2004                { $$ = $1->appendList( $3 ); }
     2005        | cfa_parameter_list ',' cfa_abstract_parameter_list ',' cfa_parameter_declaration
     2006                { $$ = $1->appendList( $3 )->appendList( $5 ); }
    19752007        ;
    19762008
    19772009cfa_abstract_parameter_list:                                                    // CFA, new & old style abstract
    19782010        cfa_abstract_parameter_declaration
    1979         | cfa_abstract_parameter_list pop ',' push cfa_abstract_parameter_declaration
    1980                 { $$ = $1->appendList( $5 ); }
     2011        | cfa_abstract_parameter_list ',' cfa_abstract_parameter_declaration
     2012                { $$ = $1->appendList( $3 ); }
    19812013        ;
    19822014
     
    20812113                { $$ = $2; }
    20822114        | '=' VOID
    2083                 { $$ = nullptr; }
     2115                { $$ = new InitializerNode( true ); }
    20842116        | ATassign initializer
    20852117                { $$ = $2->set_maybeConstructed( false ); }
     
    21272159        '.' no_attr_identifier                                                          // C99, field name
    21282160                { $$ = new ExpressionNode( build_varref( $2 ) ); }
    2129         | '[' push assignment_expression pop ']'                        // C99, single array element
     2161        | '[' assignment_expression ']'                                         // C99, single array element
    21302162                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     2163                { $$ = $2; }
     2164        | '[' subrange ']'                                                                      // CFA, multiple array elements
     2165                { $$ = $2; }
     2166        | '[' constant_expression ELLIPSIS constant_expression ']' // GCC, multiple array elements
     2167                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $2 ), maybeMoveBuild< Expression >( $4 ) ) ); }
     2168        | '.' '[' field_list ']'                                                        // CFA, tuple field selector
    21312169                { $$ = $3; }
    2132         | '[' push subrange pop ']'                                                     // CFA, multiple array elements
    2133                 { $$ = $3; }
    2134         | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2135                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $3 ), maybeMoveBuild< Expression >( $5 ) ) ); }
    2136         | '.' '[' push field_list pop ']'                                       // CFA, tuple field selector
    2137                 { $$ = $4; }
    21382170        ;
    21392171
     
    21722204type_parameter:                                                                                 // CFA
    21732205        type_class no_attr_identifier_or_type_name
    2174                 { typedefTable.addToScope( *$2, TYPEDEFname /*, "9"*/ ); }
     2206                { typedefTable.addToEnclosingScope( *$2, TYPEDEFname ); }
    21752207          type_initializer_opt assertion_list_opt
    21762208                { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); }
     
    22062238        '|' no_attr_identifier_or_type_name '(' type_list ')'
    22072239                { $$ = DeclarationNode::newTraitUse( $2, $4 ); }
    2208         | '|' '{' push trait_declaration_list pop '}'
     2240        | '|' '{' push trait_declaration_list '}'
    22092241                { $$ = $4; }
    2210         // | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}' '(' type_list ')'
    2211         //      { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }
     2242        | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list '}' '(' type_list ')'
     2243                { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }
    22122244        ;
    22132245
     
    22412273        no_attr_identifier_or_type_name
    22422274                {
    2243                         typedefTable.addToEnclosingScope( *$1, TYPEDEFname /*, "10"*/ );
     2275                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname );
    22442276                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
    22452277                }
    2246         | no_attr_identifier_or_type_name '(' type_parameter_list ')'
    2247                 {
    2248                         typedefTable.addToEnclosingScope( *$1, TYPEGENname /*, "11"*/ );
    2249                         $$ = DeclarationNode::newTypeDecl( $1, $3 );
     2278        | no_attr_identifier_or_type_name '(' push type_parameter_list pop ')'
     2279                {
     2280                        typedefTable.addToEnclosingScope( *$1, TYPEGENname );
     2281                        $$ = DeclarationNode::newTypeDecl( $1, $4 );
    22502282                }
    22512283        ;
    22522284
    22532285trait_specifier:                                                                                // CFA
    2254         TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    2255                 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
    2256         | TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    2257                 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
     2286        TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' '}'
     2287                { $$ = DeclarationNode::newTrait( $2, $5, 0 ); }
     2288        | TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{'
     2289                { typedefTable.enterScope(); }
     2290          trait_declaration_list '}'
     2291                { $$ = DeclarationNode::newTrait( $2, $5, $10 ); }
    22582292        ;
    22592293
    22602294trait_declaration_list:                                                                 // CFA
    22612295        trait_declaration
    2262         | trait_declaration_list pop push trait_declaration
    2263                 { $$ = $1->appendList( $4 ); }
     2296        | trait_declaration_list push trait_declaration
     2297                { $$ = $1->appendList( $3 ); }
    22642298        ;
    22652299
    22662300trait_declaration:                                                                              // CFA
    2267         cfa_trait_declaring_list ';'
    2268         | trait_declaring_list ';'
     2301        cfa_trait_declaring_list pop ';'
     2302        | trait_declaring_list pop ';'
    22692303        ;
    22702304
    22712305cfa_trait_declaring_list:                                                               // CFA
    22722306        cfa_variable_specifier
     2307                { $$ = $1; }
    22732308        | cfa_function_specifier
     2309                { $$ = $1; }
    22742310        | cfa_trait_declaring_list pop ',' push identifier_or_type_name
    22752311                { $$ = $1->appendList( $1->cloneType( $5 ) ); }
     
    22932329
    22942330external_definition_list:
    2295         push external_definition pop
    2296                 { $$ = $2; }
     2331        external_definition
    22972332        | external_definition_list
    22982333                { forall = xxx; }
    2299           push external_definition pop
     2334          push external_definition
    23002335                { $$ = $1 ? $1->appendList( $4 ) : $4; }
    23012336        ;
     
    23192354                        linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 );
    23202355                }
    2321                         // SKULLDUGGERY: Declarations in extern "X" need to be added to the current lexical scope.  However,
    2322                         // external_definition_list_opt creates a new scope that loses the types at the end of the extern block. The
    2323                         // correction is a pop/push (reverse order) to undo the push/pop from external_definition_list_opt.  This
    2324                         // trick works for nested extern "X"s, as each one undoes itself in the nesting.
    2325           '{' pop external_definition_list_opt push '}'
     2356          '{' external_definition_list_opt '}'
    23262357                {
    23272358                        linkage = linkageStack.top();
    23282359                        linkageStack.pop();
    2329                         $$ = $6;
     2360                        $$ = $5;
    23302361                }
    23312362        | EXTENSION external_definition                                         // GCC, multiple __extension__ allowed, meaning unknown
     
    23352366                }
    23362367        | type_qualifier_list
    2337                 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
    2338           '{' external_definition_list push '}'                  // CFA, namespace
    2339                 {
    2340                         for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2368                {
     2369                        if ( $1->type->forall ) xxx = forall = true; // remember generic type
     2370                }
     2371          push '{' external_definition_list '}'                         // CFA, namespace
     2372                {
     2373                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    23412374                                if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    23422375                                        iter->addQualifiers( $1->clone() );
     
    23452378                        xxx = false;
    23462379                        delete $1;
    2347                         $$ = $4;
     2380                        $$ = $5;
    23482381                }
    23492382        | declaration_qualifier_list
    2350                 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
    2351           '{' external_definition_list '}'                                       // CFA, namespace
    2352                 {
    2353                         for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2383                {
     2384                        if ( $1->type->forall ) xxx = forall = true; // remember generic type
     2385                }
     2386          push '{' external_definition_list '}'                         // CFA, namespace
     2387                {
     2388                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    23542389                                if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    23552390                                        iter->addQualifiers( $1->clone() );
     
    23582393                        xxx = false;
    23592394                        delete $1;
    2360                         $$ = $4;
     2395                        $$ = $5;
    23612396                }
    23622397        | declaration_qualifier_list type_qualifier_list
     
    23652400                        if ( $2->type->forall ) xxx = forall = true; // remember generic type
    23662401                }
    2367           '{' external_definition_list '}'                                      // CFA, namespace
    2368                 {
    2369                         for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     2402          push '{' external_definition_list '}'                         // CFA, namespace
     2403                {
     2404                        for ( DeclarationNode * iter = $6; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    23702405                                if ( isMangled( iter->linkage ) && isMangled( $2->linkage ) ) { // ignore extern "C"
    23712406                                        iter->addQualifiers( $1->clone() );
     
    23762411                        delete $1;
    23772412                        delete $2;
    2378                         $$ = $5;
     2413                        $$ = $6;
    23792414                }
    23802415        ;
     
    23882423                // declaration must still have a type_specifier.  OBSOLESCENT (see 1)
    23892424        | function_declarator compound_statement
    2390                 { $$ = $1->addFunctionBody( $2 ); }
    2391         | KR_function_declarator KR_parameter_list_opt compound_statement
    2392                 { $$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 ); }
     2425                {
     2426                        typedefTable.leaveScope();
     2427                        $$ = $1->addFunctionBody( $2 );
     2428                }
     2429        | KR_function_declarator KR_declaration_list_opt compound_statement
     2430                {
     2431                        typedefTable.leaveScope();
     2432                        $$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 );
     2433                }
    23932434        ;
    23942435
     
    24032444        cfa_function_declaration with_clause_opt compound_statement     // CFA
    24042445                {
     2446                        typedefTable.leaveScope();
    24052447                        // Add the function body to the last identifier in the function definition list, i.e., foo3:
    24062448                        //   [const double] foo1(), foo2( int ), foo3( double ) { return 3.0; }
     
    24112453                {
    24122454                        rebindForall( $1, $2 );
     2455                        typedefTable.leaveScope();
    24132456                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    24142457                }
     
    24162459                {
    24172460                        rebindForall( $1, $2 );
     2461                        typedefTable.leaveScope();
    24182462                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    24192463                }
    24202464                // handles default int return type, OBSOLESCENT (see 1)
    24212465        | type_qualifier_list function_declarator with_clause_opt compound_statement
    2422                 { $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); }
     2466                {
     2467                        typedefTable.leaveScope();
     2468                        $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
     2469                }
    24232470                // handles default int return type, OBSOLESCENT (see 1)
    24242471        | declaration_qualifier_list function_declarator with_clause_opt compound_statement
    2425                 { $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); }
     2472                {
     2473                        typedefTable.leaveScope();
     2474                        $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
     2475                }
    24262476                // handles default int return type, OBSOLESCENT (see 1)
    24272477        | declaration_qualifier_list type_qualifier_list function_declarator with_clause_opt compound_statement
    2428                 { $$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 ); }
     2478                {
     2479                        typedefTable.leaveScope();
     2480                        $$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 );
     2481                }
    24292482
    24302483                // Old-style K&R function definition, OBSOLESCENT (see 4)
    2431         | declaration_specifier KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement
     2484        | declaration_specifier KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
    24322485                {
    24332486                        rebindForall( $1, $2 );
     2487                        typedefTable.leaveScope();
    24342488                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addType( $1 );
    24352489                }
    24362490                // handles default int return type, OBSOLESCENT (see 1)
    2437         | type_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement
    2438                 { $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); }
     2491        | type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
     2492                {
     2493                        typedefTable.leaveScope();
     2494                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
     2495                }
    24392496                // handles default int return type, OBSOLESCENT (see 1)
    2440         | declaration_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement
    2441                 { $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); }
     2497        | declaration_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
     2498                {
     2499                        typedefTable.leaveScope();
     2500                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
     2501                }
    24422502                // handles default int return type, OBSOLESCENT (see 1)
    2443         | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement
    2444                 { $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 ); }
     2503        | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
     2504                {
     2505                        typedefTable.leaveScope();
     2506                        $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 );
     2507                }
    24452508        ;
    24462509
     
    26392702        paren_identifier '(' identifier_list ')'                        // function_declarator handles empty parameter
    26402703                { $$ = $1->addIdList( $3 ); }
    2641         | '(' KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
    2642                 { $$ = $2->addParamList( $6 ); }
     2704        | '(' KR_function_ptr ')' '(' parameter_type_list_opt ')'
     2705                { $$ = $2->addParamList( $5 ); }
    26432706        | '(' KR_function_no_ptr ')'                                            // redundant parenthesis
    26442707                { $$ = $2; }
     
    26862749        typedef
    26872750                // hide type name in enclosing scope by variable name
    2688                 { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER /*, "ID"*/ ); }
     2751                { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER ); }
    26892752        | '(' paren_type ')'
    26902753                { $$ = $2; }
     
    27582821
    27592822identifier_parameter_function:
    2760         paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2761                 { $$ = $1->addParamList( $4 ); }
    2762         | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2763                 { $$ = $2->addParamList( $6 ); }
     2823        paren_identifier '(' parameter_type_list_opt ')'        // empty parameter list OBSOLESCENT (see 3)
     2824                { $$ = $1->addParamList( $3 ); }
     2825        | '(' identifier_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     2826                { $$ = $2->addParamList( $5 ); }
    27642827        | '(' identifier_parameter_function ')'                         // redundant parenthesis
    27652828                { $$ = $2; }
     
    28112874
    28122875type_parameter_function:
    2813         typedef '(' push parameter_type_list_opt pop ')'        // empty parameter list OBSOLESCENT (see 3)
    2814                 { $$ = $1->addParamList( $4 ); }
    2815         | '(' type_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2816                 { $$ = $2->addParamList( $6 ); }
     2876        typedef '(' parameter_type_list_opt ')'                         // empty parameter list OBSOLESCENT (see 3)
     2877                { $$ = $1->addParamList( $3 ); }
     2878        | '(' type_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     2879                { $$ = $2->addParamList( $5 ); }
    28172880        ;
    28182881
     
    28612924
    28622925abstract_function:
    2863         '(' push parameter_type_list_opt pop ')'                        // empty parameter list OBSOLESCENT (see 3)
    2864                 { $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
    2865         | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2866                 { $$ = $2->addParamList( $6 ); }
     2926        '(' parameter_type_list_opt ')'                                         // empty parameter list OBSOLESCENT (see 3)
     2927                { $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
     2928        | '(' abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     2929                { $$ = $2->addParamList( $5 ); }
    28672930        | '(' abstract_function ')'                                                     // redundant parenthesis
    28682931                { $$ = $2; }
     
    28792942
    28802943multi_array_dimension:
    2881         '[' push assignment_expression pop ']'
    2882                 { $$ = DeclarationNode::newArray( $3, 0, false ); }
    2883         | '[' push '*' pop ']'                                                          // C99
     2944        '[' assignment_expression ']'
     2945                { $$ = DeclarationNode::newArray( $2, 0, false ); }
     2946        | '[' '*' ']'                                                                           // C99
    28842947                { $$ = DeclarationNode::newVarArray( 0 ); }
    2885         | multi_array_dimension '[' push assignment_expression pop ']'
    2886                 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
    2887         | multi_array_dimension '[' push '*' pop ']'            // C99
     2948        | multi_array_dimension '[' assignment_expression ']'
     2949                { $$ = $1->addArray( DeclarationNode::newArray( $3, 0, false ) ); }
     2950        | multi_array_dimension '[' '*' ']'                                     // C99
    28882951                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
    28892952        ;
     
    29523015
    29533016abstract_parameter_function:
    2954         '(' push parameter_type_list_opt pop ')'                        // empty parameter list OBSOLESCENT (see 3)
    2955                 { $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
    2956         | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2957                 { $$ = $2->addParamList( $6 ); }
     3017        '(' parameter_type_list_opt ')'                                         // empty parameter list OBSOLESCENT (see 3)
     3018                { $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
     3019        | '(' abstract_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3020                { $$ = $2->addParamList( $5 ); }
    29583021        | '(' abstract_parameter_function ')'                           // redundant parenthesis
    29593022                { $$ = $2; }
     
    29763039        '[' ']'
    29773040                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    2978                 // multi_array_dimension handles the '[' '*' ']' case
    2979         | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    2980                 { $$ = DeclarationNode::newVarArray( $3 ); }
    2981         | '[' push type_qualifier_list pop ']'
    2982                 { $$ = DeclarationNode::newArray( 0, $3, false ); }
    2983                 // multi_array_dimension handles the '[' assignment_expression ']' case
    2984         | '[' push type_qualifier_list assignment_expression pop ']'
    2985                 { $$ = DeclarationNode::newArray( $4, $3, false ); }
    2986         | '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'
    2987                 { $$ = DeclarationNode::newArray( $5, $4, true ); }
    2988         | '[' push type_qualifier_list STATIC assignment_expression pop ']'
    2989                 { $$ = DeclarationNode::newArray( $5, $3, true ); }
     3041        // multi_array_dimension handles the '[' '*' ']' case
     3042        | '[' type_qualifier_list '*' ']'                                       // remaining C99
     3043                { $$ = DeclarationNode::newVarArray( $2 ); }
     3044        | '[' type_qualifier_list ']'
     3045                { $$ = DeclarationNode::newArray( 0, $2, false ); }
     3046        // multi_array_dimension handles the '[' assignment_expression ']' case
     3047        | '[' type_qualifier_list assignment_expression ']'
     3048                { $$ = DeclarationNode::newArray( $3, $2, false ); }
     3049        | '[' STATIC type_qualifier_list_opt assignment_expression ']'
     3050                { $$ = DeclarationNode::newArray( $4, $3, true ); }
     3051        | '[' type_qualifier_list STATIC assignment_expression ']'
     3052                { $$ = DeclarationNode::newArray( $4, $2, true ); }
    29903053        ;
    29913054
     
    30313094
    30323095variable_abstract_function:
    3033         '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3034                 { $$ = $2->addParamList( $6 ); }
     3096        '(' variable_abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3097                { $$ = $2->addParamList( $5 ); }
    30353098        | '(' variable_abstract_function ')'                            // redundant parenthesis
    30363099                { $$ = $2; }
     
    30953158
    30963159cfa_array_parameter_1st_dimension:
    3097         '[' push type_qualifier_list '*' pop ']'                        // remaining C99
    3098                 { $$ = DeclarationNode::newVarArray( $3 ); }
    3099         | '[' push type_qualifier_list assignment_expression pop ']'
    3100                 { $$ = DeclarationNode::newArray( $4, $3, false ); }
    3101         | '[' push declaration_qualifier_list assignment_expression pop ']'
     3160        '[' type_qualifier_list '*' ']'                                         // remaining C99
     3161                { $$ = DeclarationNode::newVarArray( $2 ); }
     3162        | '[' type_qualifier_list assignment_expression ']'
     3163                { $$ = DeclarationNode::newArray( $3, $2, false ); }
     3164        | '[' declaration_qualifier_list assignment_expression ']'
    31023165                // declaration_qualifier_list must be used because of shift/reduce conflict with
    31033166                // assignment_expression, so a semantic check is necessary to preclude them as a type_qualifier cannot
    31043167                // appear in this context.
    3105                 { $$ = DeclarationNode::newArray( $4, $3, true ); }
    3106         | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
    3107                 { $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
     3168                { $$ = DeclarationNode::newArray( $3, $2, true ); }
     3169        | '[' declaration_qualifier_list type_qualifier_list assignment_expression ']'
     3170                { $$ = DeclarationNode::newArray( $4, $3->addQualifiers( $3 ), true ); }
    31083171        ;
    31093172
     
    31173180//
    31183181//              cfa_abstract_tuple identifier_or_type_name
    3119 //              '[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_ellipsis_list_opt ')'
     3182//              '[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
    31203183//
    31213184// since a function return type can be syntactically identical to a tuple type:
     
    31743237
    31753238cfa_abstract_tuple:                                                                             // CFA
    3176         '[' push cfa_abstract_parameter_list pop ']'
    3177                 { $$ = DeclarationNode::newTuple( $3 ); }
    3178         | '[' push type_specifier_nobody ELLIPSIS pop ']'
    3179                 { SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; }
    3180         | '[' push type_specifier_nobody ELLIPSIS constant_expression pop ']'
    3181                 { SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; }
     3239        '[' cfa_abstract_parameter_list ']'
     3240                { $$ = DeclarationNode::newTuple( $2 ); }
    31823241        ;
    31833242
    31843243cfa_abstract_function:                                                                  // CFA
    3185 //      '[' ']' '(' cfa_parameter_ellipsis_list_opt ')'
     3244//      '[' ']' '(' cfa_parameter_type_list_opt ')'
    31863245//              { $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); }
    3187         cfa_abstract_tuple '(' push cfa_parameter_ellipsis_list_opt pop ')'
    3188                 { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
    3189         | cfa_function_return '(' push cfa_parameter_ellipsis_list_opt pop ')'
    3190                 { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
     3246        cfa_abstract_tuple '(' cfa_parameter_type_list_opt ')'
     3247                { $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
     3248        | cfa_function_return '(' cfa_parameter_type_list_opt ')'
     3249                { $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
    31913250        ;
    31923251
Note: See TracChangeset for help on using the changeset viewer.